gpu,build,display,sensors,input

This commit is contained in:
lhyqy5 2025-10-31 13:55:09 +08:00
parent e2be896d11
commit 6f4c66896a
34 changed files with 2172 additions and 42 deletions

View File

@ -51,6 +51,7 @@ dependencies {
// implementation("androidx.datastore:datastore-preferences-rxjava3:1.1.7")
implementation(libs.androidx.datastore)
// implementation("androidx.datastore:datastore-rxjava3:1.1.7")
implementation("androidx.security:security-state:1.0.0-alpha04")
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)

View File

@ -6,9 +6,19 @@ add_subdirectory(cpuinfo)
add_library(andinfo SHARED
CpuInfoUtils.cpp
CpuJni.cpp)
CpuJni.cpp
jni_utils.cpp
EglUtils.cpp
VkUtils.cpp
egl/EglContext.cpp
egl/EglSession.cpp
vulkan/VkSession.cpp
vulkan_wrapper/vulkan_wrapper.cpp)
target_link_libraries(andinfo
android
log
cpuinfo)
cpuinfo
GLESv2
EGL
vulkan)

View File

@ -31,19 +31,19 @@
DECLARE_CPU_CLASS(Cache, "IIIIIIII")
DECLARE_CPU_CLASS(Cluster, "IIIII" CPU_CLASS_SIG(Package) "IIIIJ")
DECLARE_CPU_CLASS(Cluster, "IIIII" "L" CPU_PACKAGE "/Package;" "IIIIJ")
DECLARE_CPU_CLASS(Core, "III" CPU_CLASS_SIG(Cluster) CPU_CLASS_SIG(Package) "IIIIJ")
DECLARE_CPU_CLASS(Core, "III" "L" CPU_PACKAGE "/Cluster;" "L" CPU_PACKAGE "/Package;" "IIIIJ")
DECLARE_CPU_CLASS(Package, STRING_CLASS_SIG "IIIIII")
DECLARE_CPU_CLASS(Processor,
"I" CPU_CLASS_SIG(Core) CPU_CLASS_SIG(Cluster) CPU_CLASS_SIG(
Package) "II" CPU_CLASS_SIG(ProcessorCache))
"I" "L" CPU_PACKAGE "/Core;" "L" CPU_PACKAGE "/Cluster;" "L" CPU_PACKAGE
"/Package;" "II" "L" CPU_PACKAGE "/ProcessorCache;")
DECLARE_CPU_CLASS(ProcessorCache,
CPU_CLASS_SIG(Cache) CPU_CLASS_SIG(Cache) CPU_CLASS_SIG(Cache) CPU_CLASS_SIG(
Cache) CPU_CLASS_SIG(Cache))
"L" CPU_PACKAGE "/Cache;" "L" CPU_PACKAGE "/Cache;" "L" CPU_PACKAGE
"/Cache;" "L" CPU_PACKAGE "/Cache;" "L" CPU_PACKAGE "/Cache;")
DECLARE_CPU_CLASS(Tlb, "IIJ")

View File

@ -0,0 +1,123 @@
/*
* SPDX-FileCopyrightText: Sebastiano Barezzi
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "EglUtils"
#include <jni.h>
#include "jni_utils.h"
#include "logging.h"
#include "egl/EglSession.h"
static const EGLint kConfigAttribs[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
static const EGLint kContextAttribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
static void
maybeAddGlInformation(JNIEnv *env, EglSession &eglSession, jobject eglInformationBuilder) {
jclass eglInformationBuilderClass = withJniCheck<jclass>(env, [=]() {
return env->FindClass("com/xyzshell/andinfo/libs/gpu/models/EglInformation$Builder");
});
auto eglInformationAddGlInformationMethodId = withJniCheck<jmethodID>(env, [=]() {
return env->GetMethodID(
eglInformationBuilderClass,
"addGlInformation",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
});
// Choose a configuration
auto eglConfig = eglSession.eglChooseConfig(kConfigAttribs);
if (!eglConfig) {
LOGE("Failed to choose EGL config");
return;
}
// Create a context
auto eglContext = eglSession.createEglContext(eglConfig.value(), kContextAttribs);
if (!eglContext) {
LOGE("Failed to create EGL context");
return;
}
// Make the context current
if (!eglSession.eglMakeCurrent(EGL_NO_SURFACE, EGL_NO_SURFACE, eglContext->getContext())) {
LOGE("Failed to make EGL context current");
return;
}
auto glVendor = eglSession.glGetString(GL_VENDOR);
auto glRenderer = eglSession.glGetString(GL_RENDERER);
auto glVersion = eglSession.glGetString(GL_VERSION);
auto glExtensions = eglSession.glGetString(GL_EXTENSIONS);
withJniCheck(env, [=]() {
return env->CallVoidMethod(
eglInformationBuilder, eglInformationAddGlInformationMethodId,
glVendor ? env->NewStringUTF(glVendor) : nullptr,
glRenderer ? env->NewStringUTF(glRenderer) : nullptr,
glVersion ? env->NewStringUTF(glVersion) : nullptr,
glExtensions ? env->NewStringUTF(glExtensions) : nullptr);
});
// Cleanup the current context
eglSession.eglMakeCurrent(EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
extern "C"
jobject Java_com_xyzshell_andinfo_libs_gpu_utils_EglUtils_getEglInformation(
JNIEnv *env, jobject thiz) {
jclass eglInformationBuilderClass = withJniCheck<jclass>(env, [=]() {
return env->FindClass("com/xyzshell/andinfo/libs/gpu/models/EglInformation$Builder");
});
auto eglInformationBuilderConstructorMethodId = withJniCheck<jmethodID>(env, [=]() {
return env->GetMethodID(
eglInformationBuilderClass,
"<init>",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
});
auto eglInformationBuilderBuildMethodId = withJniCheck<jmethodID>(env, [=]() {
return env->GetMethodID(
eglInformationBuilderClass,
"build",
"()Lcom/xyzshell/andinfo/libs/gpu/models/EglInformation;");
});
auto eglSession = EglSession::create();
if (!eglSession) {
LOGE("Failed to create EGL session");
return nullptr;
}
const char *eglVendor = eglSession->eglQueryString(EGL_VENDOR);
const char *eglVersion = eglSession->eglQueryString(EGL_VERSION);
const char *eglExtensions = eglSession->eglQueryString(EGL_EXTENSIONS);
const char *eglClientApi = eglSession->eglQueryString(EGL_CLIENT_APIS);
auto eglInformationBuild = withJniCheck<jobject>(env, [=]() {
return env->NewObject(
eglInformationBuilderClass,
eglInformationBuilderConstructorMethodId,
eglVendor ? env->NewStringUTF(eglVendor) : nullptr,
eglVersion ? env->NewStringUTF(eglVersion) : nullptr,
eglExtensions ? env->NewStringUTF(eglExtensions) : nullptr,
eglClientApi ? env->NewStringUTF(eglClientApi) : nullptr);
});
maybeAddGlInformation(env, *eglSession, eglInformationBuild);
auto eglInformation = withJniCheck<jobject>(env, [=]() {
return env->CallObjectMethod(eglInformationBuild, eglInformationBuilderBuildMethodId);
});
return eglInformation;
}

View File

@ -0,0 +1,80 @@
/*
* SPDX-FileCopyrightText: Sebastiano Barezzi
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "VkUtils"
#include <vector>
#include <jni.h>
#include "vulkan/VkSession.h"
#include "jni_utils.h"
#include "logging.h"
static const std::vector<const char *> kRequiredExtensions = {
"VK_KHR_surface",
"VK_KHR_android_surface"
};
extern "C"
JNIEXPORT jobject JNICALL
Java_com_xyzshell_andinfo_libs_gpu_utils_VkUtils_getVkInfo(
JNIEnv *env, jobject thiz) {
jclass vkPhysicalDevicesClass = withJniCheck<jclass>(env, [=]() {
return env->FindClass("com/xyzshell/andinfo/libs/gpu/utils/VkUtils$VkPhysicalDevices");
});
auto vkPhysicalDevicesConstructorMethodId = withJniCheck<jmethodID>(env, [=]() {
return env->GetMethodID(vkPhysicalDevicesClass, "<init>", "()V");
});
auto addDeviceMethodId = withJniCheck<jmethodID>(env, [=]() {
return env->GetMethodID(
vkPhysicalDevicesClass,
"addDevice",
"(JJJJJLjava/lang/String;)Z");
});
VkApplicationInfo appInfo{
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.pApplicationName = "AndInfo",
.applicationVersion = VK_MAKE_VERSION(1, 0, 0),
.pEngineName = "No Engine",
.engineVersion = VK_MAKE_VERSION(1, 0, 0),
.apiVersion = VK_API_VERSION_1_0,
};
VkInstanceCreateInfo createInfo{
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pApplicationInfo = &appInfo,
.enabledLayerCount = 0,
.enabledExtensionCount = (uint32_t) kRequiredExtensions.size(),
.ppEnabledExtensionNames = kRequiredExtensions.data(),
};
auto vkSession = VkSession::create(&createInfo, nullptr);
if (!vkSession) {
LOGE("Failed to create Vulkan session");
return nullptr;
}
auto physicalDevices = vkSession->vkEnumeratePhysicalDevices();
auto vkPhysicalDevices = env->NewObject(vkPhysicalDevicesClass,
vkPhysicalDevicesConstructorMethodId);
for (const auto &device: physicalDevices) {
auto deviceProperties = vkSession->vkGetPhysicalDeviceProperties(device);
withJniCheck<bool>(env, [=]() {
return env->CallBooleanMethod(
vkPhysicalDevices, addDeviceMethodId,
static_cast<jlong>(deviceProperties.apiVersion),
static_cast<jlong>(deviceProperties.driverVersion),
static_cast<jlong>(deviceProperties.vendorID),
static_cast<jlong>(deviceProperties.deviceID),
static_cast<jlong>(deviceProperties.deviceType),
env->NewStringUTF(deviceProperties.deviceName));
});
}
return vkPhysicalDevices;
}

View File

@ -0,0 +1,33 @@
/*
* SPDX-FileCopyrightText: Sebastiano Barezzi
* SPDX-License-Identifier: Apache-2.0
*/
#include "EglContext.h"
#include <stdexcept>
EglContext::EglContext(EGLDisplay eglDisplay, EGLConfig config, const EGLint *attribList) {
mEglDisplay = eglDisplay;
mEglContext = ::eglCreateContext(eglDisplay, config, EGL_NO_CONTEXT, attribList);
if (mEglContext == EGL_NO_CONTEXT) {
throw std::runtime_error("Failed to create EGL context");
}
}
EglContext::~EglContext() {
::eglDestroyContext(mEglDisplay, mEglContext);
}
EGLContext EglContext::getContext() {
return mEglContext;
}
std::unique_ptr<EglContext>
EglContext::create(EGLDisplay eglDisplay, EGLConfig config, const EGLint *attribList) {
try {
return std::unique_ptr<EglContext>(new EglContext(eglDisplay, config, attribList));
} catch (...) {
return nullptr;
}
}

View File

@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: Sebastiano Barezzi
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <memory>
#include <EGL/egl.h>
class EglContext {
public:
EglContext(const EglContext &) = delete;
~EglContext();
EglContext &operator=(const EglContext &) = delete;
EGLContext getContext();
static std::unique_ptr<EglContext>
create(EGLDisplay eglDisplay, EGLConfig config, const EGLint *attribList);
private:
EglContext(EGLDisplay eglDisplay, EGLConfig config, const EGLint *attribList);
EGLDisplay mEglDisplay;
EGLContext mEglContext;
};

View File

@ -0,0 +1,67 @@
/*
* SPDX-FileCopyrightText: Sebastiano Barezzi
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "EglSession"
#include <stdexcept>
#include "EglSession.h"
#include "../logging.h"
EglSession::EglSession() {
mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (mDisplay == EGL_NO_DISPLAY) {
throw std::runtime_error("Failed to get EGL display");
}
if (!eglInitialize(mDisplay, &major, &minor)) {
throw std::runtime_error("Failed to initialize EGL");
}
}
EglSession::~EglSession() {
eglTerminate(mDisplay);
}
const char *EglSession::eglQueryString(EGLint name) {
return ::eglQueryString(mDisplay, name);
}
std::optional<EGLConfig>
EglSession::eglChooseConfig(const EGLint *attribList) {
EGLConfig config;
EGLint numConfigs;
if (!::eglChooseConfig(mDisplay, attribList, &config, 1, &numConfigs)) {
return nullptr;
}
return config;
}
std::unique_ptr<EglContext>
EglSession::createEglContext(EGLConfig config, const EGLint *attribList) {
try {
return EglContext::create(mDisplay, config, attribList);
} catch (std::runtime_error &error) {
LOGE("Failed to create EGL context: %s", error.what());
return {};
}
}
bool EglSession::eglMakeCurrent(EGLSurface drawSurface, EGLSurface readSurface,
EGLContext context) {
return ::eglMakeCurrent(mDisplay, drawSurface, readSurface, context);
}
const char *EglSession::glGetString(GLenum name) {
return reinterpret_cast<const char *>(::glGetString(name));
}
std::unique_ptr<EglSession> EglSession::create() {
try {
return std::unique_ptr<EglSession>(new EglSession());
} catch (...) {
return nullptr;
}
}

View File

@ -0,0 +1,40 @@
/*
* SPDX-FileCopyrightText: Sebastiano Barezzi
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <GLES/gl.h>
#include <EGL/egl.h>
#include <memory>
#include <optional>
#include "EglContext.h"
class EglSession {
public:
EglSession(const EglSession &) = delete;
~EglSession();
EglSession &operator=(const EglSession &) = delete;
const char *eglQueryString(EGLint name);
std::optional<EGLConfig> eglChooseConfig(const EGLint *attribList);
std::unique_ptr<EglContext>
createEglContext(EGLConfig config, const EGLint *attribList);
bool eglMakeCurrent(EGLSurface drawSurface, EGLSurface readSurface, EGLContext context);
const char *glGetString(GLenum name);
static std::unique_ptr<EglSession> create();
private:
EglSession();
EGLDisplay mDisplay = nullptr;
EGLint major = 0, minor = 0;
};

View File

@ -0,0 +1,31 @@
/*
* SPDX-FileCopyrightText: Sebastiano Barezzi
* SPDX-License-Identifier: Apache-2.0
*/
#include "jni_utils.h"
void withJniCheck(JNIEnv *env, const std::function<void()> &func) {
func();
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
env->ExceptionClear();
throw std::runtime_error("JNI exception");
}
}
jmethodID getArrayListAddMethodID(JNIEnv *env, jobject object) {
jclass arrayListClazz = withJniCheck<jclass>(env, [=]() {
return env->GetObjectClass(object);
});
auto methodID = withJniCheck<jmethodID>(env, [=]() {
return env->GetMethodID(
arrayListClazz,
"add",
"(Ljava/lang/Object;)Z");
});
return methodID;
}

View File

@ -5,26 +5,36 @@
#pragma once
#include <cstdlib>
#include <functional>
#include <jni.h>
#include <stdexcept> // For std::runtime_error
// Helper for stringifying preprocessor macros
#define STRINGIFY_IMPL(x) #x
#define STRINGIFY(x) STRINGIFY_IMPL(x)
#define JNI_CHECK(env) \
do { \
if (env->ExceptionCheck()) { \
env->ExceptionDescribe(); \
abort(); \
} \
} while (0)
env->ExceptionClear(); \
throw std::runtime_error("JNI exception at " __FILE__ ":" STRINGIFY(__LINE__)); \
}
#define OBJECT_CLASS_SIG "Ljava/lang/Object;"
#define STRING_CLASS_SIG "Ljava/lang/String;"
void withJniCheck(JNIEnv *env, const std::function<void()> &func);
static jmethodID getArrayListAddMethodID(JNIEnv *env, jobject object) {
auto arrayListClazz = env->GetObjectClass(object);
JNI_CHECK(env);
template<typename T>
T withJniCheck(JNIEnv *env, const std::function<T()> &func) {
T result = func();
auto methodID = env->GetMethodID(arrayListClazz, "add", "(" OBJECT_CLASS_SIG ")Z");
JNI_CHECK(env);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
env->ExceptionClear();
throw std::runtime_error("JNI exception");
}
return methodID;
return result;
}
jmethodID getArrayListAddMethodID(JNIEnv *env, jobject object);
#define STRING_CLASS_SIG "Ljava/lang/String;"

View File

@ -0,0 +1,11 @@
/*
* SPDX-FileCopyrightText: Sebastiano Barezzi
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <android/log.h>
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

View File

@ -0,0 +1,66 @@
/*
* SPDX-FileCopyrightText: Sebastiano Barezzi
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "VkSession"
#include <stdexcept>
#include "VkSession.h"
#include "../logging.h"
VkSession::VkSession(const VkInstanceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator) {
if (!IsVulkanSupported()) {
throw std::runtime_error("Vulkan not supported");
}
if (vkCreateInstance(pCreateInfo, pAllocator, &mInstance) != VK_SUCCESS) {
throw std::runtime_error("Failed to create Vulkan instance");
}
}
VkSession::~VkSession() {
vkDestroyInstance(mInstance, nullptr);
}
std::vector<VkPhysicalDevice> VkSession::vkEnumeratePhysicalDevices() {
VkResult result;
uint32_t deviceCount = 0;
result = ::vkEnumeratePhysicalDevices(mInstance, &deviceCount, nullptr);
if (result != VK_SUCCESS) {
LOGE("Failed to enumerate Vulkan devices: %d", result);
return {};
}
if (deviceCount <= 0) {
LOGI("No Vulkan device found");
return {};
}
std::vector<VkPhysicalDevice> devices(deviceCount);
result = ::vkEnumeratePhysicalDevices(mInstance, &deviceCount, devices.data());
if (result != VK_SUCCESS) {
LOGE("Failed to enumerate Vulkan devices: %d", result);
return {};
}
return devices;
}
VkPhysicalDeviceProperties VkSession::vkGetPhysicalDeviceProperties(VkPhysicalDevice device) {
VkPhysicalDeviceProperties properties;
::vkGetPhysicalDeviceProperties(device, &properties);
return properties;
}
std::unique_ptr<VkSession> VkSession::create(const VkInstanceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator) {
try {
return std::unique_ptr<VkSession>(new VkSession(pCreateInfo, pAllocator));
} catch (std::runtime_error &error) {
LOGE("Failed to create Vulkan session: %s", error.what());
return nullptr;
}
}

View File

@ -0,0 +1,31 @@
/*
* SPDX-FileCopyrightText: Sebastiano Barezzi
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <memory>
#include <vector>
#include "../vulkan_wrapper/vulkan_wrapper.h"
class VkSession {
public:
VkSession(const VkSession &) = delete;
~VkSession();
VkSession &operator=(const VkSession &) = delete;
std::vector<VkPhysicalDevice> vkEnumeratePhysicalDevices();
static std::unique_ptr<VkSession>
create(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator);
VkPhysicalDeviceProperties vkGetPhysicalDeviceProperties(VkPhysicalDevice device);
private:
VkSession(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator);
VkInstance mInstance = nullptr;
};

View File

@ -0,0 +1,215 @@
// Copyright 2016 Google Inc. All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
// This file is generated.
#include "vulkan_wrapper.h"
#include <dlfcn.h>
/*
* Initialize the Vulkan function pointer variables declared in this header.
* Returns UNSUPPORTED if vulkan is not available, SUPPORTED if it is available.
*/
static VulkanWrapperStatus InitVulkan() {
void* libvulkan = dlopen("libvulkan.so", RTLD_NOW | RTLD_LOCAL);
if (!libvulkan) {
return UNSUPPORTED;
}
// Vulkan supported, set function addresses
vkCreateInstance = reinterpret_cast<PFN_vkCreateInstance>(dlsym(libvulkan, "vkCreateInstance"));
vkDestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(dlsym(libvulkan, "vkDestroyInstance"));
vkEnumeratePhysicalDevices = reinterpret_cast<PFN_vkEnumeratePhysicalDevices>(dlsym(libvulkan, "vkEnumeratePhysicalDevices"));
vkGetPhysicalDeviceFeatures = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures>(dlsym(libvulkan, "vkGetPhysicalDeviceFeatures"));
vkGetPhysicalDeviceFormatProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceFormatProperties>(dlsym(libvulkan, "vkGetPhysicalDeviceFormatProperties"));
vkGetPhysicalDeviceImageFormatProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceImageFormatProperties>(dlsym(libvulkan, "vkGetPhysicalDeviceImageFormatProperties"));
vkGetPhysicalDeviceProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties>(dlsym(libvulkan, "vkGetPhysicalDeviceProperties"));
vkGetPhysicalDeviceQueueFamilyProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceQueueFamilyProperties>(dlsym(libvulkan, "vkGetPhysicalDeviceQueueFamilyProperties"));
vkGetPhysicalDeviceMemoryProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceMemoryProperties>(dlsym(libvulkan, "vkGetPhysicalDeviceMemoryProperties"));
vkGetInstanceProcAddr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(dlsym(libvulkan, "vkGetInstanceProcAddr"));
vkGetDeviceProcAddr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(dlsym(libvulkan, "vkGetDeviceProcAddr"));
vkCreateDevice = reinterpret_cast<PFN_vkCreateDevice>(dlsym(libvulkan, "vkCreateDevice"));
vkDestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(dlsym(libvulkan, "vkDestroyDevice"));
vkEnumerateInstanceExtensionProperties = reinterpret_cast<PFN_vkEnumerateInstanceExtensionProperties>(dlsym(libvulkan, "vkEnumerateInstanceExtensionProperties"));
vkEnumerateDeviceExtensionProperties = reinterpret_cast<PFN_vkEnumerateDeviceExtensionProperties>(dlsym(libvulkan, "vkEnumerateDeviceExtensionProperties"));
vkEnumerateInstanceLayerProperties = reinterpret_cast<PFN_vkEnumerateInstanceLayerProperties>(dlsym(libvulkan, "vkEnumerateInstanceLayerProperties"));
vkEnumerateDeviceLayerProperties = reinterpret_cast<PFN_vkEnumerateDeviceLayerProperties>(dlsym(libvulkan, "vkEnumerateDeviceLayerProperties"));
vkGetDeviceQueue = reinterpret_cast<PFN_vkGetDeviceQueue>(dlsym(libvulkan, "vkGetDeviceQueue"));
vkQueueSubmit = reinterpret_cast<PFN_vkQueueSubmit>(dlsym(libvulkan, "vkQueueSubmit"));
vkQueueWaitIdle = reinterpret_cast<PFN_vkQueueWaitIdle>(dlsym(libvulkan, "vkQueueWaitIdle"));
vkDeviceWaitIdle = reinterpret_cast<PFN_vkDeviceWaitIdle>(dlsym(libvulkan, "vkDeviceWaitIdle"));
vkAllocateMemory = reinterpret_cast<PFN_vkAllocateMemory>(dlsym(libvulkan, "vkAllocateMemory"));
vkFreeMemory = reinterpret_cast<PFN_vkFreeMemory>(dlsym(libvulkan, "vkFreeMemory"));
vkMapMemory = reinterpret_cast<PFN_vkMapMemory>(dlsym(libvulkan, "vkMapMemory"));
vkUnmapMemory = reinterpret_cast<PFN_vkUnmapMemory>(dlsym(libvulkan, "vkUnmapMemory"));
vkFlushMappedMemoryRanges = reinterpret_cast<PFN_vkFlushMappedMemoryRanges>(dlsym(libvulkan, "vkFlushMappedMemoryRanges"));
vkInvalidateMappedMemoryRanges = reinterpret_cast<PFN_vkInvalidateMappedMemoryRanges>(dlsym(libvulkan, "vkInvalidateMappedMemoryRanges"));
vkGetDeviceMemoryCommitment = reinterpret_cast<PFN_vkGetDeviceMemoryCommitment>(dlsym(libvulkan, "vkGetDeviceMemoryCommitment"));
vkBindBufferMemory = reinterpret_cast<PFN_vkBindBufferMemory>(dlsym(libvulkan, "vkBindBufferMemory"));
vkBindImageMemory = reinterpret_cast<PFN_vkBindImageMemory>(dlsym(libvulkan, "vkBindImageMemory"));
vkGetBufferMemoryRequirements = reinterpret_cast<PFN_vkGetBufferMemoryRequirements>(dlsym(libvulkan, "vkGetBufferMemoryRequirements"));
vkGetImageMemoryRequirements = reinterpret_cast<PFN_vkGetImageMemoryRequirements>(dlsym(libvulkan, "vkGetImageMemoryRequirements"));
vkGetImageSparseMemoryRequirements = reinterpret_cast<PFN_vkGetImageSparseMemoryRequirements>(dlsym(libvulkan, "vkGetImageSparseMemoryRequirements"));
vkGetPhysicalDeviceSparseImageFormatProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceSparseImageFormatProperties>(dlsym(libvulkan, "vkGetPhysicalDeviceSparseImageFormatProperties"));
vkQueueBindSparse = reinterpret_cast<PFN_vkQueueBindSparse>(dlsym(libvulkan, "vkQueueBindSparse"));
vkCreateFence = reinterpret_cast<PFN_vkCreateFence>(dlsym(libvulkan, "vkCreateFence"));
vkDestroyFence = reinterpret_cast<PFN_vkDestroyFence>(dlsym(libvulkan, "vkDestroyFence"));
vkResetFences = reinterpret_cast<PFN_vkResetFences>(dlsym(libvulkan, "vkResetFences"));
vkGetFenceStatus = reinterpret_cast<PFN_vkGetFenceStatus>(dlsym(libvulkan, "vkGetFenceStatus"));
vkWaitForFences = reinterpret_cast<PFN_vkWaitForFences>(dlsym(libvulkan, "vkWaitForFences"));
vkCreateSemaphore = reinterpret_cast<PFN_vkCreateSemaphore>(dlsym(libvulkan, "vkCreateSemaphore"));
vkDestroySemaphore = reinterpret_cast<PFN_vkDestroySemaphore>(dlsym(libvulkan, "vkDestroySemaphore"));
vkCreateEvent = reinterpret_cast<PFN_vkCreateEvent>(dlsym(libvulkan, "vkCreateEvent"));
vkDestroyEvent = reinterpret_cast<PFN_vkDestroyEvent>(dlsym(libvulkan, "vkDestroyEvent"));
vkGetEventStatus = reinterpret_cast<PFN_vkGetEventStatus>(dlsym(libvulkan, "vkGetEventStatus"));
vkSetEvent = reinterpret_cast<PFN_vkSetEvent>(dlsym(libvulkan, "vkSetEvent"));
vkResetEvent = reinterpret_cast<PFN_vkResetEvent>(dlsym(libvulkan, "vkResetEvent"));
vkCreateQueryPool = reinterpret_cast<PFN_vkCreateQueryPool>(dlsym(libvulkan, "vkCreateQueryPool"));
vkDestroyQueryPool = reinterpret_cast<PFN_vkDestroyQueryPool>(dlsym(libvulkan, "vkDestroyQueryPool"));
vkGetQueryPoolResults = reinterpret_cast<PFN_vkGetQueryPoolResults>(dlsym(libvulkan, "vkGetQueryPoolResults"));
vkCreateBuffer = reinterpret_cast<PFN_vkCreateBuffer>(dlsym(libvulkan, "vkCreateBuffer"));
vkDestroyBuffer = reinterpret_cast<PFN_vkDestroyBuffer>(dlsym(libvulkan, "vkDestroyBuffer"));
vkCreateBufferView = reinterpret_cast<PFN_vkCreateBufferView>(dlsym(libvulkan, "vkCreateBufferView"));
vkDestroyBufferView = reinterpret_cast<PFN_vkDestroyBufferView>(dlsym(libvulkan, "vkDestroyBufferView"));
vkCreateImage = reinterpret_cast<PFN_vkCreateImage>(dlsym(libvulkan, "vkCreateImage"));
vkDestroyImage = reinterpret_cast<PFN_vkDestroyImage>(dlsym(libvulkan, "vkDestroyImage"));
vkGetImageSubresourceLayout = reinterpret_cast<PFN_vkGetImageSubresourceLayout>(dlsym(libvulkan, "vkGetImageSubresourceLayout"));
vkCreateImageView = reinterpret_cast<PFN_vkCreateImageView>(dlsym(libvulkan, "vkCreateImageView"));
vkDestroyImageView = reinterpret_cast<PFN_vkDestroyImageView>(dlsym(libvulkan, "vkDestroyImageView"));
vkCreateShaderModule = reinterpret_cast<PFN_vkCreateShaderModule>(dlsym(libvulkan, "vkCreateShaderModule"));
vkDestroyShaderModule = reinterpret_cast<PFN_vkDestroyShaderModule>(dlsym(libvulkan, "vkDestroyShaderModule"));
vkCreatePipelineCache = reinterpret_cast<PFN_vkCreatePipelineCache>(dlsym(libvulkan, "vkCreatePipelineCache"));
vkDestroyPipelineCache = reinterpret_cast<PFN_vkDestroyPipelineCache>(dlsym(libvulkan, "vkDestroyPipelineCache"));
vkGetPipelineCacheData = reinterpret_cast<PFN_vkGetPipelineCacheData>(dlsym(libvulkan, "vkGetPipelineCacheData"));
vkMergePipelineCaches = reinterpret_cast<PFN_vkMergePipelineCaches>(dlsym(libvulkan, "vkMergePipelineCaches"));
vkCreateGraphicsPipelines = reinterpret_cast<PFN_vkCreateGraphicsPipelines>(dlsym(libvulkan, "vkCreateGraphicsPipelines"));
vkCreateComputePipelines = reinterpret_cast<PFN_vkCreateComputePipelines>(dlsym(libvulkan, "vkCreateComputePipelines"));
vkDestroyPipeline = reinterpret_cast<PFN_vkDestroyPipeline>(dlsym(libvulkan, "vkDestroyPipeline"));
vkCreatePipelineLayout = reinterpret_cast<PFN_vkCreatePipelineLayout>(dlsym(libvulkan, "vkCreatePipelineLayout"));
vkDestroyPipelineLayout = reinterpret_cast<PFN_vkDestroyPipelineLayout>(dlsym(libvulkan, "vkDestroyPipelineLayout"));
vkCreateSampler = reinterpret_cast<PFN_vkCreateSampler>(dlsym(libvulkan, "vkCreateSampler"));
vkDestroySampler = reinterpret_cast<PFN_vkDestroySampler>(dlsym(libvulkan, "vkDestroySampler"));
vkCreateDescriptorSetLayout = reinterpret_cast<PFN_vkCreateDescriptorSetLayout>(dlsym(libvulkan, "vkCreateDescriptorSetLayout"));
vkDestroyDescriptorSetLayout = reinterpret_cast<PFN_vkDestroyDescriptorSetLayout>(dlsym(libvulkan, "vkDestroyDescriptorSetLayout"));
vkCreateDescriptorPool = reinterpret_cast<PFN_vkCreateDescriptorPool>(dlsym(libvulkan, "vkCreateDescriptorPool"));
vkDestroyDescriptorPool = reinterpret_cast<PFN_vkDestroyDescriptorPool>(dlsym(libvulkan, "vkDestroyDescriptorPool"));
vkResetDescriptorPool = reinterpret_cast<PFN_vkResetDescriptorPool>(dlsym(libvulkan, "vkResetDescriptorPool"));
vkAllocateDescriptorSets = reinterpret_cast<PFN_vkAllocateDescriptorSets>(dlsym(libvulkan, "vkAllocateDescriptorSets"));
vkFreeDescriptorSets = reinterpret_cast<PFN_vkFreeDescriptorSets>(dlsym(libvulkan, "vkFreeDescriptorSets"));
vkUpdateDescriptorSets = reinterpret_cast<PFN_vkUpdateDescriptorSets>(dlsym(libvulkan, "vkUpdateDescriptorSets"));
vkCreateFramebuffer = reinterpret_cast<PFN_vkCreateFramebuffer>(dlsym(libvulkan, "vkCreateFramebuffer"));
vkDestroyFramebuffer = reinterpret_cast<PFN_vkDestroyFramebuffer>(dlsym(libvulkan, "vkDestroyFramebuffer"));
vkCreateRenderPass = reinterpret_cast<PFN_vkCreateRenderPass>(dlsym(libvulkan, "vkCreateRenderPass"));
vkDestroyRenderPass = reinterpret_cast<PFN_vkDestroyRenderPass>(dlsym(libvulkan, "vkDestroyRenderPass"));
vkGetRenderAreaGranularity = reinterpret_cast<PFN_vkGetRenderAreaGranularity>(dlsym(libvulkan, "vkGetRenderAreaGranularity"));
vkCreateCommandPool = reinterpret_cast<PFN_vkCreateCommandPool>(dlsym(libvulkan, "vkCreateCommandPool"));
vkDestroyCommandPool = reinterpret_cast<PFN_vkDestroyCommandPool>(dlsym(libvulkan, "vkDestroyCommandPool"));
vkResetCommandPool = reinterpret_cast<PFN_vkResetCommandPool>(dlsym(libvulkan, "vkResetCommandPool"));
vkAllocateCommandBuffers = reinterpret_cast<PFN_vkAllocateCommandBuffers>(dlsym(libvulkan, "vkAllocateCommandBuffers"));
vkFreeCommandBuffers = reinterpret_cast<PFN_vkFreeCommandBuffers>(dlsym(libvulkan, "vkFreeCommandBuffers"));
vkBeginCommandBuffer = reinterpret_cast<PFN_vkBeginCommandBuffer>(dlsym(libvulkan, "vkBeginCommandBuffer"));
vkEndCommandBuffer = reinterpret_cast<PFN_vkEndCommandBuffer>(dlsym(libvulkan, "vkEndCommandBuffer"));
vkResetCommandBuffer = reinterpret_cast<PFN_vkResetCommandBuffer>(dlsym(libvulkan, "vkResetCommandBuffer"));
vkCmdBindPipeline = reinterpret_cast<PFN_vkCmdBindPipeline>(dlsym(libvulkan, "vkCmdBindPipeline"));
vkCmdSetViewport = reinterpret_cast<PFN_vkCmdSetViewport>(dlsym(libvulkan, "vkCmdSetViewport"));
vkCmdSetScissor = reinterpret_cast<PFN_vkCmdSetScissor>(dlsym(libvulkan, "vkCmdSetScissor"));
vkCmdSetLineWidth = reinterpret_cast<PFN_vkCmdSetLineWidth>(dlsym(libvulkan, "vkCmdSetLineWidth"));
vkCmdSetDepthBias = reinterpret_cast<PFN_vkCmdSetDepthBias>(dlsym(libvulkan, "vkCmdSetDepthBias"));
vkCmdSetBlendConstants = reinterpret_cast<PFN_vkCmdSetBlendConstants>(dlsym(libvulkan, "vkCmdSetBlendConstants"));
vkCmdSetDepthBounds = reinterpret_cast<PFN_vkCmdSetDepthBounds>(dlsym(libvulkan, "vkCmdSetDepthBounds"));
vkCmdSetStencilCompareMask = reinterpret_cast<PFN_vkCmdSetStencilCompareMask>(dlsym(libvulkan, "vkCmdSetStencilCompareMask"));
vkCmdSetStencilWriteMask = reinterpret_cast<PFN_vkCmdSetStencilWriteMask>(dlsym(libvulkan, "vkCmdSetStencilWriteMask"));
vkCmdSetStencilReference = reinterpret_cast<PFN_vkCmdSetStencilReference>(dlsym(libvulkan, "vkCmdSetStencilReference"));
vkCmdBindDescriptorSets = reinterpret_cast<PFN_vkCmdBindDescriptorSets>(dlsym(libvulkan, "vkCmdBindDescriptorSets"));
vkCmdBindIndexBuffer = reinterpret_cast<PFN_vkCmdBindIndexBuffer>(dlsym(libvulkan, "vkCmdBindIndexBuffer"));
vkCmdBindVertexBuffers = reinterpret_cast<PFN_vkCmdBindVertexBuffers>(dlsym(libvulkan, "vkCmdBindVertexBuffers"));
vkCmdDraw = reinterpret_cast<PFN_vkCmdDraw>(dlsym(libvulkan, "vkCmdDraw"));
vkCmdDrawIndexed = reinterpret_cast<PFN_vkCmdDrawIndexed>(dlsym(libvulkan, "vkCmdDrawIndexed"));
vkCmdDrawIndirect = reinterpret_cast<PFN_vkCmdDrawIndirect>(dlsym(libvulkan, "vkCmdDrawIndirect"));
vkCmdDrawIndexedIndirect = reinterpret_cast<PFN_vkCmdDrawIndexedIndirect>(dlsym(libvulkan, "vkCmdDrawIndexedIndirect"));
vkCmdDispatch = reinterpret_cast<PFN_vkCmdDispatch>(dlsym(libvulkan, "vkCmdDispatch"));
vkCmdDispatchIndirect = reinterpret_cast<PFN_vkCmdDispatchIndirect>(dlsym(libvulkan, "vkCmdDispatchIndirect"));
vkCmdCopyBuffer = reinterpret_cast<PFN_vkCmdCopyBuffer>(dlsym(libvulkan, "vkCmdCopyBuffer"));
vkCmdCopyImage = reinterpret_cast<PFN_vkCmdCopyImage>(dlsym(libvulkan, "vkCmdCopyImage"));
vkCmdBlitImage = reinterpret_cast<PFN_vkCmdBlitImage>(dlsym(libvulkan, "vkCmdBlitImage"));
vkCmdCopyBufferToImage = reinterpret_cast<PFN_vkCmdCopyBufferToImage>(dlsym(libvulkan, "vkCmdCopyBufferToImage"));
vkCmdCopyImageToBuffer = reinterpret_cast<PFN_vkCmdCopyImageToBuffer>(dlsym(libvulkan, "vkCmdCopyImageToBuffer"));
vkCmdUpdateBuffer = reinterpret_cast<PFN_vkCmdUpdateBuffer>(dlsym(libvulkan, "vkCmdUpdateBuffer"));
vkCmdFillBuffer = reinterpret_cast<PFN_vkCmdFillBuffer>(dlsym(libvulkan, "vkCmdFillBuffer"));
vkCmdClearColorImage = reinterpret_cast<PFN_vkCmdClearColorImage>(dlsym(libvulkan, "vkCmdClearColorImage"));
vkCmdClearDepthStencilImage = reinterpret_cast<PFN_vkCmdClearDepthStencilImage>(dlsym(libvulkan, "vkCmdClearDepthStencilImage"));
vkCmdClearAttachments = reinterpret_cast<PFN_vkCmdClearAttachments>(dlsym(libvulkan, "vkCmdClearAttachments"));
vkCmdResolveImage = reinterpret_cast<PFN_vkCmdResolveImage>(dlsym(libvulkan, "vkCmdResolveImage"));
vkCmdSetEvent = reinterpret_cast<PFN_vkCmdSetEvent>(dlsym(libvulkan, "vkCmdSetEvent"));
vkCmdResetEvent = reinterpret_cast<PFN_vkCmdResetEvent>(dlsym(libvulkan, "vkCmdResetEvent"));
vkCmdWaitEvents = reinterpret_cast<PFN_vkCmdWaitEvents>(dlsym(libvulkan, "vkCmdWaitEvents"));
vkCmdPipelineBarrier = reinterpret_cast<PFN_vkCmdPipelineBarrier>(dlsym(libvulkan, "vkCmdPipelineBarrier"));
vkCmdBeginQuery = reinterpret_cast<PFN_vkCmdBeginQuery>(dlsym(libvulkan, "vkCmdBeginQuery"));
vkCmdEndQuery = reinterpret_cast<PFN_vkCmdEndQuery>(dlsym(libvulkan, "vkCmdEndQuery"));
vkCmdResetQueryPool = reinterpret_cast<PFN_vkCmdResetQueryPool>(dlsym(libvulkan, "vkCmdResetQueryPool"));
vkCmdWriteTimestamp = reinterpret_cast<PFN_vkCmdWriteTimestamp>(dlsym(libvulkan, "vkCmdWriteTimestamp"));
vkCmdCopyQueryPoolResults = reinterpret_cast<PFN_vkCmdCopyQueryPoolResults>(dlsym(libvulkan, "vkCmdCopyQueryPoolResults"));
vkCmdPushConstants = reinterpret_cast<PFN_vkCmdPushConstants>(dlsym(libvulkan, "vkCmdPushConstants"));
vkCmdBeginRenderPass = reinterpret_cast<PFN_vkCmdBeginRenderPass>(dlsym(libvulkan, "vkCmdBeginRenderPass"));
vkCmdNextSubpass = reinterpret_cast<PFN_vkCmdNextSubpass>(dlsym(libvulkan, "vkCmdNextSubpass"));
vkCmdEndRenderPass = reinterpret_cast<PFN_vkCmdEndRenderPass>(dlsym(libvulkan, "vkCmdEndRenderPass"));
vkCmdExecuteCommands = reinterpret_cast<PFN_vkCmdExecuteCommands>(dlsym(libvulkan, "vkCmdExecuteCommands"));
vkDestroySurfaceKHR = reinterpret_cast<PFN_vkDestroySurfaceKHR>(dlsym(libvulkan, "vkDestroySurfaceKHR"));
vkGetPhysicalDeviceSurfaceSupportKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceSupportKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceSurfaceSupportKHR"));
vkGetPhysicalDeviceSurfaceCapabilitiesKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"));
vkGetPhysicalDeviceSurfaceFormatsKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceSurfaceFormatsKHR"));
vkGetPhysicalDeviceSurfacePresentModesKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfacePresentModesKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceSurfacePresentModesKHR"));
vkCreateSwapchainKHR = reinterpret_cast<PFN_vkCreateSwapchainKHR>(dlsym(libvulkan, "vkCreateSwapchainKHR"));
vkDestroySwapchainKHR = reinterpret_cast<PFN_vkDestroySwapchainKHR>(dlsym(libvulkan, "vkDestroySwapchainKHR"));
vkGetSwapchainImagesKHR = reinterpret_cast<PFN_vkGetSwapchainImagesKHR>(dlsym(libvulkan, "vkGetSwapchainImagesKHR"));
vkAcquireNextImageKHR = reinterpret_cast<PFN_vkAcquireNextImageKHR>(dlsym(libvulkan, "vkAcquireNextImageKHR"));
vkQueuePresentKHR = reinterpret_cast<PFN_vkQueuePresentKHR>(dlsym(libvulkan, "vkQueuePresentKHR"));
// vkGetPhysicalDeviceDisplayPropertiesKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPropertiesKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceDisplayPropertiesKHR"));
// vkGetPhysicalDeviceDisplayPlanePropertiesKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR"));
// vkGetDisplayPlaneSupportedDisplaysKHR = reinterpret_cast<PFN_vkGetDisplayPlaneSupportedDisplaysKHR>(dlsym(libvulkan, "vkGetDisplayPlaneSupportedDisplaysKHR"));
// vkGetDisplayModePropertiesKHR = reinterpret_cast<PFN_vkGetDisplayModePropertiesKHR>(dlsym(libvulkan, "vkGetDisplayModePropertiesKHR"));
// vkCreateDisplayModeKHR = reinterpret_cast<PFN_vkCreateDisplayModeKHR>(dlsym(libvulkan, "vkCreateDisplayModeKHR"));
// vkGetDisplayPlaneCapabilitiesKHR = reinterpret_cast<PFN_vkGetDisplayPlaneCapabilitiesKHR>(dlsym(libvulkan, "vkGetDisplayPlaneCapabilitiesKHR"));
// vkCreateDisplayPlaneSurfaceKHR = reinterpret_cast<PFN_vkCreateDisplayPlaneSurfaceKHR>(dlsym(libvulkan, "vkCreateDisplayPlaneSurfaceKHR"));
// vkCreateSharedSwapchainsKHR = reinterpret_cast<PFN_vkCreateSharedSwapchainsKHR>(dlsym(libvulkan, "vkCreateSharedSwapchainsKHR"));
#ifdef VK_USE_PLATFORM_XLIB_KHR
// vkCreateXlibSurfaceKHR = reinterpret_cast<PFN_vkCreateXlibSurfaceKHR>(dlsym(libvulkan, "vkCreateXlibSurfaceKHR"));
// vkGetPhysicalDeviceXlibPresentationSupportKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceXlibPresentationSupportKHR"));
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
// vkCreateXcbSurfaceKHR = reinterpret_cast<PFN_vkCreateXcbSurfaceKHR>(dlsym(libvulkan, "vkCreateXcbSurfaceKHR"));
// vkGetPhysicalDeviceXcbPresentationSupportKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceXcbPresentationSupportKHR"));
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
// vkCreateWaylandSurfaceKHR = reinterpret_cast<PFN_vkCreateWaylandSurfaceKHR>(dlsym(libvulkan, "vkCreateWaylandSurfaceKHR"));
// vkGetPhysicalDeviceWaylandPresentationSupportKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceWaylandPresentationSupportKHR"));
#endif
#ifdef VK_USE_PLATFORM_MIR_KHR
// vkCreateMirSurfaceKHR = reinterpret_cast<PFN_vkCreateMirSurfaceKHR>(dlsym(libvulkan, "vkCreateMirSurfaceKHR"));
// vkGetPhysicalDeviceMirPresentationSupportKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceMirPresentationSupportKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceMirPresentationSupportKHR"));
#endif
#ifdef VK_USE_PLATFORM_ANDROID_KHR
// vkCreateAndroidSurfaceKHR = reinterpret_cast<PFN_vkCreateAndroidSurfaceKHR>(dlsym(libvulkan, "vkCreateAndroidSurfaceKHR"));
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
// vkCreateWin32SurfaceKHR = reinterpret_cast<PFN_vkCreateWin32SurfaceKHR>(dlsym(libvulkan, "vkCreateWin32SurfaceKHR"));
// vkGetPhysicalDeviceWin32PresentationSupportKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceWin32PresentationSupportKHR"));
#endif
#ifdef USE_DEBUG_EXTENTIONS
vkCreateDebugReportCallbackEXT = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(dlsym(libvulkan, "vkCreateDebugReportCallbackEXT"));
vkDestroyDebugReportCallbackEXT = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(dlsym(libvulkan, "vkDestroyDebugReportCallbackEXT"));
vkDebugReportMessageEXT = reinterpret_cast<PFN_vkDebugReportMessageEXT>(dlsym(libvulkan, "vkDebugReportMessageEXT"));
#endif
return SUPPORTED;
}
bool IsVulkanSupported() {
return InitVulkan() == SUPPORTED;
}

View File

@ -0,0 +1,227 @@
// Copyright 2016 Google Inc. All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
// This file is generated.
#pragma once
#define VK_NO_PROTOTYPES 1
#include <vulkan/vulkan.h>
enum VulkanWrapperStatus {
UNSUPPORTED = 0,
SUPPORTED = 1,
};
/**
* Return whether Vulkan is supported in this system
*/
bool IsVulkanSupported();
// VK_core
extern PFN_vkCreateInstance vkCreateInstance;
extern PFN_vkDestroyInstance vkDestroyInstance;
extern PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
extern PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures;
extern PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties;
extern PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties;
extern PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
extern PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties;
extern PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties;
extern PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
extern PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
extern PFN_vkCreateDevice vkCreateDevice;
extern PFN_vkDestroyDevice vkDestroyDevice;
extern PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
extern PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties;
extern PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties;
extern PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties;
extern PFN_vkGetDeviceQueue vkGetDeviceQueue;
extern PFN_vkQueueSubmit vkQueueSubmit;
extern PFN_vkQueueWaitIdle vkQueueWaitIdle;
extern PFN_vkDeviceWaitIdle vkDeviceWaitIdle;
extern PFN_vkAllocateMemory vkAllocateMemory;
extern PFN_vkFreeMemory vkFreeMemory;
extern PFN_vkMapMemory vkMapMemory;
extern PFN_vkUnmapMemory vkUnmapMemory;
extern PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges;
extern PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges;
extern PFN_vkGetDeviceMemoryCommitment vkGetDeviceMemoryCommitment;
extern PFN_vkBindBufferMemory vkBindBufferMemory;
extern PFN_vkBindImageMemory vkBindImageMemory;
extern PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements;
extern PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements;
extern PFN_vkGetImageSparseMemoryRequirements vkGetImageSparseMemoryRequirements;
extern PFN_vkGetPhysicalDeviceSparseImageFormatProperties vkGetPhysicalDeviceSparseImageFormatProperties;
extern PFN_vkQueueBindSparse vkQueueBindSparse;
extern PFN_vkCreateFence vkCreateFence;
extern PFN_vkDestroyFence vkDestroyFence;
extern PFN_vkResetFences vkResetFences;
extern PFN_vkGetFenceStatus vkGetFenceStatus;
extern PFN_vkWaitForFences vkWaitForFences;
extern PFN_vkCreateSemaphore vkCreateSemaphore;
extern PFN_vkDestroySemaphore vkDestroySemaphore;
extern PFN_vkCreateEvent vkCreateEvent;
extern PFN_vkDestroyEvent vkDestroyEvent;
extern PFN_vkGetEventStatus vkGetEventStatus;
extern PFN_vkSetEvent vkSetEvent;
extern PFN_vkResetEvent vkResetEvent;
extern PFN_vkCreateQueryPool vkCreateQueryPool;
extern PFN_vkDestroyQueryPool vkDestroyQueryPool;
extern PFN_vkGetQueryPoolResults vkGetQueryPoolResults;
extern PFN_vkCreateBuffer vkCreateBuffer;
extern PFN_vkDestroyBuffer vkDestroyBuffer;
extern PFN_vkCreateBufferView vkCreateBufferView;
extern PFN_vkDestroyBufferView vkDestroyBufferView;
extern PFN_vkCreateImage vkCreateImage;
extern PFN_vkDestroyImage vkDestroyImage;
extern PFN_vkGetImageSubresourceLayout vkGetImageSubresourceLayout;
extern PFN_vkCreateImageView vkCreateImageView;
extern PFN_vkDestroyImageView vkDestroyImageView;
extern PFN_vkCreateShaderModule vkCreateShaderModule;
extern PFN_vkDestroyShaderModule vkDestroyShaderModule;
extern PFN_vkCreatePipelineCache vkCreatePipelineCache;
extern PFN_vkDestroyPipelineCache vkDestroyPipelineCache;
extern PFN_vkGetPipelineCacheData vkGetPipelineCacheData;
extern PFN_vkMergePipelineCaches vkMergePipelineCaches;
extern PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines;
extern PFN_vkCreateComputePipelines vkCreateComputePipelines;
extern PFN_vkDestroyPipeline vkDestroyPipeline;
extern PFN_vkCreatePipelineLayout vkCreatePipelineLayout;
extern PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout;
extern PFN_vkCreateSampler vkCreateSampler;
extern PFN_vkDestroySampler vkDestroySampler;
extern PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout;
extern PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout;
extern PFN_vkCreateDescriptorPool vkCreateDescriptorPool;
extern PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool;
extern PFN_vkResetDescriptorPool vkResetDescriptorPool;
extern PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets;
extern PFN_vkFreeDescriptorSets vkFreeDescriptorSets;
extern PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets;
extern PFN_vkCreateFramebuffer vkCreateFramebuffer;
extern PFN_vkDestroyFramebuffer vkDestroyFramebuffer;
extern PFN_vkCreateRenderPass vkCreateRenderPass;
extern PFN_vkDestroyRenderPass vkDestroyRenderPass;
extern PFN_vkGetRenderAreaGranularity vkGetRenderAreaGranularity;
extern PFN_vkCreateCommandPool vkCreateCommandPool;
extern PFN_vkDestroyCommandPool vkDestroyCommandPool;
extern PFN_vkResetCommandPool vkResetCommandPool;
extern PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers;
extern PFN_vkFreeCommandBuffers vkFreeCommandBuffers;
extern PFN_vkBeginCommandBuffer vkBeginCommandBuffer;
extern PFN_vkEndCommandBuffer vkEndCommandBuffer;
extern PFN_vkResetCommandBuffer vkResetCommandBuffer;
extern PFN_vkCmdBindPipeline vkCmdBindPipeline;
extern PFN_vkCmdSetViewport vkCmdSetViewport;
extern PFN_vkCmdSetScissor vkCmdSetScissor;
extern PFN_vkCmdSetLineWidth vkCmdSetLineWidth;
extern PFN_vkCmdSetDepthBias vkCmdSetDepthBias;
extern PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants;
extern PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds;
extern PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask;
extern PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask;
extern PFN_vkCmdSetStencilReference vkCmdSetStencilReference;
extern PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets;
extern PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer;
extern PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers;
extern PFN_vkCmdDraw vkCmdDraw;
extern PFN_vkCmdDrawIndexed vkCmdDrawIndexed;
extern PFN_vkCmdDrawIndirect vkCmdDrawIndirect;
extern PFN_vkCmdDrawIndexedIndirect vkCmdDrawIndexedIndirect;
extern PFN_vkCmdDispatch vkCmdDispatch;
extern PFN_vkCmdDispatchIndirect vkCmdDispatchIndirect;
extern PFN_vkCmdCopyBuffer vkCmdCopyBuffer;
extern PFN_vkCmdCopyImage vkCmdCopyImage;
extern PFN_vkCmdBlitImage vkCmdBlitImage;
extern PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage;
extern PFN_vkCmdCopyImageToBuffer vkCmdCopyImageToBuffer;
extern PFN_vkCmdUpdateBuffer vkCmdUpdateBuffer;
extern PFN_vkCmdFillBuffer vkCmdFillBuffer;
extern PFN_vkCmdClearColorImage vkCmdClearColorImage;
extern PFN_vkCmdClearDepthStencilImage vkCmdClearDepthStencilImage;
extern PFN_vkCmdClearAttachments vkCmdClearAttachments;
extern PFN_vkCmdResolveImage vkCmdResolveImage;
extern PFN_vkCmdSetEvent vkCmdSetEvent;
extern PFN_vkCmdResetEvent vkCmdResetEvent;
extern PFN_vkCmdWaitEvents vkCmdWaitEvents;
extern PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier;
extern PFN_vkCmdBeginQuery vkCmdBeginQuery;
extern PFN_vkCmdEndQuery vkCmdEndQuery;
extern PFN_vkCmdResetQueryPool vkCmdResetQueryPool;
extern PFN_vkCmdWriteTimestamp vkCmdWriteTimestamp;
extern PFN_vkCmdCopyQueryPoolResults vkCmdCopyQueryPoolResults;
extern PFN_vkCmdPushConstants vkCmdPushConstants;
extern PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass;
extern PFN_vkCmdNextSubpass vkCmdNextSubpass;
extern PFN_vkCmdEndRenderPass vkCmdEndRenderPass;
extern PFN_vkCmdExecuteCommands vkCmdExecuteCommands;
// VK_KHR_surface
extern PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
extern PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
extern PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
extern PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
extern PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
// VK_KHR_swapchain
extern PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR;
extern PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
extern PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
extern PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
extern PFN_vkQueuePresentKHR vkQueuePresentKHR;
// VK_KHR_display
extern PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR;
extern PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR;
extern PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR;
extern PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR;
extern PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR;
extern PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR;
extern PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR;
// VK_KHR_display_swapchain
extern PFN_vkCreateSharedSwapchainsKHR vkCreateSharedSwapchainsKHR;
#ifdef VK_USE_PLATFORM_XLIB_KHR
// VK_KHR_xlib_surface
extern PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR;
extern PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
// VK_KHR_xcb_surface
extern PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR;
extern PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
// VK_KHR_wayland_surface
extern PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;
extern PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_MIR_KHR
// VK_KHR_mir_surface
extern PFN_vkCreateMirSurfaceKHR vkCreateMirSurfaceKHR;
extern PFN_vkGetPhysicalDeviceMirPresentationSupportKHR vkGetPhysicalDeviceMirPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_ANDROID_KHR
// VK_KHR_android_surface
extern PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR;
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
// VK_KHR_win32_surface
extern PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
extern PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR;
#endif
#ifdef USE_DEBUG_EXTENTIONS
#include <vulkan/vk_sdk_platform.h>
// VK_EXT_debug_report
extern PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
extern PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
extern PFN_vkDebugReportMessageEXT vkDebugReportMessageEXT;
#endif

View File

@ -1,24 +1,58 @@
package com.xyzshell.andinfo
import android.content.Context
import com.xyzshell.andinfo.libs.CpuInfo
import com.xyzshell.andinfo.libs.DeviceInfo
import com.xyzshell.andinfo.libs.DisplayInfo
import com.xyzshell.andinfo.libs.SensorInfo
import com.xyzshell.andinfo.libs.BuildInfo
import com.xyzshell.andinfo.libs.GpuInfo
import com.xyzshell.andinfo.libs.InputInfo
class AndInfo private constructor() {
class AndInfo private constructor(private val applicationContext: Context) {
companion object {
val instance = SingletonHolder.holder
private lateinit var INSTANCE: AndInfo
fun init(context: Context) {
INSTANCE = AndInfo(context.applicationContext)
}
private object SingletonHolder {
val holder= AndInfo()
val instance: AndInfo
get() {
if (!::INSTANCE.isInitialized) {
throw IllegalStateException("AndInfo must be initialized with init(context) before use.")
}
return INSTANCE
}
}
private val _cpu: CpuInfo
private val _device: DeviceInfo
private val _display: DisplayInfo
private val _sensor: SensorInfo
private val _build: BuildInfo
private val _gpu: GpuInfo
private val _input: InputInfo
init {
_cpu = CpuInfo()
_device = DeviceInfo(applicationContext)
_display = DisplayInfo(applicationContext)
_sensor = SensorInfo(applicationContext)
_build = BuildInfo(applicationContext)
_gpu = GpuInfo(applicationContext)
_input = InputInfo(applicationContext)
}
val cpu get() = _cpu
val device get() = _device
val display get() = _display
val sensor get() = _sensor
val build get() = _build
val gpu get() = _gpu
val input get() = _input
val context get() = applicationContext
}

View File

@ -0,0 +1,111 @@
package com.xyzshell.andinfo.libs
import android.content.Context
import android.os.Build
// import androidx.security.state.SecurityStateManagerCompat
import java.util.Date
class BuildInfo(private val context: Context) {
// private val securityStateManager = SecurityStateManagerCompat(context)
// private val globalSecurityState = securityStateManager.getGlobalSecurityState()
val fingerprint: String
get() = Build.FINGERPRINT
val tags: String
get() = Build.TAGS
val type: String
get() = Build.TYPE
val buildDate: Date
get() = Date(Build.TIME)
val host: String
get() = Build.HOST
val user: String
get() = Build.USER
val id: String
get() = Build.ID
val display: String
get() = Build.DISPLAY
val versionRelease: String
get() = Build.VERSION.RELEASE
val versionCodename: String
get() = Build.VERSION.CODENAME
val versionSdkInt: Int
get() = Build.VERSION.SDK_INT
val versionPreviewSdkInt: Int
get() = Build.VERSION.PREVIEW_SDK_INT
val securityPatch: String
get() = Build.VERSION.SECURITY_PATCH
val baseOs: String
get() = Build.VERSION.BASE_OS
val incremental: String
get() = Build.VERSION.INCREMENTAL
val releaseOrCodename: String?
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) Build.VERSION.RELEASE_OR_CODENAME else null
val mediaPerformanceClass: Int
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.VERSION.MEDIA_PERFORMANCE_CLASS else 0
val releaseOrPreviewDisplay: String?
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) Build.VERSION.RELEASE_OR_PREVIEW_DISPLAY else null
val jvmName: String?
get() = System.getProperty("java.vm.name")
val jvmVendor: String?
get() = System.getProperty("java.vm.vendor")
val jvmVersion: String?
get() = System.getProperty("java.vm.version")
val jvmClassVersion: String?
get() = System.getProperty("java.class.version")
val jvmSpecificationName: String?
get() = System.getProperty("java.specification.name")
val jvmSpecificationVendor: String?
get() = System.getProperty("java.specification.vendor")
val jvmSpecificationVersion: String?
get() = System.getProperty("java.specification.version")
val vendorSecurityPatchLevel: String?
get() = null // globalSecurityState.getString(SecurityStateManagerCompat.KEY_VENDOR_SPL)
val kernelVersion: String?
get() = null // globalSecurityState.getString(SecurityStateManagerCompat.KEY_KERNEL_VERSION)
val kernelCompleteVersion: String?
get() = System.getProperty("os.version")
val bootloaderVersion: String
get() = Build.BOOTLOADER
val radioVersion: String?
get() = Build.getRadioVersion()
val fingerprintedPartitions: List<PartitionInfo>
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
Build.getFingerprintedPartitions().map { PartitionInfo(it.name, it.fingerprint) }
} else {
emptyList()
}
data class PartitionInfo(val name: String, val fingerprint: String)
}

View File

@ -0,0 +1,49 @@
package com.xyzshell.andinfo.libs
import android.app.ActivityManager
import android.content.Context
import android.os.Build
class DeviceInfo(private val context: Context) {
private val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val device: String
get() = Build.DEVICE
val brand: String
get() = Build.BRAND
val model: String
get() = Build.MODEL
val manufacturer: String
get() = Build.MANUFACTURER
val productName: String
get() = Build.PRODUCT
val hardwareName: String
get() = Build.HARDWARE
val boardName: String
get() = Build.BOARD
val hardwareSku: String?
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.SKU else null
val odmSku: String?
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.ODM_SKU else null
val socManufacturer: String?
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.SOC_MANUFACTURER else null
val socModel: String?
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.SOC_MODEL else null
fun getMemoryInfo(): ActivityManager.MemoryInfo {
val memoryInfo = ActivityManager.MemoryInfo()
activityManager.getMemoryInfo(memoryInfo)
return memoryInfo
}
}

View File

@ -0,0 +1,64 @@
package com.xyzshell.andinfo.libs
import android.content.Context
import android.hardware.display.DisplayManager
import android.os.Build
import android.view.Display
import android.graphics.Point
import android.util.DisplayMetrics
class DisplayInfo(private val context: Context) {
private val displayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
fun getDefaultDisplayInfo(): DefaultDisplayInfo? {
val defaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY) ?: return null
val displayMetrics = DisplayMetrics()
defaultDisplay.getMetrics(displayMetrics)
val size = Point()
defaultDisplay.getSize(size)
val mode = defaultDisplay.mode
val refreshRate = mode.refreshRate
val isHdr = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
defaultDisplay.hdrCapabilities?.supportedHdrTypes?.isNotEmpty() ?: false
} else {
false
}
val isWideColorGamut = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
defaultDisplay.isWideColorGamut
} else {
false
}
return DefaultDisplayInfo(
id = defaultDisplay.displayId,
name = defaultDisplay.name,
widthPixels = displayMetrics.widthPixels,
heightPixels = displayMetrics.heightPixels,
densityDpi = displayMetrics.densityDpi,
xdpi = displayMetrics.xdpi,
ydpi = displayMetrics.ydpi,
refreshRate = refreshRate,
isHdr = isHdr,
isWideColorGamut = isWideColorGamut
)
}
data class DefaultDisplayInfo(
val id: Int,
val name: String,
val widthPixels: Int,
val heightPixels: Int,
val densityDpi: Int,
val xdpi: Float,
val ydpi: Float,
val refreshRate: Float,
val isHdr: Boolean,
val isWideColorGamut: Boolean
)
}

View File

@ -0,0 +1,49 @@
package com.xyzshell.andinfo.libs
import android.content.Context
import com.xyzshell.andinfo.libs.gpu.models.EglInformation
import com.xyzshell.andinfo.libs.gpu.models.GlInformation
import com.xyzshell.andinfo.libs.gpu.models.VkPhysicalDevice
import com.xyzshell.andinfo.libs.gpu.models.VkPhysicalDeviceType
import com.xyzshell.andinfo.libs.gpu.models.VkVendorId
import com.xyzshell.andinfo.libs.gpu.utils.EglUtils
import com.xyzshell.andinfo.libs.gpu.utils.VkUtils
class GpuInfo(private val context: Context) {
init {
System.loadLibrary("andinfo")
}
fun getGpuInformation(): GpuInformationData {
val vkPhysicalDevices = VkUtils.getVkInfo()
val eglInformation = EglUtils.getEglInformation()
return GpuInformationData(vkPhysicalDevices, eglInformation)
}
data class GpuInformationData(
val vkPhysicalDevices: List<VkPhysicalDevice>?,
val eglInformation: EglInformation?
)
companion object {
val vkPhysicalDeviceTypeToString = mapOf(
VkPhysicalDeviceType.OTHER.value to "Other",
VkPhysicalDeviceType.INTEGRATED_GPU.value to "Integrated GPU",
VkPhysicalDeviceType.DISCRETE_GPU.value to "Discrete GPU",
VkPhysicalDeviceType.VIRTUAL_GPU.value to "Virtual GPU",
VkPhysicalDeviceType.CPU.value to "CPU",
)
val vkVendorIdToString = mapOf(
VkVendorId.KHRONOS to "Khronos",
VkVendorId.VIV to "Vivante",
VkVendorId.VSI to "VeriSilicon",
VkVendorId.KAZAN to "Kazan",
VkVendorId.CODEPLAY to "Codeplay",
VkVendorId.MESA to "Mesa",
VkVendorId.POCL to "POCL",
VkVendorId.MOBILEYE to "Mobileye",
)
}
}

View File

@ -0,0 +1,107 @@
package com.xyzshell.andinfo.libs
import android.content.Context
import android.hardware.input.InputManager
import android.os.Build
import android.view.InputDevice
import android.view.KeyCharacterMap
import androidx.annotation.RequiresApi
class InputInfo(private val context: Context) {
private val inputManager = context.getSystemService(InputManager::class.java)
fun getInputDevices(): List<InputDeviceInfo> {
return inputManager.inputDeviceIds.toList().mapNotNull { id ->
inputManager.getInputDevice(id)?.let { device -> InputDeviceInfo(device) }
}
}
fun getInputDevice(deviceId: Int): InputDeviceInfo? {
return inputManager.getInputDevice(deviceId)?.let { device ->
InputDeviceInfo(device)
}
}
@RequiresApi(Build.VERSION_CODES.S)
fun getMaximumObscuringOpacityForTouch(): Float {
return inputManager.maximumObscuringOpacityForTouch
}
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
fun isStylusPointerIconEnabled(): Boolean {
return inputManager.isStylusPointerIconEnabled
}
data class InputDeviceInfo(val inputDevice: InputDevice) {
val id: Int get() = inputDevice.id
val controllerNumber: Int get() = inputDevice.controllerNumber
val vendorId: Int get() = inputDevice.vendorId
val productId: Int get() = inputDevice.productId
val descriptor: String? get() = inputDevice.descriptor
val isVirtual: Boolean get() = inputDevice.isVirtual
val isExternal: Boolean
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
inputDevice.isExternal
} else {
false
}
val name: String get() = inputDevice.name
val sources: Int get() = inputDevice.sources
val keyboardType: Int get() = inputDevice.keyboardType
val keyCharacterMapKeyboardType: Int get() = inputDevice.keyCharacterMap.keyboardType
val motionRangesCount: Int get() = inputDevice.motionRanges.size
val hasVibrator: Boolean
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
inputDevice.vibratorManager.vibratorIds.isNotEmpty()
} else {
@Suppress("DEPRECATION")
inputDevice.vibrator.hasVibrator()
}
val isEnabled: Boolean
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
inputDevice.isEnabled
} else {
true
}
val hasMicrophone: Boolean get() = inputDevice.hasMicrophone()
companion object {
val keyboardTypeToString = mapOf(
InputDevice.KEYBOARD_TYPE_NONE to "None",
InputDevice.KEYBOARD_TYPE_NON_ALPHABETIC to "Non-alphabetic",
InputDevice.KEYBOARD_TYPE_ALPHABETIC to "Alphabetic",
)
val keyCharacterMapKeyboardTypeToString = mapOf(
KeyCharacterMap.NUMERIC to "Numeric",
KeyCharacterMap.PREDICTIVE to "Predictive",
KeyCharacterMap.ALPHA to "Alpha",
KeyCharacterMap.FULL to "Full",
KeyCharacterMap.SPECIAL_FUNCTION to "Special Function",
)
val sourceClassToString = mapOf(
InputDevice.SOURCE_CLASS_BUTTON to "Button",
InputDevice.SOURCE_CLASS_POINTER to "Pointer",
InputDevice.SOURCE_CLASS_TRACKBALL to "Trackball",
InputDevice.SOURCE_CLASS_POSITION to "Position",
InputDevice.SOURCE_CLASS_JOYSTICK to "Joystick",
)
val sourceToString = mapOf(
InputDevice.SOURCE_KEYBOARD to "Keyboard",
InputDevice.SOURCE_DPAD to "D-Pad",
InputDevice.SOURCE_GAMEPAD to "Gamepad",
InputDevice.SOURCE_TOUCHSCREEN to "Touchscreen",
InputDevice.SOURCE_MOUSE to "Mouse",
InputDevice.SOURCE_STYLUS to "Stylus",
InputDevice.SOURCE_TRACKBALL to "Trackball",
InputDevice.SOURCE_TOUCHPAD to "Touchpad",
InputDevice.SOURCE_TOUCH_NAVIGATION to "Touch Navigation",
InputDevice.SOURCE_ROTARY_ENCODER to "Rotary Encoder",
InputDevice.SOURCE_JOYSTICK to "Joystick",
InputDevice.SOURCE_HDMI to "HDMI",
)
}
}
}

View File

@ -0,0 +1,86 @@
package com.xyzshell.andinfo.libs
import android.content.Context
import android.hardware.Sensor
import android.hardware.SensorDirectChannel
import android.hardware.SensorManager
import android.os.Build
import androidx.annotation.RequiresApi
class SensorInfo(private val context: Context) {
private val sensorManager = context.getSystemService(SensorManager::class.java)
fun getAllSensors(): List<Sensor> {
return sensorManager.getSensorList(Sensor.TYPE_ALL)
}
fun getSensorDetail(sensor: Sensor): SensorDetail {
return SensorDetail(
name = sensor.name,
id = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) sensor.id.takeIf { it > 0 } else null,
stringType = sensor.stringType,
type = sensor.type,
vendor = sensor.vendor,
version = sensor.version,
isDynamicSensor = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) sensor.isDynamicSensor else false,
isWakeUpSensor = sensor.isWakeUpSensor,
fifoMaxEventCount = sensor.fifoMaxEventCount,
fifoReservedEventCount = sensor.fifoReservedEventCount,
minDelay = sensor.minDelay,
maxDelay = sensor.maxDelay,
maximumRange = sensor.maximumRange,
power = sensor.power,
reportingMode = sensor.reportingMode,
resolution = sensor.resolution,
isAdditionalInfoSupported = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) sensor.isAdditionalInfoSupported else false,
highestDirectReportRateLevel = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) sensor.highestDirectReportRateLevel else SensorDirectChannel.RATE_STOP
)
}
fun isDynamicSensorDiscoverySupported(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
sensorManager.isDynamicSensorDiscoverySupported
} else {
false
}
}
data class SensorDetail(
val name: String,
val id: Int?,
val stringType: String,
val type: Int,
val vendor: String,
val version: Int,
val isDynamicSensor: Boolean,
val isWakeUpSensor: Boolean,
val fifoMaxEventCount: Int,
val fifoReservedEventCount: Int,
val minDelay: Int,
val maxDelay: Int,
val maximumRange: Float,
val power: Float,
val reportingMode: Int,
val resolution: Float,
val isAdditionalInfoSupported: Boolean,
val highestDirectReportRateLevel: Int
)
companion object {
val sensorReportingModeToStringResId = mapOf(
Sensor.REPORTING_MODE_CONTINUOUS to "连续",
Sensor.REPORTING_MODE_ON_CHANGE to "变化时",
Sensor.REPORTING_MODE_ONE_SHOT to "单次",
Sensor.REPORTING_MODE_SPECIAL_TRIGGER to "特殊触发",
)
@RequiresApi(Build.VERSION_CODES.O)
val sensorDirectReportModeRatesToStringResId = mapOf(
SensorDirectChannel.RATE_STOP to "停止",
SensorDirectChannel.RATE_NORMAL to "正常",
SensorDirectChannel.RATE_FAST to "快速",
SensorDirectChannel.RATE_VERY_FAST to "非常快速",
)
}
}

View File

@ -0,0 +1,9 @@
package com.xyzshell.andinfo.libs.gpu.models
data class EglInformation(
val eglVendor: String?,
val eglVersion: String?,
val eglExtensions: List<String>?,
val eglClientApi: List<String>?,
val glInformation: GlInformation?,
)

View File

@ -0,0 +1,8 @@
package com.xyzshell.andinfo.libs.gpu.models
data class GlInformation(
val glVendor: String?,
val glRenderer: String?,
val glVersion: String?,
val glExtensions: String?,
)

View File

@ -0,0 +1,49 @@
/*
* SPDX-FileCopyrightText: Sebastiano Barezzi
* SPDX-License-Identifier: Apache-2.0
*/
package com.xyzshell.andinfo.libs.gpu.models
data class VkApiVersion(
/**
* Variant number.
*/
val variant: UInt,
/**
* Major version number.
*/
val major: UInt,
/**
* Minor version number.
*/
val minor: UInt,
/**
* Patch version number.
*/
val patch: UInt,
) {
val version = 0UL
.or(variant.shl(29).toULong())
.or(major.shl(22).toULong())
.or(minor.shl(12).toULong())
.or(patch.toULong())
companion object {
/**
* The variant is a 3-bit integer packed into bits 31-29.
* The major version is a 7-bit integer packed into bits 28-22.
* The minor version number is a 10-bit integer packed into bits 21-12.
* The patch version number is a 12-bit integer packed into bits 11-0.
*/
fun fromVersion(version: ULong): VkApiVersion {
val variant = version.shr(29).toUInt()
val major = version.shr(22).and(0x7FU).toUInt()
val minor = version.shr(12).and(0x3FFU).toUInt()
val patch = version.and(0xFFFU).toUInt()
return VkApiVersion(variant, major, minor, patch)
}
}
}

View File

@ -0,0 +1,20 @@
package com.xyzshell.andinfo.libs.gpu.models
data class VkPhysicalDevice(
val apiVersion: VkVersion,
val driverVersion: Int,
val vendorId: Int,
val registeredVendorId: VkVendorId?,
val deviceId: Int,
val deviceType: VkPhysicalDeviceType,
val deviceName: String,
)
data class VkVersion(
val version: Int,
) {
val major: Int = (version shr 22) and 0x7F
val minor: Int = (version shr 12) and 0x3FF
val patch: Int = version and 0xFFF
val variant: Int = (version shr 29) and 0x7
}

View File

@ -0,0 +1,14 @@
package com.xyzshell.andinfo.libs.gpu.models
enum class VkPhysicalDeviceType(val value: Int) {
OTHER(0),
INTEGRATED_GPU(1),
DISCRETE_GPU(2),
VIRTUAL_GPU(3),
CPU(4),
;
companion object {
fun fromValue(value: Int) = values().firstOrNull { it.value == value }
}
}

View File

@ -0,0 +1,17 @@
package com.xyzshell.andinfo.libs.gpu.models
enum class VkVendorId(val id: Int) {
KHRONOS(0x10001),
VIV(0x10002),
VSI(0x10003),
KAZAN(0x10004),
CODEPLAY(0x10005),
MESA(0x10006),
POCL(0x10007),
MOBILEYE(0x10008),
;
companion object {
fun fromId(id: Int) = values().firstOrNull { it.id == id }
}
}

View File

@ -0,0 +1,62 @@
package com.xyzshell.andinfo.libs.gpu.utils
import android.opengl.EGL14
import android.opengl.GLES10
import android.opengl.GLES20
import android.opengl.GLES30
import android.opengl.GLES31
import android.opengl.GLES32
import android.os.Build
import com.xyzshell.andinfo.libs.gpu.models.EglInformation
import com.xyzshell.andinfo.libs.gpu.models.GlInformation
import java.lang.reflect.Field
object EglUtils {
fun getEglInformation(): EglInformation? {
val eglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY)
if (eglDisplay == EGL14.EGL_NO_DISPLAY) {
return null
}
val version = IntArray(2)
if (!EGL14.eglInitialize(eglDisplay, version, 0, version, 1)) {
return null
}
val eglVendor = EGL14.eglQueryString(eglDisplay, EGL14.EGL_VENDOR)
val eglVersion = EGL14.eglQueryString(eglDisplay, EGL14.EGL_VERSION)
val eglExtensions = EGL14.eglQueryString(eglDisplay, EGL14.EGL_EXTENSIONS)
?.split(" ")
?.filter { it.isNotBlank() }
val eglClientApi = EGL14.eglQueryString(eglDisplay, EGL14.EGL_CLIENT_APIS)
?.split(" ")
?.filter { it.isNotBlank() }
val glInformation = getGlInformation()
EGL14.eglTerminate(eglDisplay)
return EglInformation(
eglVendor,
eglVersion,
eglExtensions,
eglClientApi,
glInformation,
)
}
private fun getGlInformation(): GlInformation? {
val glVendor = GLES10.glGetString(GLES10.GL_VENDOR)
val glRenderer = GLES10.glGetString(GLES10.GL_RENDERER)
val glVersion = GLES10.glGetString(GLES10.GL_VERSION)
val glExtensions = GLES10.glGetString(GLES10.GL_EXTENSIONS)
return GlInformation(
glVendor,
glRenderer,
glVersion,
glExtensions,
)
}
}

View File

@ -0,0 +1,35 @@
/*
* SPDX-FileCopyrightText: Sebastiano Barezzi
* SPDX-License-Identifier: Apache-2.0
*/
package com.xyzshell.andinfo.libs.gpu.utils
import com.xyzshell.andinfo.libs.gpu.models.VkApiVersion
import com.xyzshell.andinfo.libs.gpu.models.VkPhysicalDevice
import com.xyzshell.andinfo.libs.gpu.models.VkVersion
object VkUtils {
class VkPhysicalDevices : ArrayList<VkPhysicalDevice>() {
fun addDevice(
apiVersion: Long,
driverVersion: Long,
vendorId: Int,
deviceId: Int,
deviceType: Int,
deviceName: String,
) = add(
VkPhysicalDevice(
apiVersion = VkVersion(apiVersion.toInt()),
driverVersion = driverVersion.toInt(),
vendorId = vendorId,
registeredVendorId = com.xyzshell.andinfo.libs.gpu.models.VkVendorId.fromId(vendorId),
deviceId = deviceId,
deviceType = com.xyzshell.andinfo.libs.gpu.models.VkPhysicalDeviceType.fromValue(deviceType) ?: com.xyzshell.andinfo.libs.gpu.models.VkPhysicalDeviceType.OTHER,
deviceName = deviceName,
)
)
}
external fun getVkInfo(): VkPhysicalDevices?
}

View File

@ -1,13 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS" />
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyAndriodInfo">
android:theme="@style/Theme.MyAndriodInfo"
tools:replace="android:name">
<activity
android:name=".MainActivity"
android:exported="true"

View File

@ -33,6 +33,37 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.xyzshell.myphoneinfo.ui.theme.MyAndriodInfoTheme
import com.xyzshell.andinfo.AndInfo
import android.text.format.Formatter
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import android.hardware.Sensor
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.ListItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.material3.SheetState
import androidx.compose.material3.rememberStandardBottomSheetState
import androidx.compose.material3.BottomSheetScaffold
import androidx.compose.material3.SheetValue
import androidx.compose.material3.rememberBottomSheetScaffoldState
import androidx.compose.material3.BottomSheetDefaults
import androidx.compose.material3.BottomSheetScaffoldState
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.rememberBottomSheetScaffoldState
import kotlinx.coroutines.launch
import androidx.compose.runtime.rememberCoroutineScope
import com.xyzshell.andinfo.libs.SensorInfo
import com.xyzshell.andinfo.libs.GpuInfo
import com.xyzshell.andinfo.libs.gpu.models.VkPhysicalDevice
import com.xyzshell.andinfo.libs.gpu.models.EglInformation
import androidx.compose.foundation.lazy.itemsIndexed
import android.os.Build
import com.xyzshell.andinfo.libs.InputInfo
import com.xyzshell.andinfo.libs.InputInfo.InputDeviceInfo
import androidx.compose.foundation.clickable
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
@ -55,7 +86,16 @@ class MainActivity : ComponentActivity() {
@Composable
fun MainView(name: String, modifier: Modifier = Modifier) {
val showDialog = remember { mutableStateOf(false) }
var showCpuDialog by remember { mutableStateOf(false) }
var showDeviceDialog by remember { mutableStateOf(false) }
var showDisplayDialog by remember { mutableStateOf(false) }
var showSensorsDialog by remember { mutableStateOf(false) }
var selectedSensor by remember { mutableStateOf<Sensor?>(null) }
var showBuildDialog by remember { mutableStateOf(false) }
var showGpuDialog by remember { mutableStateOf(false) }
var showInputDevicesDialog by remember { mutableStateOf(false) }
var selectedInputDevice by remember { mutableStateOf<InputDeviceInfo?>(null) }
Column (modifier){
Box(modifier = Modifier.fillMaxWidth()){
Text(text = name, Modifier.align(Alignment.Center))
@ -63,28 +103,414 @@ fun MainView(name: String, modifier: Modifier = Modifier) {
Card(modifier= Modifier.fillMaxWidth().padding(10.dp)){
Text("硬件:${AndInfo.instance.cpu.hardware()}")
Text("核心数:${AndInfo.instance.cpu.cores.size}")
Button(onClick = {showDialog.value = true}) { Text("cpu") }
Button(onClick = { showCpuDialog = true }) { Text("CPU 详情") }
}
Spacer(modifier = Modifier.height(16.dp))
Card(modifier= Modifier.fillMaxWidth().padding(10.dp)){
val memoryInfo = AndInfo.instance.device.getMemoryInfo()
Text("设备型号:${AndInfo.instance.device.model}")
Text("制造商:${AndInfo.instance.device.manufacturer}")
Text("总内存:${Formatter.formatFileSize(AndInfo.instance.context, memoryInfo.totalMem)}")
Text("可用内存:${Formatter.formatFileSize(AndInfo.instance.context, memoryInfo.availMem)}")
Button(onClick = { showDeviceDialog = true }) { Text("设备详情") }
}
Spacer(modifier = Modifier.height(16.dp))
Card(modifier= Modifier.fillMaxWidth().padding(10.dp)){
val defaultDisplayInfo = AndInfo.instance.display.getDefaultDisplayInfo()
if (defaultDisplayInfo != null) {
Text("显示器名称:${defaultDisplayInfo.name}")
Text("分辨率:${defaultDisplayInfo.widthPixels}x${defaultDisplayInfo.heightPixels}")
Text("刷新率:${defaultDisplayInfo.refreshRate} Hz")
Button(onClick = { showDisplayDialog = true }) { Text("显示器详情") }
} else {
Text("无法获取显示器信息")
}
}
if (showDialog.value) {
Spacer(modifier = Modifier.height(16.dp))
Card(modifier= Modifier.fillMaxWidth().padding(10.dp)){
val allSensors = AndInfo.instance.sensor.getAllSensors()
Text("传感器数量:${allSensors.size}")
Text("支持动态传感器发现:${AndInfo.instance.sensor.isDynamicSensorDiscoverySupported()}")
Button(onClick = { showSensorsDialog = true }) { Text("传感器列表") }
}
Spacer(modifier = Modifier.height(16.dp))
Card(modifier= Modifier.fillMaxWidth().padding(10.dp)){
Text("构建指纹:${AndInfo.instance.build.fingerprint}")
Text("构建类型:${AndInfo.instance.build.type}")
Text("Android 版本:${AndInfo.instance.build.versionRelease} (SDK ${AndInfo.instance.build.versionSdkInt})")
Button(onClick = { showBuildDialog = true }) { Text("构建详情") }
}
Spacer(modifier = Modifier.height(16.dp))
Card(modifier= Modifier.fillMaxWidth().padding(10.dp)){
val gpuInfo = AndInfo.instance.gpu.getGpuInformation()
Text("Vulkan 设备数量:${gpuInfo.vkPhysicalDevices?.size ?: 0}")
Text("EGL 信息可用:${gpuInfo.eglInformation != null}")
Button(onClick = { showGpuDialog = true }) { Text("GPU 详情") }
}
Spacer(modifier = Modifier.height(16.dp))
Card(modifier= Modifier.fillMaxWidth().padding(10.dp)){
val inputDevices = AndInfo.instance.input.getInputDevices()
Text("输入设备数量:${inputDevices.size}")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
Text("触摸最大遮蔽不透明度:${AndInfo.instance.input.getMaximumObscuringOpacityForTouch()}")
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
Text("手写笔指针图标启用:${AndInfo.instance.input.isStylusPointerIconEnabled()}")
}
Button(onClick = { showInputDevicesDialog = true }) { Text("输入设备列表") }
}
}
if (showCpuDialog) {
AlertDialog(
onDismissRequest = { showDialog.value = false },
title = { Text(text = "标题") },
onDismissRequest = { showCpuDialog = false },
title = { Text(text = "CPU 详情") },
text = { Text(text = AndInfo.instance.cpu.text()) },
confirmButton = {
TextButton(onClick = { showDialog.value = false }) {
TextButton(onClick = { showCpuDialog = false }) {
Text("确认")
}
},
dismissButton = {
TextButton(onClick = { showDialog.value = false }) {
TextButton(onClick = { showCpuDialog = false }) {
Text("取消")
}
}
)
}
}
if (showDeviceDialog) {
val memoryInfo = AndInfo.instance.device.getMemoryInfo()
AlertDialog(
onDismissRequest = { showDeviceDialog = false },
title = { Text(text = "设备详情") },
text = {
Column {
Text("设备:${AndInfo.instance.device.device}")
Text("品牌:${AndInfo.instance.device.brand}")
Text("型号:${AndInfo.instance.device.model}")
Text("制造商:${AndInfo.instance.device.manufacturer}")
Text("产品名称:${AndInfo.instance.device.productName}")
Text("硬件名称:${AndInfo.instance.device.hardwareName}")
Text("主板名称:${AndInfo.instance.device.boardName}")
AndInfo.instance.device.hardwareSku?.let { Text("硬件 SKU$it") }
AndInfo.instance.device.odmSku?.let { Text("ODM SKU$it") }
AndInfo.instance.device.socManufacturer?.let { Text("SoC 制造商:$it") }
AndInfo.instance.device.socModel?.let { Text("SoC 型号:$it") }
Text("总内存:${Formatter.formatFileSize(AndInfo.instance.context, memoryInfo.totalMem)}")
Text("可用内存:${Formatter.formatFileSize(AndInfo.instance.context, memoryInfo.availMem)}")
Text("低内存阈值:${Formatter.formatFileSize(AndInfo.instance.context, memoryInfo.threshold)}")
Text("当前是否低内存:${memoryInfo.lowMemory}")
}
},
confirmButton = {
TextButton(onClick = { showDeviceDialog = false }) {
Text("确认")
}
},
dismissButton = {
TextButton(onClick = { showDeviceDialog = false }) {
Text("取消")
}
}
)
}
if (showDisplayDialog) {
val defaultDisplayInfo = AndInfo.instance.display.getDefaultDisplayInfo()
if (defaultDisplayInfo != null) {
AlertDialog(
onDismissRequest = { showDisplayDialog = false },
title = { Text(text = "显示器详情") },
text = {
Column {
Text("ID${defaultDisplayInfo.id}")
Text("名称:${defaultDisplayInfo.name}")
Text("宽度 (像素)${defaultDisplayInfo.widthPixels}")
Text("高度 (像素)${defaultDisplayInfo.heightPixels}")
Text("密度 (DPI)${defaultDisplayInfo.densityDpi}")
Text("X DPI${defaultDisplayInfo.xdpi}")
Text("Y DPI${defaultDisplayInfo.ydpi}")
Text("刷新率:${defaultDisplayInfo.refreshRate} Hz")
Text("是否支持 HDR${defaultDisplayInfo.isHdr}")
Text("是否支持广色域:${defaultDisplayInfo.isWideColorGamut}")
}
},
confirmButton = {
TextButton(onClick = { showDisplayDialog = false }) {
Text("确认")
}
},
dismissButton = {
TextButton(onClick = { showDisplayDialog = false }) {
Text("取消")
}
}
)
} else {
AlertDialog(
onDismissRequest = { showDisplayDialog = false },
title = { Text(text = "显示器详情") },
text = { Text(text = "无法获取显示器信息") },
confirmButton = {
TextButton(onClick = { showDisplayDialog = false }) {
Text("确认")
}
}
)
}
}
if (showSensorsDialog) {
val allSensors = AndInfo.instance.sensor.getAllSensors()
AlertDialog(
onDismissRequest = { showSensorsDialog = false },
title = { Text(text = "传感器列表") },
text = {
LazyColumn {
items(allSensors) { sensor ->
ListItem(
headlineContent = { Text(sensor.name) },
supportingContent = { Text(sensor.stringType) },
trailingContent = { Text(sensor.vendor) },
modifier = Modifier.fillMaxWidth()
.clickable {
selectedSensor = sensor
showSensorsDialog = false
}
)
}
}
},
confirmButton = {
TextButton(onClick = { showSensorsDialog = false }) {
Text("确认")
}
}
)
}
selectedSensor?.let { sensor ->
val sensorDetail = AndInfo.instance.sensor.getSensorDetail(sensor)
AlertDialog(
onDismissRequest = { selectedSensor = null },
title = { Text(text = sensorDetail.name) },
text = {
Column {
Text("名称:${sensorDetail.name}")
sensorDetail.id?.let { Text("ID$it") }
Text("字符串类型:${sensorDetail.stringType}")
Text("类型:${sensorDetail.type}")
Text("供应商:${sensorDetail.vendor}")
Text("版本:${sensorDetail.version}")
Text("是否动态传感器:${sensorDetail.isDynamicSensor}")
Text("是否唤醒传感器:${sensorDetail.isWakeUpSensor}")
Text("FIFO 最大事件数:${sensorDetail.fifoMaxEventCount}")
Text("FIFO 预留事件数:${sensorDetail.fifoReservedEventCount}")
Text("最小延迟:${sensorDetail.minDelay}")
Text("最大延迟:${sensorDetail.maxDelay}")
Text("最大量程:${sensorDetail.maximumRange}")
Text("功耗:${sensorDetail.power}")
Text("报告模式:${SensorInfo.sensorReportingModeToStringResId[sensorDetail.reportingMode] ?: sensorDetail.reportingMode.toString()}")
Text("分辨率:${sensorDetail.resolution}")
Text("是否支持附加信息:${sensorDetail.isAdditionalInfoSupported}")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Text("最高直接报告速率级别:${SensorInfo.sensorDirectReportModeRatesToStringResId[sensorDetail.highestDirectReportRateLevel] ?: sensorDetail.highestDirectReportRateLevel.toString()}")
}
}
},
confirmButton = {
TextButton(onClick = { selectedSensor = null }) {
Text("确认")
}
}
)
}
if (showBuildDialog) {
val buildInfo = AndInfo.instance.build
AlertDialog(
onDismissRequest = { showBuildDialog = false },
title = { Text(text = "构建详情") },
text = {
LazyColumn {
item { Text("指纹:${buildInfo.fingerprint}") }
item { Text("标签:${buildInfo.tags}") }
item { Text("类型:${buildInfo.type}") }
item { Text("构建日期:${buildInfo.buildDate}") }
item { Text("主机:${buildInfo.host}") }
item { Text("用户:${buildInfo.user}") }
item { Text("ID${buildInfo.id}") }
item { Text("显示:${buildInfo.display}") }
item { Text("版本发布:${buildInfo.versionRelease}") }
item { Text("版本代号:${buildInfo.versionCodename}") }
item { Text("SDK 版本:${buildInfo.versionSdkInt}") }
item { Text("预览 SDK 版本:${buildInfo.versionPreviewSdkInt}") }
item { Text("安全补丁:${buildInfo.securityPatch}") }
item { Text("基础操作系统:${buildInfo.baseOs}") }
item { Text("增量:${buildInfo.incremental}") }
buildInfo.releaseOrCodename?.let { item { Text("发布或代号:$it") } }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
item { Text("媒体性能类:${buildInfo.mediaPerformanceClass}") }
}
buildInfo.releaseOrPreviewDisplay?.let { item { Text("发布或预览显示:$it") } }
item { Spacer(modifier = Modifier.height(8.dp)) }
item { Text("JVM 名称:${buildInfo.jvmName}") }
item { Text("JVM 供应商:${buildInfo.jvmVendor}") }
item { Text("JVM 版本:${buildInfo.jvmVersion}") }
item { Text("JVM 类版本:${buildInfo.jvmClassVersion}") }
item { Text("JVM 规范名称:${buildInfo.jvmSpecificationName}") }
item { Text("JVM 规范供应商:${buildInfo.jvmSpecificationVendor}") }
item { Text("JVM 规范版本:${buildInfo.jvmSpecificationVersion}") }
item { Spacer(modifier = Modifier.height(8.dp)) }
buildInfo.vendorSecurityPatchLevel?.let { item { Text("供应商安全补丁级别:$it") } }
buildInfo.kernelVersion?.let { item { Text("内核版本:$it") } }
buildInfo.kernelCompleteVersion?.let { item { Text("内核完整版本:$it") } }
item { Spacer(modifier = Modifier.height(8.dp)) }
item { Text("引导加载程序版本:${buildInfo.bootloaderVersion}") }
buildInfo.radioVersion?.let { item { Text("无线电版本:$it") } }
if (buildInfo.fingerprintedPartitions.isNotEmpty()) {
item { Spacer(modifier = Modifier.height(8.dp)) }
item { Text("指纹分区:") }
items(buildInfo.fingerprintedPartitions) { partition ->
Text(" ${partition.name}: ${partition.fingerprint}")
}
}
}
},
confirmButton = {
TextButton(onClick = { showBuildDialog = false }) {
Text("确认")
}
}
)
}
if (showGpuDialog) {
val gpuInfo = AndInfo.instance.gpu.getGpuInformation()
AlertDialog(
onDismissRequest = { showGpuDialog = false },
title = { Text(text = "GPU 详情") },
text = {
LazyColumn {
gpuInfo.vkPhysicalDevices?.let { devices ->
if (devices.isNotEmpty()) {
item { Text("Vulkan 物理设备:") }
itemsIndexed(devices) { index, vkPhysicalDevice ->
Column(modifier = Modifier.padding(start = 16.dp)) {
Text("设备 ${index + 1}:")
Text(" 名称: ${vkPhysicalDevice.deviceName}")
Text(" API 版本: ${vkPhysicalDevice.apiVersion.major}.${vkPhysicalDevice.apiVersion.minor}.${vkPhysicalDevice.apiVersion.patch}")
Text(" 驱动版本: ${vkPhysicalDevice.driverVersion}")
Text(" 供应商 ID: ${vkPhysicalDevice.vendorId}")
vkPhysicalDevice.registeredVendorId?.let {
Text(" 注册供应商 ID: ${GpuInfo.vkVendorIdToString[it] ?: it.toString()}")
}
Text(" 设备 ID: ${vkPhysicalDevice.deviceId}")
Text(" 设备类型: ${GpuInfo.vkPhysicalDeviceTypeToString[vkPhysicalDevice.deviceType.value] ?: vkPhysicalDevice.deviceType.toString()}")
}
}
} else {
item { Text("无 Vulkan 物理设备信息") }
}
} ?: run {
item { Text("无 Vulkan 物理设备信息") }
}
gpuInfo.eglInformation?.let { eglInfo ->
item { Spacer(modifier = Modifier.height(8.dp)) }
item { Text("EGL 信息:") }
eglInfo.eglVendor?.let { item { Text(" 供应商: $it") } }
eglInfo.eglVersion?.let { item { Text(" 版本: $it") } }
eglInfo.eglExtensions?.let {
item { Text(" 扩展: ${it.joinToString()}") }
}
eglInfo.eglClientApi?.let {
item { Text(" 客户端 API: ${it.joinToString()}") }
}
eglInfo.glInformation?.let { glInfo ->
item { Spacer(modifier = Modifier.height(8.dp)) }
item { Text("OpenGL ES 信息:") }
glInfo.glVendor?.let { item { Text(" 供应商: $it") } }
glInfo.glRenderer?.let { item { Text(" 渲染器: $it") } }
glInfo.glVersion?.let { item { Text(" 版本: $it") } }
glInfo.glExtensions?.let { item { Text(" 扩展: $it") } }
}
} ?: run {
item { Spacer(modifier = Modifier.height(8.dp)) }
item { Text("无 EGL 信息") }
}
}
},
confirmButton = {
TextButton(onClick = { showGpuDialog = false }) {
Text("确认")
}
}
)
}
if (showInputDevicesDialog) {
val inputDevices = AndInfo.instance.input.getInputDevices()
AlertDialog(
onDismissRequest = { showInputDevicesDialog = false },
title = { Text(text = "输入设备列表") },
text = {
LazyColumn {
items(inputDevices) { inputDevice ->
ListItem(
headlineContent = { Text(inputDevice.name) },
supportingContent = { Text("ID: ${inputDevice.id}, 供应商: ${inputDevice.vendorId}, 产品: ${inputDevice.productId}") },
modifier = Modifier.fillMaxWidth()
.clickable {
selectedInputDevice = inputDevice
showInputDevicesDialog = false
}
)
}
}
},
confirmButton = {
TextButton(onClick = { showInputDevicesDialog = false }) {
Text("确认")
}
}
)
}
selectedInputDevice?.let { inputDevice ->
AlertDialog(
onDismissRequest = { selectedInputDevice = null },
title = { Text(text = inputDevice.name) },
text = {
LazyColumn {
item { Text("ID: ${inputDevice.id}") }
item { Text("控制器编号: ${inputDevice.controllerNumber}") }
item { Text("供应商 ID: ${inputDevice.vendorId}") }
item { Text("产品 ID: ${inputDevice.productId}") }
inputDevice.descriptor?.let { item { Text("描述符: $it") } }
item { Text("是否虚拟: ${inputDevice.isVirtual}") }
item { Text("是否外部: ${inputDevice.isExternal}") }
item { Text("名称: ${inputDevice.name}") }
item { Text("源类: ${InputInfo.InputDeviceInfo.sourceClassToString.filter { (key, _) -> (inputDevice.sources and key) == key }.values.joinToString()}") }
item { Text("源: ${InputInfo.InputDeviceInfo.sourceToString.filter { (key, _) -> (inputDevice.sources and key) == key }.values.joinToString()}") }
item { Text("键盘类型: ${InputInfo.InputDeviceInfo.keyboardTypeToString[inputDevice.keyboardType] ?: inputDevice.keyboardType.toString()}") }
item { Text("KeyCharacterMap 键盘类型: ${InputInfo.InputDeviceInfo.keyCharacterMapKeyboardTypeToString[inputDevice.keyCharacterMapKeyboardType] ?: inputDevice.keyCharacterMapKeyboardType.toString()}") }
item { Text("运动范围数量: ${inputDevice.motionRangesCount}") }
item { Text("有振动器: ${inputDevice.hasVibrator}") }
item { Text("已启用: ${inputDevice.isEnabled}") }
item { Text("有麦克风: ${inputDevice.hasMicrophone}") }
}
},
confirmButton = {
TextButton(onClick = { selectedInputDevice = null }) {
Text("确认")
}
}
)
}
}
@Preview(showBackground = true)

View File

@ -0,0 +1,11 @@
package com.xyzshell.myphoneinfo
import android.app.Application
import com.xyzshell.andinfo.AndInfo
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
AndInfo.init(this)
}
}