Merge "Fix loop in SF flushTransactionQueues" into qt-dev
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 5836f11..7ac0eb7 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -62,7 +62,7 @@
using std::string;
-#define MAX_SYS_FILES 10
+#define MAX_SYS_FILES 11
const char* k_traceTagsProperty = "debug.atrace.tags.enableflags";
const char* k_userInitiatedTraceProperty = "debug.atrace.user_initiated";
@@ -133,7 +133,11 @@
{ OPT, "events/sched/sched_blocked_reason/enable" },
{ OPT, "events/sched/sched_cpu_hotplug/enable" },
{ OPT, "events/sched/sched_pi_setprio/enable" },
+ { OPT, "events/sched/sched_process_exit/enable" },
{ OPT, "events/cgroup/enable" },
+ { OPT, "events/oom/oom_score_adj_update/enable" },
+ { OPT, "events/task/task_rename/enable" },
+ { OPT, "events/task/task_newtask/enable" },
} },
{ "irq", "IRQ Events", 0, {
{ REQ, "events/irq/enable" },
@@ -231,10 +235,6 @@
{ OPT, "events/kmem/rss_stat/enable" },
{ OPT, "events/kmem/ion_heap_grow/enable" },
{ OPT, "events/kmem/ion_heap_shrink/enable" },
- { OPT, "events/oom/oom_score_adj_update/enable" },
- { OPT, "events/sched/sched_process_exit/enable" },
- { OPT, "events/task/task_rename/enable" },
- { OPT, "events/task/task_newtask/enable" },
} },
};
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index 7c58a85..032d072 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -33,6 +33,8 @@
chmod 0666 /sys/kernel/tracing/events/sched/sched_cpu_hotplug/enable
chmod 0666 /sys/kernel/debug/tracing/events/sched/sched_pi_setprio/enable
chmod 0666 /sys/kernel/tracing/events/sched/sched_pi_setprio/enable
+ chmod 0666 /sys/kernel/debug/tracing/events/sched/sched_process_exit/enable
+ chmod 0666 /sys/kernel/tracing/events/sched/sched_process_exit/enable
chmod 0666 /sys/kernel/debug/tracing/events/sched/sched_waking/enable
chmod 0666 /sys/kernel/tracing/events/sched/sched_waking/enable
chmod 0666 /sys/kernel/debug/tracing/events/cgroup/enable
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index c730ab9..1384285 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -569,35 +569,6 @@
remove_path_xattr(path, kXattrInodeCodeCache);
}
}
-
- auto extPath = findDataMediaPath(uuid, userId);
- if (flags & FLAG_CLEAR_CACHE_ONLY) {
- // Clear only cached data from shared storage
- path = StringPrintf("%s/Android/data/%s/cache", extPath.c_str(), pkgname);
- if (delete_dir_contents(path, true) != 0) {
- res = error("Failed to delete contents of " + path);
- }
- } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
- // No code cache on shared storage
- } else {
- // Clear everything on shared storage
- path = StringPrintf("%s/Android/sandbox/%s", extPath.c_str(), pkgname);
- if (delete_dir_contents(path, true) != 0) {
- res = error("Failed to delete contents of " + path);
- }
- path = StringPrintf("%s/Android/data/%s", extPath.c_str(), pkgname);
- if (delete_dir_contents(path, true) != 0) {
- res = error("Failed to delete contents of " + path);
- }
- path = StringPrintf("%s/Android/media/%s", extPath.c_str(), pkgname);
- if (delete_dir_contents(path, true) != 0) {
- res = error("Failed to delete contents of " + path);
- }
- path = StringPrintf("%s/Android/obb/%s", extPath.c_str(), pkgname);
- if (delete_dir_contents(path, true) != 0) {
- res = error("Failed to delete contents of " + path);
- }
- }
}
if (flags & FLAG_STORAGE_DE) {
std::string suffix = "";
@@ -617,6 +588,41 @@
}
}
}
+ if (flags & FLAG_STORAGE_EXTERNAL) {
+ std::lock_guard<std::recursive_mutex> lock(mMountsLock);
+ for (const auto& n : mStorageMounts) {
+ auto extPath = n.second;
+ if (n.first.compare(0, 14, "/mnt/media_rw/") != 0) {
+ extPath += StringPrintf("/%d", userId);
+ } else if (userId != 0) {
+ // TODO: support devices mounted under secondary users
+ continue;
+ }
+ if (flags & FLAG_CLEAR_CACHE_ONLY) {
+ // Clear only cached data from shared storage
+ auto path = StringPrintf("%s/Android/data/%s/cache", extPath.c_str(), pkgname);
+ if (delete_dir_contents(path, true) != 0) {
+ res = error("Failed to delete contents of " + path);
+ }
+ } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
+ // No code cache on shared storage
+ } else {
+ // Clear everything on shared storage
+ auto path = StringPrintf("%s/Android/data/%s", extPath.c_str(), pkgname);
+ if (delete_dir_contents(path, true) != 0) {
+ res = error("Failed to delete contents of " + path);
+ }
+ path = StringPrintf("%s/Android/media/%s", extPath.c_str(), pkgname);
+ if (delete_dir_contents(path, true) != 0) {
+ res = error("Failed to delete contents of " + path);
+ }
+ path = StringPrintf("%s/Android/obb/%s", extPath.c_str(), pkgname);
+ if (delete_dir_contents(path, true) != 0) {
+ res = error("Failed to delete contents of " + path);
+ }
+ }
+ }
+ }
return res;
}
@@ -666,24 +672,6 @@
if (delete_dir_contents_and_dir(path) != 0) {
res = error("Failed to delete " + path);
}
-
- auto extPath = findDataMediaPath(uuid, userId);
- path = StringPrintf("%s/Android/sandbox/%s", extPath.c_str(), pkgname);
- if (delete_dir_contents_and_dir(path, true) != 0) {
- res = error("Failed to delete " + path);
- }
- path = StringPrintf("%s/Android/data/%s", extPath.c_str(), pkgname);
- if (delete_dir_contents_and_dir(path, true) != 0) {
- res = error("Failed to delete " + path);
- }
- path = StringPrintf("%s/Android/media/%s", extPath.c_str(), pkgname);
- if (delete_dir_contents_and_dir(path, true) != 0) {
- res = error("Failed to delete " + path);
- }
- path = StringPrintf("%s/Android/obb/%s", extPath.c_str(), pkgname);
- if (delete_dir_contents_and_dir(path, true) != 0) {
- res = error("Failed to delete " + path);
- }
}
if (flags & FLAG_STORAGE_DE) {
auto path = create_data_user_de_package_path(uuid_, userId, pkgname);
@@ -696,6 +684,30 @@
// Verify if it's ok to do that.
destroy_app_reference_profile(packageName);
}
+ if (flags & FLAG_STORAGE_EXTERNAL) {
+ std::lock_guard<std::recursive_mutex> lock(mMountsLock);
+ for (const auto& n : mStorageMounts) {
+ auto extPath = n.second;
+ if (n.first.compare(0, 14, "/mnt/media_rw/") != 0) {
+ extPath += StringPrintf("/%d", userId);
+ } else if (userId != 0) {
+ // TODO: support devices mounted under secondary users
+ continue;
+ }
+ auto path = StringPrintf("%s/Android/data/%s", extPath.c_str(), pkgname);
+ if (delete_dir_contents_and_dir(path, true) != 0) {
+ res = error("Failed to delete contents of " + path);
+ }
+ path = StringPrintf("%s/Android/media/%s", extPath.c_str(), pkgname);
+ if (delete_dir_contents_and_dir(path, true) != 0) {
+ res = error("Failed to delete contents of " + path);
+ }
+ path = StringPrintf("%s/Android/obb/%s", extPath.c_str(), pkgname);
+ if (delete_dir_contents_and_dir(path, true) != 0) {
+ res = error("Failed to delete contents of " + path);
+ }
+ }
+ }
return res;
}
@@ -1694,8 +1706,6 @@
}
ATRACE_BEGIN("external");
- auto sandboxPath = create_data_media_package_path(uuid_, userId, "sandbox", pkgname);
- calculate_tree_size(sandboxPath, &extStats.dataSize);
auto extPath = create_data_media_package_path(uuid_, userId, "data", pkgname);
collectManualStats(extPath, &extStats);
auto mediaPath = create_data_media_package_path(uuid_, userId, "media", pkgname);
diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl
index 63c9765..4610a66 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -114,6 +114,7 @@
const int FLAG_STORAGE_DE = 0x1;
const int FLAG_STORAGE_CE = 0x2;
+ const int FLAG_STORAGE_EXTERNAL = 0x4;
const int FLAG_CLEAR_CACHE_ONLY = 0x10;
const int FLAG_CLEAR_CODE_CACHE_ONLY = 0x20;
diff --git a/headers/media_plugin/media/drm/DrmAPI.h b/headers/media_plugin/media/drm/DrmAPI.h
index 59bd292..17b9993 100644
--- a/headers/media_plugin/media/drm/DrmAPI.h
+++ b/headers/media_plugin/media/drm/DrmAPI.h
@@ -115,7 +115,8 @@
kKeyStatusType_Expired,
kKeyStatusType_OutputNotAllowed,
kKeyStatusType_StatusPending,
- kKeyStatusType_InternalError
+ kKeyStatusType_InternalError,
+ kKeyStatusType_UsableInFuture
};
// Used by sendKeysChange to report the usability status of each
diff --git a/include/audiomanager/IAudioManager.h b/include/audiomanager/IAudioManager.h
index d0642c6..2f5ccb8 100644
--- a/include/audiomanager/IAudioManager.h
+++ b/include/audiomanager/IAudioManager.h
@@ -38,6 +38,7 @@
RELEASE_PLAYER = IBinder::FIRST_CALL_TRANSACTION + 3,
TRACK_RECORDER = IBinder::FIRST_CALL_TRANSACTION + 4,
RECORDER_EVENT = IBinder::FIRST_CALL_TRANSACTION + 5,
+ RELEASE_RECORDER = IBinder::FIRST_CALL_TRANSACTION + 6,
};
DECLARE_META_INTERFACE(AudioManager)
@@ -52,6 +53,7 @@
/*oneway*/ virtual status_t releasePlayer(audio_unique_id_t piid) = 0;
virtual audio_unique_id_t trackRecorder(const sp<IBinder>& recorder) = 0;
/*oneway*/ virtual status_t recorderEvent(audio_unique_id_t riid, recorder_state_t event) = 0;
+ /*oneway*/ virtual status_t releaseRecorder(audio_unique_id_t riid) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/libs/graphicsenv/GpuStatsInfo.cpp b/libs/graphicsenv/GpuStatsInfo.cpp
index cbf6e50..4a801be 100644
--- a/libs/graphicsenv/GpuStatsInfo.cpp
+++ b/libs/graphicsenv/GpuStatsInfo.cpp
@@ -35,6 +35,10 @@
if ((status = parcel->writeInt32(vkLoadingCount)) != OK) return status;
if ((status = parcel->writeInt32(vkLoadingFailureCount)) != OK) return status;
if ((status = parcel->writeInt32(vulkanVersion)) != OK) return status;
+ if ((status = parcel->writeInt32(cpuVulkanVersion)) != OK) return status;
+ if ((status = parcel->writeInt32(glesVersion)) != OK) return status;
+ if ((status = parcel->writeInt32(angleLoadingCount)) != OK) return status;
+ if ((status = parcel->writeInt32(angleLoadingFailureCount)) != OK) return status;
return OK;
}
@@ -49,6 +53,10 @@
if ((status = parcel->readInt32(&vkLoadingCount)) != OK) return status;
if ((status = parcel->readInt32(&vkLoadingFailureCount)) != OK) return status;
if ((status = parcel->readInt32(&vulkanVersion)) != OK) return status;
+ if ((status = parcel->readInt32(&cpuVulkanVersion)) != OK) return status;
+ if ((status = parcel->readInt32(&glesVersion)) != OK) return status;
+ if ((status = parcel->readInt32(&angleLoadingCount)) != OK) return status;
+ if ((status = parcel->readInt32(&angleLoadingFailureCount)) != OK) return status;
return OK;
}
@@ -60,9 +68,13 @@
StringAppendF(&result, "driverBuildTime = %" PRId64 "\n", driverBuildTime);
StringAppendF(&result, "glLoadingCount = %d\n", glLoadingCount);
StringAppendF(&result, "glLoadingFailureCount = %d\n", glLoadingFailureCount);
+ StringAppendF(&result, "angleLoadingCount = %d\n", angleLoadingCount);
+ StringAppendF(&result, "angleLoadingFailureCount = %d\n", angleLoadingFailureCount);
StringAppendF(&result, "vkLoadingCount = %d\n", vkLoadingCount);
StringAppendF(&result, "vkLoadingFailureCount = %d\n", vkLoadingFailureCount);
StringAppendF(&result, "vulkanVersion = %d\n", vulkanVersion);
+ StringAppendF(&result, "cpuVulkanVersion = %d\n", cpuVulkanVersion);
+ StringAppendF(&result, "glesVersion = %d\n", glesVersion);
return result;
}
@@ -72,6 +84,8 @@
if ((status = parcel->writeUint64(driverVersionCode)) != OK) return status;
if ((status = parcel->writeInt64Vector(glDriverLoadingTime)) != OK) return status;
if ((status = parcel->writeInt64Vector(vkDriverLoadingTime)) != OK) return status;
+ if ((status = parcel->writeInt64Vector(angleDriverLoadingTime)) != OK) return status;
+ if ((status = parcel->writeBool(cpuVulkanInUse)) != OK) return status;
return OK;
}
@@ -81,6 +95,8 @@
if ((status = parcel->readUint64(&driverVersionCode)) != OK) return status;
if ((status = parcel->readInt64Vector(&glDriverLoadingTime)) != OK) return status;
if ((status = parcel->readInt64Vector(&vkDriverLoadingTime)) != OK) return status;
+ if ((status = parcel->readInt64Vector(&angleDriverLoadingTime)) != OK) return status;
+ if ((status = parcel->readBool(&cpuVulkanInUse)) != OK) return status;
return OK;
}
@@ -88,11 +104,17 @@
std::string result;
StringAppendF(&result, "appPackageName = %s\n", appPackageName.c_str());
StringAppendF(&result, "driverVersionCode = %" PRIu64 "\n", driverVersionCode);
+ StringAppendF(&result, "cpuVulkanInUse = %d\n", cpuVulkanInUse);
result.append("glDriverLoadingTime:");
for (int32_t loadingTime : glDriverLoadingTime) {
StringAppendF(&result, " %d", loadingTime);
}
result.append("\n");
+ result.append("angleDriverLoadingTime:");
+ for (int32_t loadingTime : angleDriverLoadingTime) {
+ StringAppendF(&result, " %d", loadingTime);
+ }
+ result.append("\n");
result.append("vkDriverLoadingTime:");
for (int32_t loadingTime : vkDriverLoadingTime) {
StringAppendF(&result, " %d", loadingTime);
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index 8728f03..407f77d 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -160,6 +160,22 @@
mSphalLibraries = sphalLibraries;
}
+void GraphicsEnv::hintActivityLaunch() {
+ ATRACE_CALL();
+
+ // If there's already graphics driver preloaded in the process, just send
+ // the stats info to GpuStats directly through async binder.
+ std::lock_guard<std::mutex> lock(mStatsLock);
+ if (mGpuStats.glDriverToSend) {
+ mGpuStats.glDriverToSend = false;
+ sendGpuStatsLocked(GraphicsEnv::Api::API_GL, true, mGpuStats.glDriverLoadingTime);
+ }
+ if (mGpuStats.vkDriverToSend) {
+ mGpuStats.vkDriverToSend = false;
+ sendGpuStatsLocked(GraphicsEnv::Api::API_VK, true, mGpuStats.vkDriverLoadingTime);
+ }
+}
+
void GraphicsEnv::setGpuStats(const std::string& driverPackageName,
const std::string& driverVersionName, uint64_t driverVersionCode,
int64_t driverBuildTime, const std::string& appPackageName,
@@ -220,34 +236,21 @@
}
}
-void GraphicsEnv::setDriverLoaded(GraphicsEnv::Api api, bool isLoaded, int64_t driverLoadingTime) {
+void GraphicsEnv::setDriverLoaded(GraphicsEnv::Api api, bool isDriverLoaded,
+ int64_t driverLoadingTime) {
ATRACE_CALL();
std::lock_guard<std::mutex> lock(mStatsLock);
- GraphicsEnv::Driver driver = GraphicsEnv::Driver::NONE;
- bool isIntendedDriverLoaded = false;
+ const bool doNotSend = mGpuStats.appPackageName.empty();
if (api == GraphicsEnv::Api::API_GL) {
- driver = mGpuStats.glDriverToLoad;
- isIntendedDriverLoaded = isLoaded &&
- ((mGpuStats.glDriverFallback == GraphicsEnv::Driver::NONE) ||
- (mGpuStats.glDriverToLoad == mGpuStats.glDriverFallback));
+ if (doNotSend) mGpuStats.glDriverToSend = true;
+ mGpuStats.glDriverLoadingTime = driverLoadingTime;
} else {
- driver = mGpuStats.vkDriverToLoad;
- isIntendedDriverLoaded =
- isLoaded && (mGpuStats.vkDriverFallback == GraphicsEnv::Driver::NONE);
+ if (doNotSend) mGpuStats.vkDriverToSend = true;
+ mGpuStats.vkDriverLoadingTime = driverLoadingTime;
}
- sendGpuStatsLocked(driver, isIntendedDriverLoaded, driverLoadingTime);
-}
-
-void GraphicsEnv::clearDriverLoadingInfo(GraphicsEnv::Api api) {
- ATRACE_CALL();
-
- std::lock_guard<std::mutex> lock(mStatsLock);
- if (api == GraphicsEnv::Api::API_GL) {
- mGpuStats.glDriverToLoad = GraphicsEnv::Driver::NONE;
- mGpuStats.glDriverFallback = GraphicsEnv::Driver::NONE;
- }
+ sendGpuStatsLocked(api, isDriverLoaded, driverLoadingTime);
}
static sp<IGpuService> getGpuService() {
@@ -260,7 +263,18 @@
return interface_cast<IGpuService>(binder);
}
-void GraphicsEnv::sendGpuStatsLocked(GraphicsEnv::Driver driver, bool isDriverLoaded,
+void GraphicsEnv::setCpuVulkanInUse() {
+ ATRACE_CALL();
+
+ // Use the same stats lock to protect getGpuService() as well.
+ std::lock_guard<std::mutex> lock(mStatsLock);
+ const sp<IGpuService> gpuService = getGpuService();
+ if (gpuService) {
+ gpuService->setCpuVulkanInUse(mGpuStats.appPackageName, mGpuStats.driverVersionCode);
+ }
+}
+
+void GraphicsEnv::sendGpuStatsLocked(GraphicsEnv::Api api, bool isDriverLoaded,
int64_t driverLoadingTime) {
ATRACE_CALL();
@@ -274,19 +288,31 @@
"\tdriverBuildTime[%" PRId64 "]\n"
"\tappPackageName[%s]\n"
"\tvulkanVersion[%d]\n"
- "\tdriver[%d]\n"
+ "\tapi[%d]\n"
"\tisDriverLoaded[%d]\n"
"\tdriverLoadingTime[%" PRId64 "]",
mGpuStats.driverPackageName.c_str(), mGpuStats.driverVersionName.c_str(),
mGpuStats.driverVersionCode, mGpuStats.driverBuildTime, mGpuStats.appPackageName.c_str(),
- mGpuStats.vulkanVersion, static_cast<int32_t>(driver), isDriverLoaded, driverLoadingTime);
+ mGpuStats.vulkanVersion, static_cast<int32_t>(api), isDriverLoaded, driverLoadingTime);
+
+ GraphicsEnv::Driver driver = GraphicsEnv::Driver::NONE;
+ bool isIntendedDriverLoaded = false;
+ if (api == GraphicsEnv::Api::API_GL) {
+ driver = mGpuStats.glDriverToLoad;
+ isIntendedDriverLoaded =
+ isDriverLoaded && (mGpuStats.glDriverFallback == GraphicsEnv::Driver::NONE);
+ } else {
+ driver = mGpuStats.vkDriverToLoad;
+ isIntendedDriverLoaded =
+ isDriverLoaded && (mGpuStats.vkDriverFallback == GraphicsEnv::Driver::NONE);
+ }
const sp<IGpuService> gpuService = getGpuService();
if (gpuService) {
gpuService->setGpuStats(mGpuStats.driverPackageName, mGpuStats.driverVersionName,
mGpuStats.driverVersionCode, mGpuStats.driverBuildTime,
mGpuStats.appPackageName, mGpuStats.vulkanVersion, driver,
- isDriverLoaded, driverLoadingTime);
+ isIntendedDriverLoaded, driverLoadingTime);
}
}
diff --git a/libs/graphicsenv/IGpuService.cpp b/libs/graphicsenv/IGpuService.cpp
index 100dca5..5f96249 100644
--- a/libs/graphicsenv/IGpuService.cpp
+++ b/libs/graphicsenv/IGpuService.cpp
@@ -91,6 +91,17 @@
outStats->clear();
return reply.readParcelableVector(outStats);
}
+
+ virtual void setCpuVulkanInUse(const std::string& appPackageName,
+ const uint64_t driverVersionCode) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IGpuService::getInterfaceDescriptor());
+
+ data.writeUtf8AsUtf16(appPackageName);
+ data.writeUint64(driverVersionCode);
+
+ remote()->transact(BnGpuService::SET_CPU_VULKAN_IN_USE, data, &reply, IBinder::FLAG_ONEWAY);
+ }
};
IMPLEMENT_META_INTERFACE(GpuService, "android.graphicsenv.IGpuService");
@@ -163,6 +174,19 @@
return OK;
}
+ case SET_CPU_VULKAN_IN_USE: {
+ CHECK_INTERFACE(IGpuService, data, reply);
+
+ std::string appPackageName;
+ if ((status = data.readUtf8FromUtf16(&appPackageName)) != OK) return status;
+
+ uint64_t driverVersionCode;
+ if ((status = data.readUint64(&driverVersionCode)) != OK) return status;
+
+ setCpuVulkanInUse(appPackageName, driverVersionCode);
+
+ return OK;
+ }
case SHELL_COMMAND_TRANSACTION: {
int in = data.readFileDescriptor();
int out = data.readFileDescriptor();
diff --git a/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h b/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h
index e96c932..edcccfe 100644
--- a/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h
+++ b/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h
@@ -45,6 +45,10 @@
int32_t vkLoadingCount = 0;
int32_t vkLoadingFailureCount = 0;
int32_t vulkanVersion = 0;
+ int32_t cpuVulkanVersion = 0;
+ int32_t glesVersion = 0;
+ int32_t angleLoadingCount = 0;
+ int32_t angleLoadingFailureCount = 0;
};
/*
@@ -64,6 +68,8 @@
uint64_t driverVersionCode = 0;
std::vector<int64_t> glDriverLoadingTime = {};
std::vector<int64_t> vkDriverLoadingTime = {};
+ std::vector<int64_t> angleDriverLoadingTime = {};
+ bool cpuVulkanInUse = false;
};
} // namespace android
diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
index b10cab7..7d62750 100644
--- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
+++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
@@ -55,6 +55,10 @@
Driver glDriverFallback;
Driver vkDriverToLoad;
Driver vkDriverFallback;
+ bool glDriverToSend;
+ bool vkDriverToSend;
+ int64_t glDriverLoadingTime;
+ int64_t vkDriverLoadingTime;
GpuStats()
: driverPackageName(""),
@@ -66,7 +70,11 @@
glDriverToLoad(Driver::NONE),
glDriverFallback(Driver::NONE),
vkDriverToLoad(Driver::NONE),
- vkDriverFallback(Driver::NONE) {}
+ vkDriverFallback(Driver::NONE),
+ glDriverToSend(false),
+ vkDriverToSend(false),
+ glDriverLoadingTime(0),
+ vkDriverLoadingTime(0) {}
};
public:
@@ -84,13 +92,14 @@
// which is required by android_link_namespaces.
void setDriverPathAndSphalLibraries(const std::string path, const std::string sphalLibraries);
android_namespace_t* getDriverNamespace();
+ void hintActivityLaunch();
void setGpuStats(const std::string& driverPackageName, const std::string& driverVersionName,
uint64_t versionCode, int64_t driverBuildTime,
const std::string& appPackageName, const int32_t vulkanVersion);
+ void setCpuVulkanInUse();
void setDriverToLoad(Driver driver);
void setDriverLoaded(Api api, bool isDriverLoaded, int64_t driverLoadingTime);
- void clearDriverLoadingInfo(Api api);
- void sendGpuStatsLocked(Driver driver, bool isDriverLoaded, int64_t driverLoadingTime);
+ void sendGpuStatsLocked(Api api, bool isDriverLoaded, int64_t driverLoadingTime);
bool shouldUseAngle(std::string appName);
bool shouldUseAngle();
diff --git a/libs/graphicsenv/include/graphicsenv/IGpuService.h b/libs/graphicsenv/include/graphicsenv/IGpuService.h
index 5bf0269..34f1c7e 100644
--- a/libs/graphicsenv/include/graphicsenv/IGpuService.h
+++ b/libs/graphicsenv/include/graphicsenv/IGpuService.h
@@ -40,6 +40,10 @@
const int32_t vulkanVersion, GraphicsEnv::Driver driver,
bool isDriverLoaded, int64_t driverLoadingTime) = 0;
+ // set CPU Vulkan in use signal from GraphicsEnvironment.
+ virtual void setCpuVulkanInUse(const std::string& appPackageName,
+ const uint64_t driverVersionCode) = 0;
+
// get GPU global stats from GpuStats module.
virtual status_t getGpuStatsGlobalInfo(std::vector<GpuStatsGlobalInfo>* outStats) const = 0;
@@ -53,6 +57,7 @@
SET_GPU_STATS = IBinder::FIRST_CALL_TRANSACTION,
GET_GPU_STATS_GLOBAL_INFO,
GET_GPU_STATS_APP_INFO,
+ SET_CPU_VULKAN_IN_USE,
// Always append new enum to the end.
};
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index a8b1a4c..4372e16 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -142,6 +142,28 @@
return result;
}
+ virtual status_t captureScreen(uint64_t displayOrLayerStack, ui::Dataspace* outDataspace,
+ sp<GraphicBuffer>* outBuffer) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ data.writeUint64(displayOrLayerStack);
+ status_t result = remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN_BY_ID, data, &reply);
+ if (result != NO_ERROR) {
+ ALOGE("captureScreen failed to transact: %d", result);
+ return result;
+ }
+ result = reply.readInt32();
+ if (result != NO_ERROR) {
+ ALOGE("captureScreen failed to readInt32: %d", result);
+ return result;
+ }
+
+ *outDataspace = static_cast<ui::Dataspace>(reply.readInt32());
+ *outBuffer = new GraphicBuffer();
+ reply.read(**outBuffer);
+ return result;
+ }
+
virtual status_t captureLayers(
const sp<IBinder>& layerHandleBinder, sp<GraphicBuffer>* outBuffer,
const ui::Dataspace reqDataspace, const ui::PixelFormat reqPixelFormat,
@@ -1042,6 +1064,19 @@
}
return NO_ERROR;
}
+ case CAPTURE_SCREEN_BY_ID: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ uint64_t displayOrLayerStack = data.readUint64();
+ ui::Dataspace outDataspace = ui::Dataspace::V0_SRGB;
+ sp<GraphicBuffer> outBuffer;
+ status_t res = captureScreen(displayOrLayerStack, &outDataspace, &outBuffer);
+ reply->writeInt32(res);
+ if (res == NO_ERROR) {
+ reply->writeInt32(static_cast<int32_t>(outDataspace));
+ reply->write(*outBuffer);
+ }
+ return NO_ERROR;
+ }
case CAPTURE_LAYERS: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> layerHandleBinder = data.readStrongBinder();
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 437cdd7..5d4367d 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1572,6 +1572,13 @@
useIdentityTransform, rotation, false, outBuffer, ignored);
}
+status_t ScreenshotClient::capture(uint64_t displayOrLayerStack, ui::Dataspace* outDataspace,
+ sp<GraphicBuffer>* outBuffer) {
+ sp<ISurfaceComposer> s(ComposerService::getComposerService());
+ if (s == nullptr) return NO_INIT;
+ return s->captureScreen(displayOrLayerStack, outDataspace, outBuffer);
+}
+
status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle,
const ui::Dataspace reqDataSpace,
const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
diff --git a/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp b/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp
index e64ba9b..cee1b81 100644
--- a/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp
+++ b/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp
@@ -1061,7 +1061,7 @@
status_t H2BGraphicBufferProducer::attachBuffer(
int* outSlot, const sp<GraphicBuffer>& buffer) {
- AnwBuffer tBuffer;
+ AnwBuffer tBuffer{};
wrapAs(&tBuffer, *buffer);
status_t fnStatus;
status_t transStatus = toStatusT(mBase->attachBuffer(tBuffer,
@@ -1076,7 +1076,7 @@
int slot,
const QueueBufferInput& input,
QueueBufferOutput* output) {
- HGraphicBufferProducer::QueueBufferInput tInput;
+ HGraphicBufferProducer::QueueBufferInput tInput{};
native_handle_t* nh;
if (!wrapAs(&tInput, &nh, input)) {
ALOGE("H2BGraphicBufferProducer::queueBuffer - "
diff --git a/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp b/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp
index e039593..e891ec5 100644
--- a/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp
+++ b/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp
@@ -15,7 +15,7 @@
*/
//#define LOG_NDEBUG 0
-#define LOG_TAG "H2BGraphicBufferProducer@2.0"
+#define LOG_TAG "B2HGraphicBufferProducer@2.0"
#include <android-base/logging.h>
@@ -30,13 +30,38 @@
#include <vndk/hardware_buffer.h>
namespace android {
-
namespace hardware {
namespace graphics {
namespace bufferqueue {
namespace V2_0 {
namespace utils {
+namespace /* unnamed */ {
+
+using BQueueBufferInput = ::android::
+ IGraphicBufferProducer::QueueBufferInput;
+using HQueueBufferInput = ::android::hardware::graphics::bufferqueue::V2_0::
+ IGraphicBufferProducer::QueueBufferInput;
+using BQueueBufferOutput = ::android::
+ IGraphicBufferProducer::QueueBufferOutput;
+using HQueueBufferOutput = ::android::hardware::graphics::bufferqueue::V2_0::
+ IGraphicBufferProducer::QueueBufferOutput;
+
+using ::android::hardware::graphics::bufferqueue::V2_0::utils::b2h;
+using ::android::hardware::graphics::bufferqueue::V2_0::utils::h2b;
+
+bool b2h(BQueueBufferOutput const& from, HQueueBufferOutput* to) {
+ to->width = from.width;
+ to->height = from.height;
+ to->transformHint = static_cast<int32_t>(from.transformHint);
+ to->numPendingBuffers = from.numPendingBuffers;
+ to->nextFrameNumber = from.nextFrameNumber;
+ to->bufferReplaced = from.bufferReplaced;
+ return true;
+}
+
+} // unnamed namespace
+
// B2HGraphicBufferProducer
// ========================
@@ -161,11 +186,7 @@
int32_t slot,
QueueBufferInput const& hInput,
queueBuffer_cb _hidl_cb) {
- using HOutput = QueueBufferOutput;
- using BInput = BGraphicBufferProducer::QueueBufferInput;
- using BOutput = BGraphicBufferProducer::QueueBufferOutput;
-
- BInput bInput{
+ BQueueBufferInput bInput{
hInput.timestamp,
hInput.isAutoTimestamp,
static_cast<android_dataspace>(hInput.dataSpace),
@@ -178,35 +199,32 @@
// Convert crop.
if (!h2b(hInput.crop, &bInput.crop)) {
- _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{});
+ _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
return {};
}
// Convert surfaceDamage.
if (!h2b(hInput.surfaceDamage, &bInput.surfaceDamage)) {
- _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{});
+ _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
return {};
}
// Convert fence.
if (!h2b(hInput.fence, &bInput.fence)) {
- _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{});
+ _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
return {};
}
- BOutput bOutput{};
+ BQueueBufferOutput bOutput{};
HStatus hStatus{};
- bool converted = b2h(
- mBase->queueBuffer(static_cast<int>(slot), bInput, &bOutput),
- &hStatus);
+ QueueBufferOutput hOutput{};
+ bool converted =
+ b2h(
+ mBase->queueBuffer(static_cast<int>(slot), bInput, &bOutput),
+ &hStatus) &&
+ b2h(bOutput, &hOutput);
- _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR,
- HOutput{bOutput.width,
- bOutput.height,
- static_cast<int32_t>(bOutput.transformHint),
- bOutput.numPendingBuffers,
- bOutput.nextFrameNumber,
- bOutput.bufferReplaced});
+ _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, hOutput);
return {};
}
@@ -236,33 +254,23 @@
HConnectionType hConnectionType,
bool producerControlledByApp,
connect_cb _hidl_cb) {
- using BOutput = BGraphicBufferProducer::QueueBufferOutput;
- using HOutput = HGraphicBufferProducer::QueueBufferOutput;
sp<BProducerListener> bListener = new H2BProducerListener(hListener);
- if (!bListener) {
- _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{});
+ int bConnectionType{};
+ if (!bListener || !h2b(hConnectionType, &bConnectionType)) {
+ _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
return {};
}
- int bConnectionType;
- if (!h2b(hConnectionType, &bConnectionType)) {
- _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{});
- return {};
- }
- BOutput bOutput{};
+ BQueueBufferOutput bOutput{};
HStatus hStatus{};
- bool converted = b2h(
- mBase->connect(bListener,
- bConnectionType,
- producerControlledByApp,
- &bOutput),
- &hStatus);
- _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR,
- HOutput{bOutput.width,
- bOutput.height,
- static_cast<int32_t>(bOutput.transformHint),
- bOutput.numPendingBuffers,
- bOutput.nextFrameNumber,
- bOutput.bufferReplaced});
+ QueueBufferOutput hOutput{};
+ bool converted =
+ b2h(mBase->connect(bListener,
+ bConnectionType,
+ producerControlledByApp,
+ &bOutput),
+ &hStatus) &&
+ b2h(bOutput, &hOutput);
+ _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, hOutput);
return {};
}
diff --git a/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp b/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp
index 1023ef1..2f5b73c 100644
--- a/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp
+++ b/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp
@@ -29,13 +29,54 @@
#include <vndk/hardware_buffer.h>
namespace android {
-
namespace hardware {
namespace graphics {
namespace bufferqueue {
namespace V2_0 {
namespace utils {
+namespace /* unnamed */ {
+
+using BQueueBufferInput = ::android::
+ IGraphicBufferProducer::QueueBufferInput;
+using HQueueBufferInput = ::android::hardware::graphics::bufferqueue::V2_0::
+ IGraphicBufferProducer::QueueBufferInput;
+using BQueueBufferOutput = ::android::
+ IGraphicBufferProducer::QueueBufferOutput;
+using HQueueBufferOutput = ::android::hardware::graphics::bufferqueue::V2_0::
+ IGraphicBufferProducer::QueueBufferOutput;
+
+using ::android::hardware::graphics::bufferqueue::V2_0::utils::b2h;
+using ::android::hardware::graphics::bufferqueue::V2_0::utils::h2b;
+
+bool b2h(BQueueBufferInput const& from, HQueueBufferInput* to,
+ HFenceWrapper* hFenceWrapper) {
+ to->timestamp = from.timestamp;
+ to->isAutoTimestamp = static_cast<bool>(from.isAutoTimestamp);
+ to->dataSpace = static_cast<int32_t>(from.dataSpace);
+ to->transform = static_cast<int32_t>(from.transform);
+ to->stickyTransform = static_cast<int32_t>(from.stickyTransform);
+ if (!b2h(from.crop, &to->crop) ||
+ !b2h(from.surfaceDamage, &to->surfaceDamage) ||
+ !b2h(from.fence, hFenceWrapper)) {
+ return false;
+ }
+ to->fence = hFenceWrapper->getHandle();
+ return true;
+}
+
+bool h2b(HQueueBufferOutput const& from, BQueueBufferOutput* to) {
+ to->width = from.width;
+ to->height = from.height;
+ to->transformHint = static_cast<uint32_t>(from.transformHint);
+ to->numPendingBuffers = from.numPendingBuffers;
+ to->nextFrameNumber = from.nextFrameNumber;
+ to->bufferReplaced = from.bufferReplaced;
+ return true;
+}
+
+} // unnamed namespace
+
// H2BGraphicBufferProducer
// ========================
@@ -209,47 +250,13 @@
int slot,
QueueBufferInput const& input,
QueueBufferOutput* output) {
- HRect hCrop{};
- (void)b2h(input.crop, &hCrop);
-
- using HInput = HGraphicBufferProducer::QueueBufferInput;
- HInput hInput{
- input.timestamp,
- static_cast<bool>(input.isAutoTimestamp),
- static_cast<int32_t>(input.dataSpace),
- {}, // crop
- static_cast<int32_t>(input.transform),
- static_cast<int32_t>(input.stickyTransform),
- {}, // fence
- {} // surfaceDamage
- };
-
- // Convert crop.
- if (!b2h(input.crop, &hInput.crop)) {
- LOG(ERROR) << "queueBuffer: corrupted input crop rectangle.";
- return UNKNOWN_ERROR;
- }
-
- // Convert surfaceDamage.
- size_t numRects;
- Rect const* rectArray = input.surfaceDamage.getArray(&numRects);
- hInput.surfaceDamage.resize(numRects);
- for (size_t i = 0; i < numRects; ++i) {
- if (!b2h(rectArray[i], &hInput.surfaceDamage[i])) {
- LOG(ERROR) << "queueBuffer: corrupted input surface damage.";
- return UNKNOWN_ERROR;
- }
- }
-
- // Convert fence.
+ HQueueBufferInput hInput{};
HFenceWrapper hFenceWrapper;
- if (!b2h(input.fence, &hFenceWrapper)) {
- LOG(ERROR) << "queueBuffer: corrupted input fence.";
+ if (!b2h(input, &hInput, &hFenceWrapper)) {
+ LOG(ERROR) << "queueBuffer: corrupted input.";
return UNKNOWN_ERROR;
}
- hInput.fence = hFenceWrapper.getHandle();
- using HOutput = HGraphicBufferProducer::QueueBufferOutput;
bool converted{};
status_t bStatus{};
Return<void> transResult = mBase->queueBuffer(
@@ -257,15 +264,8 @@
hInput,
[&converted, &bStatus, output](
HStatus hStatus,
- HOutput const& hOutput) {
- converted = h2b(hStatus, &bStatus);
- output->width = hOutput.width;
- output->height = hOutput.height;
- output->transformHint =
- static_cast<uint32_t>(hOutput.transformHint);
- output->numPendingBuffers = hOutput.numPendingBuffers;
- output->nextFrameNumber = hOutput.nextFrameNumber;
- output->bufferReplaced = hOutput.bufferReplaced;
+ HQueueBufferOutput const& hOutput) {
+ converted = h2b(hStatus, &bStatus) && h2b(hOutput, output);
});
if (!transResult.isOk()) {
@@ -332,7 +332,6 @@
}
}
- using HOutput = HGraphicBufferProducer::QueueBufferOutput;
bool converted{};
status_t bStatus{};
Return<void> transResult = mBase->connect(
@@ -341,15 +340,8 @@
producerControlledByApp,
[&converted, &bStatus, output](
HStatus hStatus,
- HOutput hOutput) {
- converted = h2b(hStatus, &bStatus);
- output->width = hOutput.width;
- output->height = hOutput.height;
- output->transformHint =
- static_cast<uint32_t>(hOutput.transformHint);
- output->numPendingBuffers = hOutput.numPendingBuffers;
- output->nextFrameNumber = hOutput.nextFrameNumber;
- output->bufferReplaced = hOutput.bufferReplaced;
+ HQueueBufferOutput const& hOutput) {
+ converted = h2b(hStatus, &bStatus) && h2b(hOutput, output);
});
if (!transResult.isOk()) {
LOG(ERROR) << "connect: transaction failed.";
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index e8c7a39..fd67754 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -247,6 +247,9 @@
useIdentityTransform, rotation);
}
+ virtual status_t captureScreen(uint64_t displayOrLayerStack, ui::Dataspace* outDataspace,
+ sp<GraphicBuffer>* outBuffer) = 0;
+
template <class AA>
struct SpHash {
size_t operator()(const sp<AA>& k) const { return std::hash<AA*>()(k.get()); }
@@ -473,6 +476,7 @@
GET_ALLOWED_DISPLAY_CONFIGS,
GET_DISPLAY_BRIGHTNESS_SUPPORT,
SET_DISPLAY_BRIGHTNESS,
+ CAPTURE_SCREEN_BY_ID,
// Always append new enum to the end.
};
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 9d34468..a038838 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -515,6 +515,8 @@
const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
uint32_t rotation, sp<GraphicBuffer>* outBuffer);
+ static status_t capture(uint64_t displayOrLayerStack, ui::Dataspace* outDataspace,
+ sp<GraphicBuffer>* outBuffer);
static status_t captureLayers(const sp<IBinder>& layerHandle, const ui::Dataspace reqDataSpace,
const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
float frameScale, sp<GraphicBuffer>* outBuffer);
diff --git a/libs/gui/include/gui/bufferqueue/1.0/WGraphicBufferProducer.h b/libs/gui/include/gui/bufferqueue/1.0/WGraphicBufferProducer.h
index 0e57f20..029dcc0 100644
--- a/libs/gui/include/gui/bufferqueue/1.0/WGraphicBufferProducer.h
+++ b/libs/gui/include/gui/bufferqueue/1.0/WGraphicBufferProducer.h
@@ -68,7 +68,7 @@
Return<void> requestBuffer(int32_t slot, HGraphicBufferProducer::requestBuffer_cb _hidl_cb) override {
sp<GraphicBuffer> buf;
status_t status = mBase->requestBuffer(slot, &buf);
- AnwBuffer anwBuffer;
+ AnwBuffer anwBuffer{};
if (buf != nullptr) {
::android::conversion::wrapAs(&anwBuffer, *buf);
}
@@ -89,15 +89,15 @@
uint32_t width, uint32_t height,
::android::hardware::graphics::common::V1_0::PixelFormat format, uint32_t usage,
bool getFrameTimestamps, HGraphicBufferProducer::dequeueBuffer_cb _hidl_cb) override {
- int slot;
+ int slot{};
sp<Fence> fence;
::android::FrameEventHistoryDelta outTimestamps;
status_t status = mBase->dequeueBuffer(
&slot, &fence, width, height,
static_cast<::android::PixelFormat>(format), usage, nullptr,
getFrameTimestamps ? &outTimestamps : nullptr);
- hidl_handle tFence;
- HGraphicBufferProducer::FrameEventHistoryDelta tOutTimestamps;
+ hidl_handle tFence{};
+ HGraphicBufferProducer::FrameEventHistoryDelta tOutTimestamps{};
native_handle_t* nh = nullptr;
if ((fence == nullptr) || !::android::conversion::wrapAs(&tFence, &nh, *fence)) {
@@ -144,8 +144,8 @@
sp<GraphicBuffer> outBuffer;
sp<Fence> outFence;
status_t status = mBase->detachNextBuffer(&outBuffer, &outFence);
- AnwBuffer tBuffer;
- hidl_handle tFence;
+ AnwBuffer tBuffer{};
+ hidl_handle tFence{};
if (outBuffer == nullptr) {
LOG(ERROR) << "TWGraphicBufferProducer::detachNextBuffer - "
@@ -185,7 +185,7 @@
Return<void> queueBuffer(
int32_t slot, const HGraphicBufferProducer::QueueBufferInput& input,
HGraphicBufferProducer::queueBuffer_cb _hidl_cb) override {
- HGraphicBufferProducer::QueueBufferOutput tOutput;
+ HGraphicBufferProducer::QueueBufferOutput tOutput{};
BGraphicBufferProducer::QueueBufferInput lInput(
0, false, HAL_DATASPACE_UNKNOWN,
::android::Rect(0, 0, 1, 1),
@@ -246,7 +246,7 @@
producerControlledByApp,
&lOutput);
- HGraphicBufferProducer::QueueBufferOutput tOutput;
+ HGraphicBufferProducer::QueueBufferOutput tOutput{};
std::vector<std::vector<native_handle_t*> > nhAA;
if (!::android::conversion::wrapAs(&tOutput, &nhAA, lOutput)) {
LOG(ERROR) << "TWGraphicBufferProducer::connect - "
@@ -320,11 +320,11 @@
status_t status = mBase->getLastQueuedBuffer(
&lOutBuffer, &lOutFence, lOutTransformMatrix);
- AnwBuffer tOutBuffer;
+ AnwBuffer tOutBuffer{};
if (lOutBuffer != nullptr) {
::android::conversion::wrapAs(&tOutBuffer, *lOutBuffer);
}
- hidl_handle tOutFence;
+ hidl_handle tOutFence{};
native_handle_t* nh = nullptr;
if ((lOutFence == nullptr) || !::android::conversion::wrapAs(&tOutFence, &nh, *lOutFence)) {
LOG(ERROR) << "TWGraphicBufferProducer::getLastQueuedBuffer - "
@@ -346,7 +346,7 @@
::android::FrameEventHistoryDelta lDelta;
mBase->getFrameTimestamps(&lDelta);
- HGraphicBufferProducer::FrameEventHistoryDelta tDelta;
+ HGraphicBufferProducer::FrameEventHistoryDelta tDelta{};
std::vector<std::vector<native_handle_t*> > nhAA;
if (!::android::conversion::wrapAs(&tDelta, &nhAA, lDelta)) {
LOG(ERROR) << "TWGraphicBufferProducer::getFrameTimestamps - "
@@ -365,7 +365,7 @@
}
Return<void> getUniqueId(HGraphicBufferProducer::getUniqueId_cb _hidl_cb) override {
- uint64_t outId;
+ uint64_t outId{};
status_t status = mBase->getUniqueId(&outId);
_hidl_cb(static_cast<int32_t>(status), outId);
return Void();
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 4a78480..ff1ba0a 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -391,6 +391,25 @@
parentSurface->expectTap(1, 1);
}
+// Ensure a surface whose insets are scaled, handles the touch offset correctly.
+TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets) {
+ std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
+ std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
+ bgSurface->showAt(100, 100);
+
+ fgSurface->mInputInfo.surfaceInset = 5;
+ fgSurface->showAt(100, 100);
+
+ fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 4.0); });
+
+ // expect = touch / scale - inset
+ injectTap(112, 124);
+ fgSurface->expectTap(1, 1);
+
+ injectTap(101, 101);
+ bgSurface->expectTap(1, 1);
+}
+
// Ensure we ignore transparent region when getting screen bounds when positioning input frame.
TEST_F(InputSurfacesTest, input_ignores_transparent_region) {
std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 014b1fa..db97fae 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -623,6 +623,10 @@
bool /*captureSecureLayers*/) override {
return NO_ERROR;
}
+ status_t captureScreen(uint64_t /*displayOrLayerStack*/, ui::Dataspace* /*outDataspace*/,
+ sp<GraphicBuffer>* /*outBuffer*/) override {
+ return NO_ERROR;
+ }
virtual status_t captureLayers(
const sp<IBinder>& /*parentHandle*/, sp<GraphicBuffer>* /*outBuffer*/,
const ui::Dataspace /*reqDataspace*/, const ui::PixelFormat /*reqPixelFormat*/,
diff --git a/services/audiomanager/IAudioManager.cpp b/services/audiomanager/IAudioManager.cpp
index f5d4826..6235f06 100644
--- a/services/audiomanager/IAudioManager.cpp
+++ b/services/audiomanager/IAudioManager.cpp
@@ -122,6 +122,13 @@
data.writeInt32((int32_t) event);
return remote()->transact(RECORDER_EVENT, data, &reply, IBinder::FLAG_ONEWAY);
}
+
+ virtual status_t releaseRecorder(audio_unique_id_t riid) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioManager::getInterfaceDescriptor());
+ data.writeInt32((int32_t) riid);
+ return remote()->transact(RELEASE_RECORDER, data, &reply, IBinder::FLAG_ONEWAY);
+ }
};
IMPLEMENT_META_INTERFACE(AudioManager, "android.media.IAudioService");
diff --git a/services/gpuservice/GpuService.cpp b/services/gpuservice/GpuService.cpp
index b42884e..8accf9d 100644
--- a/services/gpuservice/GpuService.cpp
+++ b/services/gpuservice/GpuService.cpp
@@ -75,6 +75,13 @@
return OK;
}
+void GpuService::setCpuVulkanInUse(const std::string& appPackageName,
+ const uint64_t driverVersionCode) {
+ ATRACE_CALL();
+
+ mGpuStats->setCpuVulkanInUse(appPackageName, driverVersionCode);
+}
+
status_t GpuService::shellCommand(int /*in*/, int out, int err, std::vector<String16>& args) {
ATRACE_CALL();
diff --git a/services/gpuservice/GpuService.h b/services/gpuservice/GpuService.h
index 3e02b4a..8226901 100644
--- a/services/gpuservice/GpuService.h
+++ b/services/gpuservice/GpuService.h
@@ -50,6 +50,8 @@
int64_t driverLoadingTime) override;
status_t getGpuStatsGlobalInfo(std::vector<GpuStatsGlobalInfo>* outStats) const override;
status_t getGpuStatsAppInfo(std::vector<GpuStatsAppInfo>* outStats) const override;
+ void setCpuVulkanInUse(const std::string& appPackageName,
+ const uint64_t driverVersionCode) override;
/*
* IBinder interface
diff --git a/services/gpuservice/gpustats/GpuStats.cpp b/services/gpuservice/gpustats/GpuStats.cpp
index 1cb78db..37c6abc 100644
--- a/services/gpuservice/gpustats/GpuStats.cpp
+++ b/services/gpuservice/gpustats/GpuStats.cpp
@@ -19,14 +19,15 @@
#include "GpuStats.h"
-#include <unordered_set>
-
+#include <cutils/properties.h>
#include <log/log.h>
#include <utils/Trace.h>
+#include <unordered_set>
+
namespace android {
-static bool addLoadingCount(GraphicsEnv::Driver driver, bool isDriverLoaded,
+static void addLoadingCount(GraphicsEnv::Driver driver, bool isDriverLoaded,
GpuStatsGlobalInfo* const outGlobalInfo) {
switch (driver) {
case GraphicsEnv::Driver::GL:
@@ -39,13 +40,13 @@
outGlobalInfo->vkLoadingCount++;
if (!isDriverLoaded) outGlobalInfo->vkLoadingFailureCount++;
break;
+ case GraphicsEnv::Driver::ANGLE:
+ outGlobalInfo->angleLoadingCount++;
+ if (!isDriverLoaded) outGlobalInfo->angleLoadingFailureCount++;
+ break;
default:
- // Currently we don't support GraphicsEnv::Driver::ANGLE because the
- // basic driver package info only belongs to system or updated driver.
- return false;
+ break;
}
-
- return true;
}
static void addLoadingTime(GraphicsEnv::Driver driver, int64_t driverLoadingTime,
@@ -53,13 +54,20 @@
switch (driver) {
case GraphicsEnv::Driver::GL:
case GraphicsEnv::Driver::GL_UPDATED:
- if (outAppInfo->glDriverLoadingTime.size() >= GpuStats::MAX_NUM_LOADING_TIMES) break;
- outAppInfo->glDriverLoadingTime.emplace_back(driverLoadingTime);
+ if (outAppInfo->glDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
+ outAppInfo->glDriverLoadingTime.emplace_back(driverLoadingTime);
+ }
break;
case GraphicsEnv::Driver::VULKAN:
case GraphicsEnv::Driver::VULKAN_UPDATED:
- if (outAppInfo->vkDriverLoadingTime.size() >= GpuStats::MAX_NUM_LOADING_TIMES) break;
- outAppInfo->vkDriverLoadingTime.emplace_back(driverLoadingTime);
+ if (outAppInfo->vkDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
+ outAppInfo->vkDriverLoadingTime.emplace_back(driverLoadingTime);
+ }
+ break;
+ case GraphicsEnv::Driver::ANGLE:
+ if (outAppInfo->angleDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
+ outAppInfo->angleDriverLoadingTime.emplace_back(driverLoadingTime);
+ }
break;
default:
break;
@@ -89,26 +97,24 @@
if (!mGlobalStats.count(driverVersionCode)) {
GpuStatsGlobalInfo globalInfo;
- if (!addLoadingCount(driver, isDriverLoaded, &globalInfo)) {
- return;
- }
+ addLoadingCount(driver, isDriverLoaded, &globalInfo);
globalInfo.driverPackageName = driverPackageName;
globalInfo.driverVersionName = driverVersionName;
globalInfo.driverVersionCode = driverVersionCode;
globalInfo.driverBuildTime = driverBuildTime;
globalInfo.vulkanVersion = vulkanVersion;
mGlobalStats.insert({driverVersionCode, globalInfo});
- } else if (!addLoadingCount(driver, isDriverLoaded, &mGlobalStats[driverVersionCode])) {
- return;
- }
-
- if (mAppStats.size() >= MAX_NUM_APP_RECORDS) {
- ALOGV("GpuStatsAppInfo has reached maximum size. Ignore new stats.");
- return;
+ } else {
+ addLoadingCount(driver, isDriverLoaded, &mGlobalStats[driverVersionCode]);
}
const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode);
if (!mAppStats.count(appStatsKey)) {
+ if (mAppStats.size() >= MAX_NUM_APP_RECORDS) {
+ ALOGV("GpuStatsAppInfo has reached maximum size. Ignore new stats.");
+ return;
+ }
+
GpuStatsAppInfo appInfo;
addLoadingTime(driver, driverLoadingTime, &appInfo);
appInfo.appPackageName = appPackageName;
@@ -120,6 +126,26 @@
addLoadingTime(driver, driverLoadingTime, &mAppStats[appStatsKey]);
}
+void GpuStats::setCpuVulkanInUse(const std::string& appPackageName,
+ const uint64_t driverVersionCode) {
+ const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode);
+ if (!mAppStats.count(appStatsKey)) {
+ return;
+ }
+
+ mAppStats[appStatsKey].cpuVulkanInUse = true;
+}
+
+void GpuStats::interceptSystemDriverStatsLocked() {
+ // Append cpuVulkanVersion and glesVersion to system driver stats
+ if (!mGlobalStats.count(0) || mGlobalStats[0].glesVersion) {
+ return;
+ }
+
+ mGlobalStats[0].cpuVulkanVersion = property_get_int32("ro.cpuvulkan.version", 0);
+ mGlobalStats[0].glesVersion = property_get_int32("ro.opengles.version", 0);
+}
+
void GpuStats::dump(const Vector<String16>& args, std::string* result) {
ATRACE_CALL();
@@ -176,6 +202,8 @@
}
void GpuStats::dumpGlobalLocked(std::string* result) {
+ interceptSystemDriverStatsLocked();
+
for (const auto& ele : mGlobalStats) {
result->append(ele.second.toString());
result->append("\n");
@@ -196,6 +224,8 @@
outStats->clear();
outStats->reserve(mGlobalStats.size());
+ interceptSystemDriverStatsLocked();
+
for (const auto& ele : mGlobalStats) {
outStats->emplace_back(ele.second);
}
diff --git a/services/gpuservice/gpustats/GpuStats.h b/services/gpuservice/gpustats/GpuStats.h
index bb74fbb..b293f59 100644
--- a/services/gpuservice/gpustats/GpuStats.h
+++ b/services/gpuservice/gpustats/GpuStats.h
@@ -37,6 +37,8 @@
uint64_t driverVersionCode, int64_t driverBuildTime,
const std::string& appPackageName, const int32_t vulkanVersion,
GraphicsEnv::Driver driver, bool isDriverLoaded, int64_t driverLoadingTime);
+ // Set CPU Vulkan in use signal into app stats.
+ void setCpuVulkanInUse(const std::string& appPackageName, const uint64_t driverVersionCode);
// dumpsys interface
void dump(const Vector<String16>& args, std::string* result);
// Pull gpu global stats
@@ -52,6 +54,8 @@
void dumpGlobalLocked(std::string* result);
// Dump app stats
void dumpAppLocked(std::string* result);
+ // Append cpuVulkanVersion and glesVersion to system driver stats
+ void interceptSystemDriverStatsLocked();
// Below limits the memory usage of GpuStats to be less than 10KB. This is
// the preferred number for statsd while maintaining nice data quality.
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp
index 63e759c..8dd4d1d 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -29,6 +29,7 @@
srcs: [
"InputClassifier.cpp",
+ "InputClassifierConverter.cpp",
"InputDispatcher.cpp",
"InputManager.cpp",
],
diff --git a/services/inputflinger/InputClassifier.cpp b/services/inputflinger/InputClassifier.cpp
index 4a6efa6..ef1a224 100644
--- a/services/inputflinger/InputClassifier.cpp
+++ b/services/inputflinger/InputClassifier.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "InputClassifier"
#include "InputClassifier.h"
+#include "InputClassifierConverter.h"
#include <algorithm>
#include <android-base/stringprintf.h>
@@ -64,373 +65,6 @@
return it->second;
}
-static common::V1_0::Source getSource(uint32_t source) {
- static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_UNKNOWN) ==
- common::V1_0::Source::UNKNOWN, "SOURCE_UNKNOWN mismatch");
- static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_KEYBOARD) ==
- common::V1_0::Source::KEYBOARD, "SOURCE_KEYBOARD mismatch");
- static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_DPAD) ==
- common::V1_0::Source::DPAD, "SOURCE_DPAD mismatch");
- static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_GAMEPAD) ==
- common::V1_0::Source::GAMEPAD, "SOURCE_GAMEPAD mismatch");
- static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_TOUCHSCREEN) ==
- common::V1_0::Source::TOUCHSCREEN, "SOURCE_TOUCHSCREEN mismatch");
- static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_MOUSE) ==
- common::V1_0::Source::MOUSE, "SOURCE_MOUSE mismatch");
- static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_STYLUS) ==
- common::V1_0::Source::STYLUS, "SOURCE_STYLUS mismatch");
- static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_BLUETOOTH_STYLUS) ==
- common::V1_0::Source::BLUETOOTH_STYLUS, "SOURCE_BLUETOOTH_STYLUS mismatch");
- static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_TRACKBALL) ==
- common::V1_0::Source::TRACKBALL, "SOURCE_TRACKBALL mismatch");
- static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_MOUSE_RELATIVE) ==
- common::V1_0::Source::MOUSE_RELATIVE, "SOURCE_MOUSE_RELATIVE mismatch");
- static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_TOUCHPAD) ==
- common::V1_0::Source::TOUCHPAD, "SOURCE_TOUCHPAD mismatch");
- static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_TOUCH_NAVIGATION) ==
- common::V1_0::Source::TOUCH_NAVIGATION, "SOURCE_TOUCH_NAVIGATION mismatch");
- static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_JOYSTICK) ==
- common::V1_0::Source::JOYSTICK, "SOURCE_JOYSTICK mismatch");
- static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_ROTARY_ENCODER) ==
- common::V1_0::Source::ROTARY_ENCODER, "SOURCE_ROTARY_ENCODER mismatch");
- static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_ANY) ==
- common::V1_0::Source::ANY, "SOURCE_ANY mismatch");
- return static_cast<common::V1_0::Source>(source);
-}
-
-static common::V1_0::Action getAction(int32_t actionMasked) {
- static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_DOWN) ==
- common::V1_0::Action::DOWN, "ACTION_DOWN mismatch");
- static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_UP) ==
- common::V1_0::Action::UP, "ACTION_UP mismatch");
- static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_MOVE) ==
- common::V1_0::Action::MOVE, "ACTION_MOVE mismatch");
- static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_CANCEL) ==
- common::V1_0::Action::CANCEL, "ACTION_CANCEL mismatch");
- static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_OUTSIDE) ==
- common::V1_0::Action::OUTSIDE, "ACTION_OUTSIDE mismatch");
- static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_POINTER_DOWN) ==
- common::V1_0::Action::POINTER_DOWN, "ACTION_POINTER_DOWN mismatch");
- static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_POINTER_UP) ==
- common::V1_0::Action::POINTER_UP, "ACTION_POINTER_UP mismatch");
- static_assert(static_cast<common::V1_0::Action>( AMOTION_EVENT_ACTION_HOVER_MOVE) ==
- common::V1_0::Action::HOVER_MOVE, "ACTION_HOVER_MOVE mismatch");
- static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_SCROLL) ==
- common::V1_0::Action::SCROLL, "ACTION_SCROLL mismatch");
- static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_HOVER_ENTER) ==
- common::V1_0::Action::HOVER_ENTER, "ACTION_HOVER_ENTER mismatch");
- static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_HOVER_EXIT) ==
- common::V1_0::Action::HOVER_EXIT, "ACTION_HOVER_EXIT mismatch");
- static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_BUTTON_PRESS) ==
- common::V1_0::Action::BUTTON_PRESS, "ACTION_BUTTON_PRESS mismatch");
- static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_BUTTON_RELEASE) ==
- common::V1_0::Action::BUTTON_RELEASE, "ACTION_BUTTON_RELEASE mismatch");
- return static_cast<common::V1_0::Action>(actionMasked);
-}
-
-static common::V1_0::Button getActionButton(int32_t actionButton) {
- static_assert(static_cast<common::V1_0::Button>(0) ==
- common::V1_0::Button::NONE, "BUTTON_NONE mismatch");
- static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_PRIMARY) ==
- common::V1_0::Button::PRIMARY, "BUTTON_PRIMARY mismatch");
- static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_SECONDARY) ==
- common::V1_0::Button::SECONDARY, "BUTTON_SECONDARY mismatch");
- static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_TERTIARY) ==
- common::V1_0::Button::TERTIARY, "BUTTON_TERTIARY mismatch");
- static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_BACK) ==
- common::V1_0::Button::BACK, "BUTTON_BACK mismatch");
- static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_FORWARD) ==
- common::V1_0::Button::FORWARD, "BUTTON_FORWARD mismatch");
- static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) ==
- common::V1_0::Button::STYLUS_PRIMARY, "BUTTON_STYLUS_PRIMARY mismatch");
- static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY) ==
- common::V1_0::Button::STYLUS_SECONDARY, "BUTTON_STYLUS_SECONDARY mismatch");
- return static_cast<common::V1_0::Button>(actionButton);
-}
-
-static hidl_bitfield<common::V1_0::Flag> getFlags(int32_t flags) {
- static_assert(static_cast<common::V1_0::Flag>(AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED) ==
- common::V1_0::Flag::WINDOW_IS_OBSCURED);
- static_assert(static_cast<common::V1_0::Flag>(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE) ==
- common::V1_0::Flag::IS_GENERATED_GESTURE);
- static_assert(static_cast<common::V1_0::Flag>(AMOTION_EVENT_FLAG_TAINTED) ==
- common::V1_0::Flag::TAINTED);
- return static_cast<hidl_bitfield<common::V1_0::Flag>>(flags);
-}
-
-static hidl_bitfield<common::V1_0::PolicyFlag> getPolicyFlags(int32_t flags) {
- static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_WAKE) ==
- common::V1_0::PolicyFlag::WAKE);
- static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_VIRTUAL) ==
- common::V1_0::PolicyFlag::VIRTUAL);
- static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_FUNCTION) ==
- common::V1_0::PolicyFlag::FUNCTION);
- static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_GESTURE) ==
- common::V1_0::PolicyFlag::GESTURE);
- static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_INJECTED) ==
- common::V1_0::PolicyFlag::INJECTED);
- static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_TRUSTED) ==
- common::V1_0::PolicyFlag::TRUSTED);
- static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_FILTERED) ==
- common::V1_0::PolicyFlag::FILTERED);
- static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_DISABLE_KEY_REPEAT) ==
- common::V1_0::PolicyFlag::DISABLE_KEY_REPEAT);
- static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_INTERACTIVE) ==
- common::V1_0::PolicyFlag::INTERACTIVE);
- static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_PASS_TO_USER) ==
- common::V1_0::PolicyFlag::PASS_TO_USER);
- return static_cast<hidl_bitfield<common::V1_0::PolicyFlag>>(flags);
-}
-
-static hidl_bitfield<common::V1_0::EdgeFlag> getEdgeFlags(int32_t flags) {
- static_assert(static_cast<common::V1_0::EdgeFlag>(AMOTION_EVENT_EDGE_FLAG_NONE) ==
- common::V1_0::EdgeFlag::NONE);
- static_assert(static_cast<common::V1_0::EdgeFlag>(AMOTION_EVENT_EDGE_FLAG_TOP) ==
- common::V1_0::EdgeFlag::TOP);
- static_assert(static_cast<common::V1_0::EdgeFlag>(AMOTION_EVENT_EDGE_FLAG_BOTTOM) ==
- common::V1_0::EdgeFlag::BOTTOM);
- static_assert(static_cast<common::V1_0::EdgeFlag>(AMOTION_EVENT_EDGE_FLAG_LEFT) ==
- common::V1_0::EdgeFlag::LEFT);
- static_assert(static_cast<common::V1_0::EdgeFlag>(AMOTION_EVENT_EDGE_FLAG_RIGHT) ==
- common::V1_0::EdgeFlag::RIGHT);
- return static_cast<hidl_bitfield<common::V1_0::EdgeFlag>>(flags);
-}
-
-static hidl_bitfield<common::V1_0::Meta> getMetastate(int32_t state) {
- static_assert(static_cast<common::V1_0::Meta>(AMETA_NONE) ==
- common::V1_0::Meta::NONE);
- static_assert(static_cast<common::V1_0::Meta>(AMETA_ALT_ON) ==
- common::V1_0::Meta::ALT_ON);
- static_assert(static_cast<common::V1_0::Meta>(AMETA_ALT_LEFT_ON) ==
- common::V1_0::Meta::ALT_LEFT_ON);
- static_assert(static_cast<common::V1_0::Meta>(AMETA_ALT_RIGHT_ON) ==
- common::V1_0::Meta::ALT_RIGHT_ON);
- static_assert(static_cast<common::V1_0::Meta>(AMETA_SHIFT_ON) ==
- common::V1_0::Meta::SHIFT_ON);
- static_assert(static_cast<common::V1_0::Meta>(AMETA_SHIFT_LEFT_ON) ==
- common::V1_0::Meta::SHIFT_LEFT_ON);
- static_assert(static_cast<common::V1_0::Meta>(AMETA_SHIFT_RIGHT_ON) ==
- common::V1_0::Meta::SHIFT_RIGHT_ON);
- static_assert(static_cast<common::V1_0::Meta>(AMETA_SYM_ON) ==
- common::V1_0::Meta::SYM_ON);
- static_assert(static_cast<common::V1_0::Meta>(AMETA_FUNCTION_ON) ==
- common::V1_0::Meta::FUNCTION_ON);
- static_assert(static_cast<common::V1_0::Meta>(AMETA_CTRL_ON) ==
- common::V1_0::Meta::CTRL_ON);
- static_assert(static_cast<common::V1_0::Meta>(AMETA_CTRL_LEFT_ON) ==
- common::V1_0::Meta::CTRL_LEFT_ON);
- static_assert(static_cast<common::V1_0::Meta>(AMETA_CTRL_RIGHT_ON) ==
- common::V1_0::Meta::CTRL_RIGHT_ON);
- static_assert(static_cast<common::V1_0::Meta>(AMETA_META_ON) ==
- common::V1_0::Meta::META_ON);
- static_assert(static_cast<common::V1_0::Meta>(AMETA_META_LEFT_ON) ==
- common::V1_0::Meta::META_LEFT_ON);
- static_assert(static_cast<common::V1_0::Meta>(AMETA_META_RIGHT_ON) ==
- common::V1_0::Meta::META_RIGHT_ON);
- static_assert(static_cast<common::V1_0::Meta>(AMETA_CAPS_LOCK_ON) ==
- common::V1_0::Meta::CAPS_LOCK_ON);
- static_assert(static_cast<common::V1_0::Meta>(AMETA_NUM_LOCK_ON) ==
- common::V1_0::Meta::NUM_LOCK_ON);
- static_assert(static_cast<common::V1_0::Meta>(AMETA_SCROLL_LOCK_ON) ==
- common::V1_0::Meta::SCROLL_LOCK_ON);
- return static_cast<hidl_bitfield<common::V1_0::Meta>>(state);
-}
-
-static hidl_bitfield<common::V1_0::Button> getButtonState(int32_t buttonState) {
- // No need for static_assert here.
- // The button values have already been asserted in getActionButton(..) above
- return static_cast<hidl_bitfield<common::V1_0::Button>>(buttonState);
-}
-
-static common::V1_0::ToolType getToolType(int32_t toolType) {
- static_assert(static_cast<common::V1_0::ToolType>(AMOTION_EVENT_TOOL_TYPE_UNKNOWN) ==
- common::V1_0::ToolType::UNKNOWN);
- static_assert(static_cast<common::V1_0::ToolType>(AMOTION_EVENT_TOOL_TYPE_FINGER) ==
- common::V1_0::ToolType::FINGER);
- static_assert(static_cast<common::V1_0::ToolType>(AMOTION_EVENT_TOOL_TYPE_STYLUS) ==
- common::V1_0::ToolType::STYLUS);
- static_assert(static_cast<common::V1_0::ToolType>(AMOTION_EVENT_TOOL_TYPE_MOUSE) ==
- common::V1_0::ToolType::MOUSE);
- static_assert(static_cast<common::V1_0::ToolType>(AMOTION_EVENT_TOOL_TYPE_ERASER) ==
- common::V1_0::ToolType::ERASER);
- return static_cast<common::V1_0::ToolType>(toolType);
-}
-
-static common::V1_0::Axis getAxis(uint64_t axis) {
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_X) ==
- common::V1_0::Axis::X);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_Y) ==
- common::V1_0::Axis::Y);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_PRESSURE) ==
- common::V1_0::Axis::PRESSURE);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_SIZE) ==
- common::V1_0::Axis::SIZE);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_TOUCH_MAJOR) ==
- common::V1_0::Axis::TOUCH_MAJOR);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_TOUCH_MINOR) ==
- common::V1_0::Axis::TOUCH_MINOR);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_TOOL_MAJOR) ==
- common::V1_0::Axis::TOOL_MAJOR);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_TOOL_MINOR) ==
- common::V1_0::Axis::TOOL_MINOR);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_ORIENTATION) ==
- common::V1_0::Axis::ORIENTATION);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_VSCROLL) ==
- common::V1_0::Axis::VSCROLL);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_HSCROLL) ==
- common::V1_0::Axis::HSCROLL);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_Z) ==
- common::V1_0::Axis::Z);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RX) ==
- common::V1_0::Axis::RX);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RY) ==
- common::V1_0::Axis::RY);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RZ) ==
- common::V1_0::Axis::RZ);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_HAT_X) ==
- common::V1_0::Axis::HAT_X);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_HAT_Y) ==
- common::V1_0::Axis::HAT_Y);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_LTRIGGER) ==
- common::V1_0::Axis::LTRIGGER);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RTRIGGER) ==
- common::V1_0::Axis::RTRIGGER);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_THROTTLE) ==
- common::V1_0::Axis::THROTTLE);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RUDDER) ==
- common::V1_0::Axis::RUDDER);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_WHEEL) ==
- common::V1_0::Axis::WHEEL);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GAS) ==
- common::V1_0::Axis::GAS);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_BRAKE) ==
- common::V1_0::Axis::BRAKE);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_DISTANCE) ==
- common::V1_0::Axis::DISTANCE);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_TILT) ==
- common::V1_0::Axis::TILT);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_SCROLL) ==
- common::V1_0::Axis::SCROLL);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RELATIVE_X) ==
- common::V1_0::Axis::RELATIVE_X);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RELATIVE_Y) ==
- common::V1_0::Axis::RELATIVE_Y);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_1) ==
- common::V1_0::Axis::GENERIC_1);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_2) ==
- common::V1_0::Axis::GENERIC_2);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_3) ==
- common::V1_0::Axis::GENERIC_3);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_4) ==
- common::V1_0::Axis::GENERIC_4);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_5) ==
- common::V1_0::Axis::GENERIC_5);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_6) ==
- common::V1_0::Axis::GENERIC_6);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_7) ==
- common::V1_0::Axis::GENERIC_7);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_8) ==
- common::V1_0::Axis::GENERIC_8);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_9) ==
- common::V1_0::Axis::GENERIC_9);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_10) ==
- common::V1_0::Axis::GENERIC_10);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_11) ==
- common::V1_0::Axis::GENERIC_11);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_12) ==
- common::V1_0::Axis::GENERIC_12);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_13) ==
- common::V1_0::Axis::GENERIC_13);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_14) ==
- common::V1_0::Axis::GENERIC_14);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_15) ==
- common::V1_0::Axis::GENERIC_15);
- static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_16) ==
- common::V1_0::Axis::GENERIC_16);
- return static_cast<common::V1_0::Axis>(axis);
-}
-
-static common::V1_0::VideoFrame getHalVideoFrame(const TouchVideoFrame& frame) {
- common::V1_0::VideoFrame out;
- out.width = frame.getWidth();
- out.height = frame.getHeight();
- out.data = frame.getData();
- struct timeval timestamp = frame.getTimestamp();
- out.timestamp = seconds_to_nanoseconds(timestamp.tv_sec) +
- microseconds_to_nanoseconds(timestamp.tv_usec);
- return out;
-}
-
-static std::vector<common::V1_0::VideoFrame> convertVideoFrames(
- const std::vector<TouchVideoFrame>& frames) {
- std::vector<common::V1_0::VideoFrame> out;
- for (const TouchVideoFrame& frame : frames) {
- out.push_back(getHalVideoFrame(frame));
- }
- return out;
-}
-
-static uint8_t getActionIndex(int32_t action) {
- return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
- AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
-}
-
-static void getHidlPropertiesAndCoords(const NotifyMotionArgs& args,
- std::vector<common::V1_0::PointerProperties>* outPointerProperties,
- std::vector<common::V1_0::PointerCoords>* outPointerCoords) {
- outPointerProperties->reserve(args.pointerCount);
- outPointerCoords->reserve(args.pointerCount);
- for (size_t i = 0; i < args.pointerCount; i++) {
- common::V1_0::PointerProperties properties;
- properties.id = args.pointerProperties[i].id;
- properties.toolType = getToolType(args.pointerProperties[i].toolType);
- outPointerProperties->push_back(properties);
-
- common::V1_0::PointerCoords coords;
- BitSet64 bits (args.pointerCoords[i].bits);
- std::vector<float> values;
- size_t index = 0;
- while (!bits.isEmpty()) {
- uint32_t axis = bits.clearFirstMarkedBit();
- coords.bits |= 1 << static_cast<uint64_t>(getAxis(axis));
- float value = args.pointerCoords[i].values[index++];
- values.push_back(value);
- }
- coords.values = values;
- outPointerCoords->push_back(coords);
- }
-}
-
-static common::V1_0::MotionEvent getMotionEvent(const NotifyMotionArgs& args) {
- common::V1_0::MotionEvent event;
- event.deviceId = args.deviceId;
- event.source = getSource(args.source);
- event.displayId = args.displayId;
- event.downTime = args.downTime;
- event.eventTime = args.eventTime;
- event.action = getAction(args.action & AMOTION_EVENT_ACTION_MASK);
- event.actionIndex = getActionIndex(args.action);
- event.actionButton = getActionButton(args.actionButton);
- event.flags = getFlags(args.flags);
- event.policyFlags = getPolicyFlags(args.policyFlags);
- event.edgeFlags = getEdgeFlags(args.edgeFlags);
- event.metaState = getMetastate(args.metaState);
- event.buttonState = getButtonState(args.buttonState);
- event.xPrecision = args.xPrecision;
- event.yPrecision = args.yPrecision;
-
- std::vector<common::V1_0::PointerProperties> pointerProperties;
- std::vector<common::V1_0::PointerCoords> pointerCoords;
- getHidlPropertiesAndCoords(args, /*out*/&pointerProperties, /*out*/&pointerCoords);
- event.pointerProperties = pointerProperties;
- event.pointerCoords = pointerCoords;
-
- event.deviceTimestamp = args.deviceTimestamp;
- event.frames = convertVideoFrames(args.videoFrames);
-
- return event;
-}
-
static MotionClassification getMotionClassification(common::V1_0::Classification classification) {
static_assert(MotionClassification::NONE ==
static_cast<MotionClassification>(common::V1_0::Classification::NONE));
@@ -602,7 +236,8 @@
switch (event.type) {
case ClassifierEventType::MOTION: {
NotifyMotionArgs* motionArgs = static_cast<NotifyMotionArgs*>(event.args.get());
- common::V1_0::MotionEvent motionEvent = getMotionEvent(*motionArgs);
+ common::V1_0::MotionEvent motionEvent =
+ notifyMotionArgsToHalMotionEvent(*motionArgs);
Return<common::V1_0::Classification> response = mService->classify(motionEvent);
halResponseOk = response.isOk();
if (halResponseOk) {
diff --git a/services/inputflinger/InputClassifierConverter.cpp b/services/inputflinger/InputClassifierConverter.cpp
new file mode 100644
index 0000000..f82c8ef
--- /dev/null
+++ b/services/inputflinger/InputClassifierConverter.cpp
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "InputClassifierConverter.h"
+
+using android::hardware::hidl_bitfield;
+using namespace android::hardware::input;
+
+namespace android {
+
+static common::V1_0::Source getSource(uint32_t source) {
+ static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_UNKNOWN) ==
+ common::V1_0::Source::UNKNOWN, "SOURCE_UNKNOWN mismatch");
+ static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_KEYBOARD) ==
+ common::V1_0::Source::KEYBOARD, "SOURCE_KEYBOARD mismatch");
+ static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_DPAD) ==
+ common::V1_0::Source::DPAD, "SOURCE_DPAD mismatch");
+ static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_GAMEPAD) ==
+ common::V1_0::Source::GAMEPAD, "SOURCE_GAMEPAD mismatch");
+ static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_TOUCHSCREEN) ==
+ common::V1_0::Source::TOUCHSCREEN, "SOURCE_TOUCHSCREEN mismatch");
+ static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_MOUSE) ==
+ common::V1_0::Source::MOUSE, "SOURCE_MOUSE mismatch");
+ static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_STYLUS) ==
+ common::V1_0::Source::STYLUS, "SOURCE_STYLUS mismatch");
+ static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_BLUETOOTH_STYLUS) ==
+ common::V1_0::Source::BLUETOOTH_STYLUS, "SOURCE_BLUETOOTH_STYLUS mismatch");
+ static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_TRACKBALL) ==
+ common::V1_0::Source::TRACKBALL, "SOURCE_TRACKBALL mismatch");
+ static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_MOUSE_RELATIVE) ==
+ common::V1_0::Source::MOUSE_RELATIVE, "SOURCE_MOUSE_RELATIVE mismatch");
+ static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_TOUCHPAD) ==
+ common::V1_0::Source::TOUCHPAD, "SOURCE_TOUCHPAD mismatch");
+ static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_TOUCH_NAVIGATION) ==
+ common::V1_0::Source::TOUCH_NAVIGATION, "SOURCE_TOUCH_NAVIGATION mismatch");
+ static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_JOYSTICK) ==
+ common::V1_0::Source::JOYSTICK, "SOURCE_JOYSTICK mismatch");
+ static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_ROTARY_ENCODER) ==
+ common::V1_0::Source::ROTARY_ENCODER, "SOURCE_ROTARY_ENCODER mismatch");
+ static_assert(static_cast<common::V1_0::Source>(AINPUT_SOURCE_ANY) ==
+ common::V1_0::Source::ANY, "SOURCE_ANY mismatch");
+ return static_cast<common::V1_0::Source>(source);
+}
+
+static common::V1_0::Action getAction(int32_t actionMasked) {
+ static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_DOWN) ==
+ common::V1_0::Action::DOWN, "ACTION_DOWN mismatch");
+ static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_UP) ==
+ common::V1_0::Action::UP, "ACTION_UP mismatch");
+ static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_MOVE) ==
+ common::V1_0::Action::MOVE, "ACTION_MOVE mismatch");
+ static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_CANCEL) ==
+ common::V1_0::Action::CANCEL, "ACTION_CANCEL mismatch");
+ static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_OUTSIDE) ==
+ common::V1_0::Action::OUTSIDE, "ACTION_OUTSIDE mismatch");
+ static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_POINTER_DOWN) ==
+ common::V1_0::Action::POINTER_DOWN, "ACTION_POINTER_DOWN mismatch");
+ static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_POINTER_UP) ==
+ common::V1_0::Action::POINTER_UP, "ACTION_POINTER_UP mismatch");
+ static_assert(static_cast<common::V1_0::Action>( AMOTION_EVENT_ACTION_HOVER_MOVE) ==
+ common::V1_0::Action::HOVER_MOVE, "ACTION_HOVER_MOVE mismatch");
+ static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_SCROLL) ==
+ common::V1_0::Action::SCROLL, "ACTION_SCROLL mismatch");
+ static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_HOVER_ENTER) ==
+ common::V1_0::Action::HOVER_ENTER, "ACTION_HOVER_ENTER mismatch");
+ static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_HOVER_EXIT) ==
+ common::V1_0::Action::HOVER_EXIT, "ACTION_HOVER_EXIT mismatch");
+ static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_BUTTON_PRESS) ==
+ common::V1_0::Action::BUTTON_PRESS, "ACTION_BUTTON_PRESS mismatch");
+ static_assert(static_cast<common::V1_0::Action>(AMOTION_EVENT_ACTION_BUTTON_RELEASE) ==
+ common::V1_0::Action::BUTTON_RELEASE, "ACTION_BUTTON_RELEASE mismatch");
+ return static_cast<common::V1_0::Action>(actionMasked);
+}
+
+static common::V1_0::Button getActionButton(int32_t actionButton) {
+ static_assert(static_cast<common::V1_0::Button>(0) ==
+ common::V1_0::Button::NONE, "BUTTON_NONE mismatch");
+ static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_PRIMARY) ==
+ common::V1_0::Button::PRIMARY, "BUTTON_PRIMARY mismatch");
+ static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_SECONDARY) ==
+ common::V1_0::Button::SECONDARY, "BUTTON_SECONDARY mismatch");
+ static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_TERTIARY) ==
+ common::V1_0::Button::TERTIARY, "BUTTON_TERTIARY mismatch");
+ static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_BACK) ==
+ common::V1_0::Button::BACK, "BUTTON_BACK mismatch");
+ static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_FORWARD) ==
+ common::V1_0::Button::FORWARD, "BUTTON_FORWARD mismatch");
+ static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) ==
+ common::V1_0::Button::STYLUS_PRIMARY, "BUTTON_STYLUS_PRIMARY mismatch");
+ static_assert(static_cast<common::V1_0::Button>(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY) ==
+ common::V1_0::Button::STYLUS_SECONDARY, "BUTTON_STYLUS_SECONDARY mismatch");
+ return static_cast<common::V1_0::Button>(actionButton);
+}
+
+static hidl_bitfield<common::V1_0::Flag> getFlags(int32_t flags) {
+ static_assert(static_cast<common::V1_0::Flag>(AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED) ==
+ common::V1_0::Flag::WINDOW_IS_OBSCURED);
+ static_assert(static_cast<common::V1_0::Flag>(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE) ==
+ common::V1_0::Flag::IS_GENERATED_GESTURE);
+ static_assert(static_cast<common::V1_0::Flag>(AMOTION_EVENT_FLAG_TAINTED) ==
+ common::V1_0::Flag::TAINTED);
+ return static_cast<hidl_bitfield<common::V1_0::Flag>>(flags);
+}
+
+static hidl_bitfield<common::V1_0::PolicyFlag> getPolicyFlags(int32_t flags) {
+ static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_WAKE) ==
+ common::V1_0::PolicyFlag::WAKE);
+ static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_VIRTUAL) ==
+ common::V1_0::PolicyFlag::VIRTUAL);
+ static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_FUNCTION) ==
+ common::V1_0::PolicyFlag::FUNCTION);
+ static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_GESTURE) ==
+ common::V1_0::PolicyFlag::GESTURE);
+ static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_INJECTED) ==
+ common::V1_0::PolicyFlag::INJECTED);
+ static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_TRUSTED) ==
+ common::V1_0::PolicyFlag::TRUSTED);
+ static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_FILTERED) ==
+ common::V1_0::PolicyFlag::FILTERED);
+ static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_DISABLE_KEY_REPEAT) ==
+ common::V1_0::PolicyFlag::DISABLE_KEY_REPEAT);
+ static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_INTERACTIVE) ==
+ common::V1_0::PolicyFlag::INTERACTIVE);
+ static_assert(static_cast<common::V1_0::PolicyFlag>(POLICY_FLAG_PASS_TO_USER) ==
+ common::V1_0::PolicyFlag::PASS_TO_USER);
+ return static_cast<hidl_bitfield<common::V1_0::PolicyFlag>>(flags);
+}
+
+static hidl_bitfield<common::V1_0::EdgeFlag> getEdgeFlags(int32_t flags) {
+ static_assert(static_cast<common::V1_0::EdgeFlag>(AMOTION_EVENT_EDGE_FLAG_NONE) ==
+ common::V1_0::EdgeFlag::NONE);
+ static_assert(static_cast<common::V1_0::EdgeFlag>(AMOTION_EVENT_EDGE_FLAG_TOP) ==
+ common::V1_0::EdgeFlag::TOP);
+ static_assert(static_cast<common::V1_0::EdgeFlag>(AMOTION_EVENT_EDGE_FLAG_BOTTOM) ==
+ common::V1_0::EdgeFlag::BOTTOM);
+ static_assert(static_cast<common::V1_0::EdgeFlag>(AMOTION_EVENT_EDGE_FLAG_LEFT) ==
+ common::V1_0::EdgeFlag::LEFT);
+ static_assert(static_cast<common::V1_0::EdgeFlag>(AMOTION_EVENT_EDGE_FLAG_RIGHT) ==
+ common::V1_0::EdgeFlag::RIGHT);
+ return static_cast<hidl_bitfield<common::V1_0::EdgeFlag>>(flags);
+}
+
+static hidl_bitfield<common::V1_0::Meta> getMetastate(int32_t state) {
+ static_assert(static_cast<common::V1_0::Meta>(AMETA_NONE) ==
+ common::V1_0::Meta::NONE);
+ static_assert(static_cast<common::V1_0::Meta>(AMETA_ALT_ON) ==
+ common::V1_0::Meta::ALT_ON);
+ static_assert(static_cast<common::V1_0::Meta>(AMETA_ALT_LEFT_ON) ==
+ common::V1_0::Meta::ALT_LEFT_ON);
+ static_assert(static_cast<common::V1_0::Meta>(AMETA_ALT_RIGHT_ON) ==
+ common::V1_0::Meta::ALT_RIGHT_ON);
+ static_assert(static_cast<common::V1_0::Meta>(AMETA_SHIFT_ON) ==
+ common::V1_0::Meta::SHIFT_ON);
+ static_assert(static_cast<common::V1_0::Meta>(AMETA_SHIFT_LEFT_ON) ==
+ common::V1_0::Meta::SHIFT_LEFT_ON);
+ static_assert(static_cast<common::V1_0::Meta>(AMETA_SHIFT_RIGHT_ON) ==
+ common::V1_0::Meta::SHIFT_RIGHT_ON);
+ static_assert(static_cast<common::V1_0::Meta>(AMETA_SYM_ON) ==
+ common::V1_0::Meta::SYM_ON);
+ static_assert(static_cast<common::V1_0::Meta>(AMETA_FUNCTION_ON) ==
+ common::V1_0::Meta::FUNCTION_ON);
+ static_assert(static_cast<common::V1_0::Meta>(AMETA_CTRL_ON) ==
+ common::V1_0::Meta::CTRL_ON);
+ static_assert(static_cast<common::V1_0::Meta>(AMETA_CTRL_LEFT_ON) ==
+ common::V1_0::Meta::CTRL_LEFT_ON);
+ static_assert(static_cast<common::V1_0::Meta>(AMETA_CTRL_RIGHT_ON) ==
+ common::V1_0::Meta::CTRL_RIGHT_ON);
+ static_assert(static_cast<common::V1_0::Meta>(AMETA_META_ON) ==
+ common::V1_0::Meta::META_ON);
+ static_assert(static_cast<common::V1_0::Meta>(AMETA_META_LEFT_ON) ==
+ common::V1_0::Meta::META_LEFT_ON);
+ static_assert(static_cast<common::V1_0::Meta>(AMETA_META_RIGHT_ON) ==
+ common::V1_0::Meta::META_RIGHT_ON);
+ static_assert(static_cast<common::V1_0::Meta>(AMETA_CAPS_LOCK_ON) ==
+ common::V1_0::Meta::CAPS_LOCK_ON);
+ static_assert(static_cast<common::V1_0::Meta>(AMETA_NUM_LOCK_ON) ==
+ common::V1_0::Meta::NUM_LOCK_ON);
+ static_assert(static_cast<common::V1_0::Meta>(AMETA_SCROLL_LOCK_ON) ==
+ common::V1_0::Meta::SCROLL_LOCK_ON);
+ return static_cast<hidl_bitfield<common::V1_0::Meta>>(state);
+}
+
+static hidl_bitfield<common::V1_0::Button> getButtonState(int32_t buttonState) {
+ // No need for static_assert here.
+ // The button values have already been asserted in getActionButton(..) above
+ return static_cast<hidl_bitfield<common::V1_0::Button>>(buttonState);
+}
+
+static common::V1_0::ToolType getToolType(int32_t toolType) {
+ static_assert(static_cast<common::V1_0::ToolType>(AMOTION_EVENT_TOOL_TYPE_UNKNOWN) ==
+ common::V1_0::ToolType::UNKNOWN);
+ static_assert(static_cast<common::V1_0::ToolType>(AMOTION_EVENT_TOOL_TYPE_FINGER) ==
+ common::V1_0::ToolType::FINGER);
+ static_assert(static_cast<common::V1_0::ToolType>(AMOTION_EVENT_TOOL_TYPE_STYLUS) ==
+ common::V1_0::ToolType::STYLUS);
+ static_assert(static_cast<common::V1_0::ToolType>(AMOTION_EVENT_TOOL_TYPE_MOUSE) ==
+ common::V1_0::ToolType::MOUSE);
+ static_assert(static_cast<common::V1_0::ToolType>(AMOTION_EVENT_TOOL_TYPE_ERASER) ==
+ common::V1_0::ToolType::ERASER);
+ return static_cast<common::V1_0::ToolType>(toolType);
+}
+
+// MotionEvent axes asserts
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_X) ==
+ common::V1_0::Axis::X);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_Y) ==
+ common::V1_0::Axis::Y);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_PRESSURE) ==
+ common::V1_0::Axis::PRESSURE);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_SIZE) ==
+ common::V1_0::Axis::SIZE);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_TOUCH_MAJOR) ==
+ common::V1_0::Axis::TOUCH_MAJOR);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_TOUCH_MINOR) ==
+ common::V1_0::Axis::TOUCH_MINOR);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_TOOL_MAJOR) ==
+ common::V1_0::Axis::TOOL_MAJOR);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_TOOL_MINOR) ==
+ common::V1_0::Axis::TOOL_MINOR);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_ORIENTATION) ==
+ common::V1_0::Axis::ORIENTATION);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_VSCROLL) ==
+ common::V1_0::Axis::VSCROLL);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_HSCROLL) ==
+ common::V1_0::Axis::HSCROLL);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_Z) ==
+ common::V1_0::Axis::Z);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RX) ==
+ common::V1_0::Axis::RX);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RY) ==
+ common::V1_0::Axis::RY);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RZ) ==
+ common::V1_0::Axis::RZ);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_HAT_X) ==
+ common::V1_0::Axis::HAT_X);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_HAT_Y) ==
+ common::V1_0::Axis::HAT_Y);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_LTRIGGER) ==
+ common::V1_0::Axis::LTRIGGER);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RTRIGGER) ==
+ common::V1_0::Axis::RTRIGGER);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_THROTTLE) ==
+ common::V1_0::Axis::THROTTLE);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RUDDER) ==
+ common::V1_0::Axis::RUDDER);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_WHEEL) ==
+ common::V1_0::Axis::WHEEL);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GAS) ==
+ common::V1_0::Axis::GAS);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_BRAKE) ==
+ common::V1_0::Axis::BRAKE);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_DISTANCE) ==
+ common::V1_0::Axis::DISTANCE);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_TILT) ==
+ common::V1_0::Axis::TILT);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_SCROLL) ==
+ common::V1_0::Axis::SCROLL);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RELATIVE_X) ==
+ common::V1_0::Axis::RELATIVE_X);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_RELATIVE_Y) ==
+ common::V1_0::Axis::RELATIVE_Y);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_1) ==
+ common::V1_0::Axis::GENERIC_1);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_2) ==
+ common::V1_0::Axis::GENERIC_2);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_3) ==
+ common::V1_0::Axis::GENERIC_3);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_4) ==
+ common::V1_0::Axis::GENERIC_4);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_5) ==
+ common::V1_0::Axis::GENERIC_5);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_6) ==
+ common::V1_0::Axis::GENERIC_6);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_7) ==
+ common::V1_0::Axis::GENERIC_7);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_8) ==
+ common::V1_0::Axis::GENERIC_8);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_9) ==
+ common::V1_0::Axis::GENERIC_9);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_10) ==
+ common::V1_0::Axis::GENERIC_10);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_11) ==
+ common::V1_0::Axis::GENERIC_11);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_12) ==
+ common::V1_0::Axis::GENERIC_12);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_13) ==
+ common::V1_0::Axis::GENERIC_13);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_14) ==
+ common::V1_0::Axis::GENERIC_14);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_15) ==
+ common::V1_0::Axis::GENERIC_15);
+static_assert(static_cast<common::V1_0::Axis>(AMOTION_EVENT_AXIS_GENERIC_16) ==
+ common::V1_0::Axis::GENERIC_16);
+
+static common::V1_0::VideoFrame getHalVideoFrame(const TouchVideoFrame& frame) {
+ common::V1_0::VideoFrame out;
+ out.width = frame.getWidth();
+ out.height = frame.getHeight();
+ out.data = frame.getData();
+ struct timeval timestamp = frame.getTimestamp();
+ out.timestamp = seconds_to_nanoseconds(timestamp.tv_sec) +
+ microseconds_to_nanoseconds(timestamp.tv_usec);
+ return out;
+}
+
+static std::vector<common::V1_0::VideoFrame> convertVideoFrames(
+ const std::vector<TouchVideoFrame>& frames) {
+ std::vector<common::V1_0::VideoFrame> out;
+ for (const TouchVideoFrame& frame : frames) {
+ out.push_back(getHalVideoFrame(frame));
+ }
+ return out;
+}
+
+static uint8_t getActionIndex(int32_t action) {
+ return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
+ AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+}
+
+static void getHidlPropertiesAndCoords(const NotifyMotionArgs& args,
+ std::vector<common::V1_0::PointerProperties>* outPointerProperties,
+ std::vector<common::V1_0::PointerCoords>* outPointerCoords) {
+ outPointerProperties->reserve(args.pointerCount);
+ outPointerCoords->reserve(args.pointerCount);
+ for (size_t i = 0; i < args.pointerCount; i++) {
+ common::V1_0::PointerProperties properties;
+ properties.id = args.pointerProperties[i].id;
+ properties.toolType = getToolType(args.pointerProperties[i].toolType);
+ outPointerProperties->push_back(properties);
+
+ common::V1_0::PointerCoords coords;
+ // OK to copy bits because we have static_assert for pointerCoords axes
+ coords.bits = args.pointerCoords[i].bits;
+ coords.values = std::vector<float>(
+ args.pointerCoords[i].values,
+ args.pointerCoords[i].values + BitSet64::count(args.pointerCoords[i].bits));
+ outPointerCoords->push_back(coords);
+ }
+}
+
+common::V1_0::MotionEvent notifyMotionArgsToHalMotionEvent(const NotifyMotionArgs& args) {
+ common::V1_0::MotionEvent event;
+ event.deviceId = args.deviceId;
+ event.source = getSource(args.source);
+ event.displayId = args.displayId;
+ event.downTime = args.downTime;
+ event.eventTime = args.eventTime;
+ event.action = getAction(args.action & AMOTION_EVENT_ACTION_MASK);
+ event.actionIndex = getActionIndex(args.action);
+ event.actionButton = getActionButton(args.actionButton);
+ event.flags = getFlags(args.flags);
+ event.policyFlags = getPolicyFlags(args.policyFlags);
+ event.edgeFlags = getEdgeFlags(args.edgeFlags);
+ event.metaState = getMetastate(args.metaState);
+ event.buttonState = getButtonState(args.buttonState);
+ event.xPrecision = args.xPrecision;
+ event.yPrecision = args.yPrecision;
+
+ std::vector<common::V1_0::PointerProperties> pointerProperties;
+ std::vector<common::V1_0::PointerCoords> pointerCoords;
+ getHidlPropertiesAndCoords(args, /*out*/&pointerProperties, /*out*/&pointerCoords);
+ event.pointerProperties = pointerProperties;
+ event.pointerCoords = pointerCoords;
+
+ event.deviceTimestamp = args.deviceTimestamp;
+ event.frames = convertVideoFrames(args.videoFrames);
+
+ return event;
+}
+
+} // namespace android
diff --git a/services/inputflinger/InputClassifierConverter.h b/services/inputflinger/InputClassifierConverter.h
new file mode 100644
index 0000000..5154b0b
--- /dev/null
+++ b/services/inputflinger/InputClassifierConverter.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UI_INPUT_CLASSIFIER_CONVERTER_H
+#define _UI_INPUT_CLASSIFIER_CONVERTER_H
+
+#include "InputListener.h"
+#include <android/hardware/input/common/1.0/types.h>
+
+
+namespace android {
+
+/**
+ * Convert from framework's NotifyMotionArgs to hidl's common::V1_0::MotionEvent
+ */
+::android::hardware::input::common::V1_0::MotionEvent notifyMotionArgsToHalMotionEvent(
+ const NotifyMotionArgs& args);
+
+} // namespace android
+
+#endif // _UI_INPUT_CLASSIFIER_CONVERTER_H
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index b874411..31a2dab 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -3611,8 +3611,9 @@
}
void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
- dump += StringPrintf(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
- dump += StringPrintf(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
+ dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
+ dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
+ dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
if (!mFocusedApplicationHandlesByDisplay.empty()) {
diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp
index 1835449..9054316 100644
--- a/services/inputflinger/tests/Android.bp
+++ b/services/inputflinger/tests/Android.bp
@@ -6,6 +6,7 @@
"BlockingQueue_test.cpp",
"TestInputListener.cpp",
"InputClassifier_test.cpp",
+ "InputClassifierConverter_test.cpp",
"InputDispatcher_test.cpp",
"InputReader_test.cpp",
],
diff --git a/services/inputflinger/tests/InputClassifierConverter_test.cpp b/services/inputflinger/tests/InputClassifierConverter_test.cpp
new file mode 100644
index 0000000..813b69e
--- /dev/null
+++ b/services/inputflinger/tests/InputClassifierConverter_test.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "../InputClassifierConverter.h"
+
+#include <gtest/gtest.h>
+#include <utils/BitSet.h>
+
+
+using namespace android::hardware::input;
+
+namespace android {
+
+// --- InputClassifierConverterTest ---
+
+static NotifyMotionArgs generateBasicMotionArgs() {
+ // Create a basic motion event for testing
+ PointerProperties properties;
+ properties.id = 0;
+ properties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+
+ PointerCoords coords;
+ coords.clear();
+ coords.setAxisValue(AMOTION_EVENT_AXIS_X, 1);
+ coords.setAxisValue(AMOTION_EVENT_AXIS_Y, 2);
+ coords.setAxisValue(AMOTION_EVENT_AXIS_SIZE, 0.5);
+ static constexpr nsecs_t downTime = 2;
+ NotifyMotionArgs motionArgs(1/*sequenceNum*/, downTime/*eventTime*/, 3/*deviceId*/,
+ AINPUT_SOURCE_ANY, ADISPLAY_ID_DEFAULT, 4/*policyFlags*/, AMOTION_EVENT_ACTION_DOWN,
+ 0/*actionButton*/, 0/*flags*/, AMETA_NONE, 0/*buttonState*/, MotionClassification::NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE, 5/*deviceTimestamp*/,
+ 1/*pointerCount*/, &properties, &coords, 0/*xPrecision*/, 0/*yPrecision*/,
+ downTime, {}/*videoFrames*/);
+ return motionArgs;
+}
+
+static float getMotionEventAxis(common::V1_0::PointerCoords coords,
+ common::V1_0::Axis axis) {
+ uint32_t index = BitSet64::getIndexOfBit(static_cast<uint64_t>(coords.bits),
+ static_cast<uint64_t>(axis));
+ return coords.values[index];
+}
+
+/**
+ * Check that coordinates get converted properly from the framework's PointerCoords
+ * to the hidl PointerCoords in input::common.
+ */
+TEST(InputClassifierConverterTest, PointerCoordsAxes) {
+ const NotifyMotionArgs motionArgs = generateBasicMotionArgs();
+ ASSERT_EQ(1, motionArgs.pointerCoords[0].getX());
+ ASSERT_EQ(2, motionArgs.pointerCoords[0].getY());
+ ASSERT_EQ(0.5, motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_SIZE));
+ ASSERT_EQ(3U, BitSet64::count(motionArgs.pointerCoords[0].bits));
+
+ common::V1_0::MotionEvent motionEvent = notifyMotionArgsToHalMotionEvent(motionArgs);
+
+ ASSERT_EQ(getMotionEventAxis(motionEvent.pointerCoords[0], common::V1_0::Axis::X),
+ motionArgs.pointerCoords[0].getX());
+ ASSERT_EQ(getMotionEventAxis(motionEvent.pointerCoords[0], common::V1_0::Axis::Y),
+ motionArgs.pointerCoords[0].getY());
+ ASSERT_EQ(getMotionEventAxis(motionEvent.pointerCoords[0], common::V1_0::Axis::SIZE),
+ motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_SIZE));
+ ASSERT_EQ(BitSet64::count(motionArgs.pointerCoords[0].bits),
+ BitSet64::count(motionEvent.pointerCoords[0].bits));
+}
+
+} // namespace android
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 659329e..fcd4f29 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -467,11 +467,6 @@
asBaseType(INTERNAL_WAKE), &eventFlagState);
availableEvents = mEventQueue->availableToRead();
- if ((eventFlagState & asBaseType(EventQueueFlagBits::READ_AND_PROCESS)) &&
- availableEvents == 0) {
- ALOGW("Event FMQ wake without any events");
- }
-
if ((eventFlagState & asBaseType(INTERNAL_WAKE)) && mReconnecting) {
ALOGD("Event FMQ internal wake, returning from poll with no events");
return DEAD_OBJECT;
@@ -544,6 +539,9 @@
}
Info& info(mActivationCount.editValueAt(activationIndex));
info.removeBatchParamsForIdent(ident);
+ if (info.numActiveClients() == 0) {
+ info.isActive = false;
+ }
}
status_t SensorDevice::activate(void* ident, int handle, int enabled) {
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 639ce78..fa1e232 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -1686,26 +1686,29 @@
const int32_t opCode = sensor.getRequiredAppOp();
const int32_t appOpMode = sAppOpsManager.checkOp(opCode,
IPCThreadState::self()->getCallingUid(), opPackageName);
+ bool appOpAllowed = appOpMode == AppOpsManager::MODE_ALLOWED;
- // Ensure that the AppOp is allowed
- //
- // This check is also required to ensure that the user hasn't revoked the necessary permissions
- // to access the Step Detector and Step Counter when the application targets pre-Q. Without this
- // check, if the user revokes the pre-Q install-time GMS Core AR permission, the app would
- // still be able to receive Step Counter and Step Detector events.
bool canAccess = false;
- if (opCode >= 0 && appOpMode == AppOpsManager::MODE_ALLOWED) {
- if (hasPermissionForSensor(sensor)) {
+ if (hasPermissionForSensor(sensor)) {
+ // Ensure that the AppOp is allowed, or that there is no necessary app op for the sensor
+ if (opCode < 0 || appOpAllowed) {
canAccess = true;
- } else if (sensor.getType() == SENSOR_TYPE_STEP_COUNTER ||
- sensor.getType() == SENSOR_TYPE_STEP_DETECTOR) {
- int targetSdkVersion = getTargetSdkVersion(opPackageName);
- // Allow access to the sensor if the application targets pre-Q, which is before the
- // requirement to hold the AR permission to access Step Counter and Step Detector events
- // was introduced.
- if (targetSdkVersion > 0 && targetSdkVersion <= __ANDROID_API_P__) {
- canAccess = true;
- }
+ }
+ } else if (sensor.getType() == SENSOR_TYPE_STEP_COUNTER ||
+ sensor.getType() == SENSOR_TYPE_STEP_DETECTOR) {
+ int targetSdkVersion = getTargetSdkVersion(opPackageName);
+ // Allow access to the sensor if the application targets pre-Q, which is before the
+ // requirement to hold the AR permission to access Step Counter and Step Detector events
+ // was introduced, and the user hasn't revoked the app op.
+ //
+ // Verifying the app op is required to ensure that the user hasn't revoked the necessary
+ // permissions to access the Step Detector and Step Counter when the application targets
+ // pre-Q. Without this check, if the user revokes the pre-Q install-time GMS Core AR
+ // permission, the app would still be able to receive Step Counter and Step Detector events.
+ if (appOpAllowed &&
+ targetSdkVersion > 0 &&
+ targetSdkVersion <= __ANDROID_API_P__) {
+ canAccess = true;
}
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index cbe8b29..379b004 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2004,10 +2004,14 @@
ui::Transform t = getTransform();
const float xScale = t.sx();
const float yScale = t.sy();
+ float xSurfaceInset = info.surfaceInset;
+ float ySurfaceInset = info.surfaceInset;
if (xScale != 1.0f || yScale != 1.0f) {
info.windowXScale *= 1.0f / xScale;
info.windowYScale *= 1.0f / yScale;
info.touchableRegion.scaleSelf(xScale, yScale);
+ xSurfaceInset *= xScale;
+ ySurfaceInset *= yScale;
}
// Transform layer size to screen space and inset it by surface insets.
@@ -2019,7 +2023,7 @@
layerBounds = getCroppedBufferSize(getDrawingState());
}
layerBounds = t.transform(layerBounds);
- layerBounds.inset(info.surfaceInset, info.surfaceInset, info.surfaceInset, info.surfaceInset);
+ layerBounds.inset(xSurfaceInset, ySurfaceInset, xSurfaceInset, ySurfaceInset);
// Input coordinate should match the layer bounds.
info.frameLeft = layerBounds.left;
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index 1e5c25f..5b4bec9 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -37,9 +37,16 @@
return false;
}
+ Mutex::Autolock _l(mFlinger.mStateLock);
mLayer = mClient->getLayerUser(mIBinder);
mLayer->setCrop_legacy(Rect(50, 70, 200, 100), true);
- mLayer->setLayer(INT32_MAX - 2);
+
+ // setting Layer's Z requires resorting layersSortedByZ
+ ssize_t idx = mFlinger.mCurrentState.layersSortedByZ.indexOf(mLayer);
+ if (mLayer->setLayer(INT32_MAX - 2) && idx >= 0) {
+ mFlinger.mCurrentState.layersSortedByZ.removeAt(idx);
+ mFlinger.mCurrentState.layersSortedByZ.add(mLayer);
+ }
return true;
}
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index 0d14267..3684260 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -168,11 +168,8 @@
mPhaseCallback(std::make_unique<SamplingOffsetCallback>(*this, mScheduler,
tunables.mSamplingOffset)),
lastSampleTime(0ns) {
- {
- std::lock_guard threadLock(mThreadMutex);
- mThread = std::thread([this]() { threadMain(); });
- pthread_setname_np(mThread.native_handle(), "RegionSamplingThread");
- }
+ mThread = std::thread([this]() { threadMain(); });
+ pthread_setname_np(mThread.native_handle(), "RegionSamplingThread");
mIdleTimer.start();
}
@@ -186,12 +183,11 @@
mIdleTimer.stop();
{
- std::lock_guard lock(mMutex);
+ std::lock_guard lock(mThreadControlMutex);
mRunning = false;
mCondition.notify_one();
}
- std::lock_guard threadLock(mThreadMutex);
if (mThread.joinable()) {
mThread.join();
}
@@ -205,17 +201,17 @@
sp<IBinder> asBinder = IInterface::asBinder(listener);
asBinder->linkToDeath(this);
- std::lock_guard lock(mMutex);
+ std::lock_guard lock(mSamplingMutex);
mDescriptors.emplace(wp<IBinder>(asBinder), Descriptor{samplingArea, stopLayer, listener});
}
void RegionSamplingThread::removeListener(const sp<IRegionSamplingListener>& listener) {
- std::lock_guard lock(mMutex);
+ std::lock_guard lock(mSamplingMutex);
mDescriptors.erase(wp<IBinder>(IInterface::asBinder(listener)));
}
void RegionSamplingThread::checkForStaleLuma() {
- std::lock_guard lock(mMutex);
+ std::lock_guard lock(mThreadControlMutex);
if (mDiscardedFrames) {
ATRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::waitForZeroPhase));
@@ -233,7 +229,7 @@
}
void RegionSamplingThread::doSample() {
- std::lock_guard lock(mMutex);
+ std::lock_guard lock(mThreadControlMutex);
auto now = std::chrono::nanoseconds(systemTime(SYSTEM_TIME_MONOTONIC));
if (lastSampleTime + mTunables.mSamplingPeriod > now) {
ATRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::idleTimerWaiting));
@@ -254,7 +250,7 @@
}
void RegionSamplingThread::binderDied(const wp<IBinder>& who) {
- std::lock_guard lock(mMutex);
+ std::lock_guard lock(mSamplingMutex);
mDescriptors.erase(who);
}
@@ -315,6 +311,7 @@
void RegionSamplingThread::captureSample() {
ATRACE_CALL();
+ std::lock_guard lock(mSamplingMutex);
if (mDescriptors.empty()) {
return;
@@ -387,19 +384,8 @@
PIXEL_FORMAT_RGBA_8888, 1, usage, "RegionSamplingThread");
}
- // When calling into SF, we post a message into the SF message queue (so the
- // screen capture runs on the main thread). This message blocks until the
- // screenshot is actually captured, but before the capture occurs, the main
- // thread may perform a normal refresh cycle. At the end of this cycle, it
- // can request another sample (because layers changed), which triggers a
- // call into sampleNow. When sampleNow attempts to grab the mutex, we can
- // deadlock.
- //
- // To avoid this, we drop the mutex while we call into SF.
- mMutex.unlock();
bool ignored;
mFlinger.captureScreenCommon(renderArea, traverseLayers, buffer, false, ignored);
- mMutex.lock();
std::vector<Descriptor> activeDescriptors;
for (const auto& descriptor : descriptors) {
@@ -429,15 +415,19 @@
ATRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::noWorkNeeded));
}
-void RegionSamplingThread::threadMain() {
- std::lock_guard lock(mMutex);
+// NO_THREAD_SAFETY_ANALYSIS is because std::unique_lock presently lacks thread safety annotations.
+void RegionSamplingThread::threadMain() NO_THREAD_SAFETY_ANALYSIS {
+ std::unique_lock<std::mutex> lock(mThreadControlMutex);
while (mRunning) {
if (mSampleRequested) {
mSampleRequested = false;
+ lock.unlock();
captureSample();
+ lock.lock();
}
- mCondition.wait(mMutex,
- [this]() REQUIRES(mMutex) { return mSampleRequested || !mRunning; });
+ mCondition.wait(lock, [this]() REQUIRES(mThreadControlMutex) {
+ return mSampleRequested || !mRunning;
+ });
}
}
diff --git a/services/surfaceflinger/RegionSamplingThread.h b/services/surfaceflinger/RegionSamplingThread.h
index 72b2042..08134e6 100644
--- a/services/surfaceflinger/RegionSamplingThread.h
+++ b/services/surfaceflinger/RegionSamplingThread.h
@@ -100,7 +100,7 @@
void binderDied(const wp<IBinder>& who) override;
void checkForStaleLuma();
- void captureSample() REQUIRES(mMutex);
+ void captureSample();
void threadMain();
SurfaceFlinger& mFlinger;
@@ -110,19 +110,18 @@
std::unique_ptr<SamplingOffsetCallback> const mPhaseCallback;
- std::mutex mThreadMutex;
- std::thread mThread GUARDED_BY(mThreadMutex);
+ std::thread mThread;
- std::mutex mMutex;
+ std::mutex mThreadControlMutex;
std::condition_variable_any mCondition;
- bool mRunning GUARDED_BY(mMutex) = true;
- bool mSampleRequested GUARDED_BY(mMutex) = false;
+ bool mRunning GUARDED_BY(mThreadControlMutex) = true;
+ bool mSampleRequested GUARDED_BY(mThreadControlMutex) = false;
+ bool mDiscardedFrames GUARDED_BY(mThreadControlMutex) = false;
+ std::chrono::nanoseconds lastSampleTime GUARDED_BY(mThreadControlMutex);
- std::unordered_map<wp<IBinder>, Descriptor, WpHash> mDescriptors GUARDED_BY(mMutex);
- std::chrono::nanoseconds lastSampleTime GUARDED_BY(mMutex);
- bool mDiscardedFrames GUARDED_BY(mMutex) = false;
-
- sp<GraphicBuffer> mCachedBuffer GUARDED_BY(mMutex) = nullptr;
+ std::mutex mSamplingMutex;
+ std::unordered_map<wp<IBinder>, Descriptor, WpHash> mDescriptors GUARDED_BY(mSamplingMutex);
+ sp<GraphicBuffer> mCachedBuffer GUARDED_BY(mSamplingMutex) = nullptr;
};
} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 13b9238..4d885fb 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -590,7 +590,11 @@
}
void SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
- postMessageAsync(new LambdaMessage([=] { getRenderEngine().deleteTextures(1, &texture); }));
+ std::lock_guard lock(mTexturePoolMutex);
+ // We don't change the pool size, so the fix-up logic in postComposition will decide whether
+ // to actually delete this or not based on mTexturePoolSize
+ mTexturePool.push_back(texture);
+ ATRACE_INT("TexturePoolSize", mTexturePool.size());
}
// Do not call property_set on main thread which will be blocked by init
@@ -695,13 +699,11 @@
ALOGE("Run StartPropertySetThread failed!");
}
- if (mScheduler->isIdleTimerEnabled()) {
- mScheduler->setChangeRefreshRateCallback(
- [this](RefreshRateType type, Scheduler::ConfigEvent event) {
- Mutex::Autolock lock(mStateLock);
- setRefreshRateTo(type, event);
- });
- }
+ mScheduler->setChangeRefreshRateCallback(
+ [this](RefreshRateType type, Scheduler::ConfigEvent event) {
+ Mutex::Autolock lock(mStateLock);
+ setRefreshRateTo(type, event);
+ });
mRefreshRateConfigs.populate(getHwComposer().getConfigs(*display->getId()));
mRefreshRateStats.setConfigMode(getHwComposer().getActiveConfigIndex(*display->getId()));
@@ -2078,12 +2080,18 @@
{
std::lock_guard lock(mTexturePoolMutex);
- const size_t refillCount = mTexturePoolSize - mTexturePool.size();
- if (refillCount > 0) {
+ if (mTexturePool.size() < mTexturePoolSize) {
+ const size_t refillCount = mTexturePoolSize - mTexturePool.size();
const size_t offset = mTexturePool.size();
mTexturePool.resize(mTexturePoolSize);
getRenderEngine().genTextures(refillCount, mTexturePool.data() + offset);
ATRACE_INT("TexturePoolSize", mTexturePool.size());
+ } else if (mTexturePool.size() > mTexturePoolSize) {
+ const size_t deleteCount = mTexturePool.size() - mTexturePoolSize;
+ const size_t offset = mTexturePoolSize;
+ getRenderEngine().deleteTextures(deleteCount, mTexturePool.data() + offset);
+ mTexturePool.resize(mTexturePoolSize);
+ ATRACE_INT("TexturePoolSize", mTexturePool.size());
}
}
@@ -5089,6 +5097,14 @@
ALOGE("Attempting to access SurfaceFlinger with unused code: %u", code);
return PERMISSION_DENIED;
}
+ case CAPTURE_SCREEN_BY_ID: {
+ IPCThreadState* ipc = IPCThreadState::self();
+ const int uid = ipc->getCallingUid();
+ if ((uid == AID_GRAPHICS) || (uid == AID_SYSTEM) || (uid == AID_SHELL)) {
+ return OK;
+ }
+ return PERMISSION_DENIED;
+ }
}
// These codes are used for the IBinder protocol to either interrogate the recipient
@@ -5416,9 +5432,13 @@
// TODO(b/129297325): expose this via developer menu option
n = data.readInt32();
if (n && !mRefreshRateOverlay) {
- std::lock_guard<std::mutex> lock(mActiveConfigLock);
+ RefreshRateType type;
+ {
+ std::lock_guard<std::mutex> lock(mActiveConfigLock);
+ type = mDesiredActiveConfig.type;
+ }
mRefreshRateOverlay = std::make_unique<RefreshRateOverlay>(*this);
- mRefreshRateOverlay->changeRefreshRate(mDesiredActiveConfig.type);
+ mRefreshRateOverlay->changeRefreshRate(type);
} else if (!n) {
mRefreshRateOverlay.reset();
}
@@ -5503,6 +5523,66 @@
useIdentityTransform, outCapturedSecureLayers);
}
+static Dataspace pickDataspaceFromColorMode(const ColorMode colorMode) {
+ switch (colorMode) {
+ case ColorMode::DISPLAY_P3:
+ case ColorMode::BT2100_PQ:
+ case ColorMode::BT2100_HLG:
+ case ColorMode::DISPLAY_BT2020:
+ return Dataspace::DISPLAY_P3;
+ default:
+ return Dataspace::V0_SRGB;
+ }
+}
+
+const sp<DisplayDevice> SurfaceFlinger::getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) {
+ const sp<IBinder> displayToken = getPhysicalDisplayTokenLocked(DisplayId{displayOrLayerStack});
+ if (displayToken) {
+ return getDisplayDeviceLocked(displayToken);
+ }
+ // Couldn't find display by displayId. Try to get display by layerStack since virtual displays
+ // may not have a displayId.
+ for (const auto& [token, display] : mDisplays) {
+ if (display->getLayerStack() == displayOrLayerStack) {
+ return display;
+ }
+ }
+ return nullptr;
+}
+
+status_t SurfaceFlinger::captureScreen(uint64_t displayOrLayerStack, Dataspace* outDataspace,
+ sp<GraphicBuffer>* outBuffer) {
+ sp<DisplayDevice> display;
+ uint32_t width;
+ uint32_t height;
+ ui::Transform::orientation_flags captureOrientation;
+ {
+ Mutex::Autolock _l(mStateLock);
+ display = getDisplayByIdOrLayerStack(displayOrLayerStack);
+ if (!display) {
+ return BAD_VALUE;
+ }
+
+ width = uint32_t(display->getViewport().width());
+ height = uint32_t(display->getViewport().height());
+
+ captureOrientation = fromSurfaceComposerRotation(
+ static_cast<ISurfaceComposer::Rotation>(display->getOrientation()));
+ *outDataspace =
+ pickDataspaceFromColorMode(display->getCompositionDisplay()->getState().colorMode);
+ }
+
+ DisplayRenderArea renderArea(display, Rect(), width, height, *outDataspace, captureOrientation,
+ false /* captureSecureLayers */);
+
+ auto traverseLayers = std::bind(&SurfaceFlinger::traverseLayersInDisplay, this, display,
+ std::placeholders::_1);
+ bool ignored = false;
+ return captureScreenCommon(renderArea, traverseLayers, outBuffer, ui::PixelFormat::RGBA_8888,
+ false /* useIdentityTransform */,
+ ignored /* outCapturedSecureLayers */);
+}
+
status_t SurfaceFlinger::captureLayers(
const sp<IBinder>& layerHandleBinder, sp<GraphicBuffer>* outBuffer,
const Dataspace reqDataspace, const ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 5871774..d9de07b 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -405,6 +405,8 @@
const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
uint32_t reqWidth, uint32_t reqHeight,
bool useIdentityTransform, ISurfaceComposer::Rotation rotation, bool captureSecureLayers) override;
+ status_t captureScreen(uint64_t displayOrLayerStack, ui::Dataspace* outDataspace,
+ sp<GraphicBuffer>* outBuffer) override;
status_t captureLayers(
const sp<IBinder>& parentHandle, sp<GraphicBuffer>* outBuffer,
const ui::Dataspace reqDataspace, const ui::PixelFormat reqPixelFormat,
@@ -636,6 +638,7 @@
status_t captureScreenCommon(RenderArea& renderArea, TraverseLayersFunction traverseLayers,
const sp<GraphicBuffer>& buffer, bool useIdentityTransform,
bool& outCapturedSecureLayers);
+ const sp<DisplayDevice> getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack);
status_t captureScreenImplLocked(const RenderArea& renderArea,
TraverseLayersFunction traverseLayers,
ANativeWindowBuffer* buffer, bool useIdentityTransform,
diff --git a/services/surfaceflinger/TimeStats/TimeStats.h b/services/surfaceflinger/TimeStats/TimeStats.h
index 4e040a3..2bcb568 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.h
+++ b/services/surfaceflinger/TimeStats/TimeStats.h
@@ -41,7 +41,7 @@
virtual void parseArgs(bool asProto, const Vector<String16>& args, std::string& result) = 0;
virtual bool isEnabled() = 0;
- virtual std::string miniDump();
+ virtual std::string miniDump() = 0;
virtual void incrementTotalFrames() = 0;
virtual void incrementMissedFrames() = 0;
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index bebfa6c..7c0ecb3 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -856,7 +856,7 @@
}
static void cleanupInjectedLayers(CompositionTest* test) {
- EXPECT_CALL(*test->mMessageQueue, postMessage(_, 0)).Times(2);
+ EXPECT_CALL(*test->mMessageQueue, postMessage(_, 0)).Times(1);
Base::cleanupInjectedLayers(test);
}
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 613fa13..23506ba 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -1174,6 +1174,11 @@
&properties);
ATRACE_END();
+ if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
+ // Log that the app is hitting software Vulkan implementation
+ android::GraphicsEnv::getInstance().setCpuVulkanInUse();
+ }
+
data->driver_device = dev;
data->driver_version = properties.driverVersion;
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index bc00190..a22f60e 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -222,6 +222,15 @@
window,
&refresh_duration);
}
+ uint64_t get_refresh_duration()
+ {
+ ANativeWindow* window = surface.window.get();
+ native_window_get_refresh_cycle_duration(
+ window,
+ &refresh_duration);
+ return static_cast<uint64_t>(refresh_duration);
+
+ }
Surface& surface;
uint32_t num_images;
@@ -1730,8 +1739,7 @@
Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
VkResult result = VK_SUCCESS;
- pDisplayTimingProperties->refreshDuration =
- static_cast<uint64_t>(swapchain.refresh_duration);
+ pDisplayTimingProperties->refreshDuration = swapchain.get_refresh_duration();
return result;
}