Merge "Avoid deadlock in EventThread::onNewVsyncSchedule" into udc-dev
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 39eb4ab..2ce3fb0 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -7,6 +7,7 @@
rustfmt = --config-path=rustfmt.toml
# Only turn on clang-format check for the following subfolders.
clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
+ cmds/dumpstate/
cmds/idlcli/
cmds/installd/
cmds/servicemanager/
@@ -41,3 +42,4 @@
dumpsys_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "^cmds/dumpsys/"
# bugreports matches both cmds/bugreport and cmds/bugreportz
bugreports_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "^cmds/bugreport"
+binder_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "^libs/binder/"
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index 95f5c03..e66cc41 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -501,6 +501,33 @@
chmod 0440 /sys/kernel/debug/tracing/hyp/events/hyp/hyp_exit/id
chmod 0440 /sys/kernel/tracing/hyp/events/hyp/hyp_exit/id
+# host_hcall event
+ chmod 0660 /sys/kernel/debug/tracing/hyp/events/hyp/host_hcall/enable
+ chmod 0660 /sys/kernel/tracing/hyp/events/hyp/host_hcall/enable
+# TODO(b/249050813): should this be handled in kernel?
+ chmod 0440 /sys/kernel/debug/tracing/hyp/events/hyp/host_hcall/format
+ chmod 0440 /sys/kernel/tracing/hyp/events/hyp/host_hcall/format
+ chmod 0440 /sys/kernel/debug/tracing/hyp/events/hyp/host_hcall/id
+ chmod 0440 /sys/kernel/tracing/hyp/events/hyp/host_hcall/id
+
+# host_smc event
+ chmod 0660 /sys/kernel/debug/tracing/hyp/events/hyp/host_smc/enable
+ chmod 0660 /sys/kernel/tracing/hyp/events/hyp/host_smc/enable
+# TODO(b/249050813): should this be handled in kernel?
+ chmod 0440 /sys/kernel/debug/tracing/hyp/events/hyp/host_smc/format
+ chmod 0440 /sys/kernel/tracing/hyp/events/hyp/host_smc/format
+ chmod 0440 /sys/kernel/debug/tracing/hyp/events/hyp/host_smc/id
+ chmod 0440 /sys/kernel/tracing/hyp/events/hyp/host_smc/id
+
+# host_mem_abort event
+ chmod 0660 /sys/kernel/debug/tracing/hyp/events/hyp/host_mem_abort/enable
+ chmod 0660 /sys/kernel/tracing/hyp/events/hyp/host_mem_abort/enable
+# TODO(b/249050813): should this be handled in kernel?
+ chmod 0440 /sys/kernel/debug/tracing/hyp/events/hyp/host_mem_abort/format
+ chmod 0440 /sys/kernel/tracing/hyp/events/hyp/host_mem_abort/format
+ chmod 0440 /sys/kernel/debug/tracing/hyp/events/hyp/host_mem_abort/id
+ chmod 0440 /sys/kernel/tracing/hyp/events/hyp/host_mem_abort/id
+
on property:persist.debug.atrace.boottrace=1
start boottrace
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 6f84e7c..baf8e42 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -816,6 +816,8 @@
printf("Kernel: ");
DumpFileToFd(STDOUT_FILENO, "", "/proc/version");
printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
+ printf("Bootconfig: ");
+ DumpFileToFd(STDOUT_FILENO, "", "/proc/bootconfig");
printf("Uptime: ");
RunCommandToFd(STDOUT_FILENO, "", {"uptime", "-p"},
CommandOptions::WithTimeout(1).Always().Build());
@@ -1254,7 +1256,8 @@
dumpsys.writeDumpHeader(STDOUT_FILENO, service, priority);
dumpsys.writeDumpFooter(STDOUT_FILENO, service, std::chrono::milliseconds(1));
} else {
- status_t status = dumpsys.startDumpThread(Dumpsys::TYPE_DUMP | Dumpsys::TYPE_PID,
+ status_t status = dumpsys.startDumpThread(Dumpsys::TYPE_DUMP | Dumpsys::TYPE_PID |
+ Dumpsys::TYPE_CLIENTS | Dumpsys::TYPE_THREAD,
service, args);
if (status == OK) {
dumpsys.writeDumpHeader(STDOUT_FILENO, service, priority);
@@ -1273,6 +1276,9 @@
dumpsys.writeDumpFooter(STDOUT_FILENO, service, elapsed_seconds);
bool dump_complete = (status == OK);
dumpsys.stopDumpThread(dump_complete);
+ } else {
+ MYLOGE("Failed to start dump thread for service: %s, status: %d",
+ String8(service).c_str(), status);
}
}
@@ -2066,6 +2072,8 @@
SEC_TO_MSEC(10));
RunDumpsys("DUMPSYS", {"telephony.registry"}, CommandOptions::WithTimeout(90).Build(),
SEC_TO_MSEC(10));
+ RunDumpsys("DUMPSYS", {"isub"}, CommandOptions::WithTimeout(90).Build(),
+ SEC_TO_MSEC(10));
RunDumpsys("DUMPSYS", {"telecom"}, CommandOptions::WithTimeout(90).Build(),
SEC_TO_MSEC(10));
if (include_sensitive_info) {
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 794750f..1693ed5 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -1942,7 +1942,8 @@
RUNTIME_NATIVE_BOOT_NAMESPACE,
ENABLE_JITZYGOTE_IMAGE,
/*default_value=*/ "");
- bool use_jitzygote_image = jitzygote_flag == "true" || IsBootClassPathProfilingEnable();
+ bool compile_without_image = jitzygote_flag == "true" || IsBootClassPathProfilingEnable() ||
+ force_compile_without_image();
// Decide whether to use dex2oat64.
bool use_dex2oat64 = false;
@@ -1964,7 +1965,7 @@
in_dex, in_vdex, dex_metadata, reference_profile, class_loader_context,
join_fds(context_input_fds), swap_fd.get(), instruction_set, compiler_filter,
debuggable, boot_complete, for_restore, target_sdk_version,
- enable_hidden_api_checks, generate_compact_dex, use_jitzygote_image,
+ enable_hidden_api_checks, generate_compact_dex, compile_without_image,
background_job_compile, compilation_reason);
bool cancelled = false;
diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp
index b5bc28c..4f691c9 100644
--- a/cmds/installd/installd.cpp
+++ b/cmds/installd/installd.cpp
@@ -65,6 +65,10 @@
return create_cache_path_default(path, src, instruction_set);
}
+bool force_compile_without_image() {
+ return false;
+}
+
static bool initialize_globals() {
return init_globals_from_data_and_root();
}
diff --git a/cmds/installd/installd_deps.h b/cmds/installd/installd_deps.h
index 5093178..0d0a7fa 100644
--- a/cmds/installd/installd_deps.h
+++ b/cmds/installd/installd_deps.h
@@ -57,6 +57,9 @@
const char *src,
const char *instruction_set);
+// If true, pass "--force-jit-zygote" to dex2oat (i.e., compile without a boot image).
+extern bool force_compile_without_image();
+
} // namespace installd
} // namespace android
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index bf2c0d1..7cabdb0 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -711,6 +711,11 @@
return true;
}
+bool force_compile_without_image() {
+ // We don't have a boot image anyway. Compile without a boot image.
+ return true;
+}
+
static int log_callback(int type, const char *fmt, ...) {
va_list ap;
int priority;
diff --git a/cmds/installd/tests/installd_cache_test.cpp b/cmds/installd/tests/installd_cache_test.cpp
index 4976646..a00c2c7 100644
--- a/cmds/installd/tests/installd_cache_test.cpp
+++ b/cmds/installd/tests/installd_cache_test.cpp
@@ -67,6 +67,10 @@
return false;
}
+bool force_compile_without_image() {
+ return false;
+}
+
static void mkdir(const char* path) {
const std::string fullPath = StringPrintf("/data/local/tmp/user/0/%s", path);
::mkdir(fullPath.c_str(), 0755);
diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp
index 5c4e1a4..c4071c6 100644
--- a/cmds/installd/tests/installd_dexopt_test.cpp
+++ b/cmds/installd/tests/installd_dexopt_test.cpp
@@ -73,6 +73,10 @@
return create_cache_path_default(path, src, instruction_set);
}
+bool force_compile_without_image() {
+ return false;
+}
+
static void run_cmd(const std::string& cmd) {
system(cmd.c_str());
}
@@ -199,6 +203,10 @@
std::string secondary_dex_de_;
virtual void SetUp() {
+ if (base::GetBoolProperty("dalvik.vm.useartservice", false)) {
+ GTEST_SKIP() << "Skipping legacy dexopt tests when ART Service is enabled";
+ }
+
setenv("ANDROID_LOG_TAGS", "*:v", 1);
android::base::InitLogging(nullptr);
// Initialize the globals holding the file system main paths (/data/, /system/ etc..).
@@ -219,6 +227,10 @@
}
virtual void TearDown() {
+ if (base::GetBoolProperty("dalvik.vm.useartservice", false)) {
+ GTEST_SKIP();
+ }
+
if (!kDebug) {
service_->controlDexOptBlocking(false);
service_->destroyAppData(
@@ -962,6 +974,10 @@
class PrimaryDexReCompilationTest : public DexoptTest {
public:
virtual void SetUp() {
+ if (base::GetBoolProperty("dalvik.vm.useartservice", false)) {
+ GTEST_SKIP() << "Skipping legacy dexopt tests when ART Service is enabled";
+ }
+
DexoptTest::SetUp();
CompilePrimaryDexOk("verify",
DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
@@ -976,6 +992,10 @@
}
virtual void TearDown() {
+ if (base::GetBoolProperty("dalvik.vm.useartservice", false)) {
+ GTEST_SKIP();
+ }
+
first_compilation_odex_fd_.reset(-1);
first_compilation_vdex_fd_.reset(-1);
DexoptTest::TearDown();
@@ -998,6 +1018,10 @@
class ReconcileTest : public DexoptTest {
virtual void SetUp() {
+ if (base::GetBoolProperty("dalvik.vm.useartservice", false)) {
+ GTEST_SKIP() << "Skipping legacy dexopt tests when ART Service is enabled";
+ }
+
DexoptTest::SetUp();
CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
/*binder_ok*/ true, /*compile_ok*/ true);
@@ -1063,6 +1087,10 @@
static constexpr const char* kPrimaryProfile = "primary.prof";
virtual void SetUp() {
+ if (base::GetBoolProperty("dalvik.vm.useartservice", false)) {
+ GTEST_SKIP() << "Skipping legacy dexopt tests when ART Service is enabled";
+ }
+
DexoptTest::SetUp();
cur_profile_ = create_current_profile_path(
kTestUserId, package_name_, kPrimaryProfile, /*is_secondary_dex*/ false);
@@ -1436,6 +1464,9 @@
std::vector<int64_t> extra_ce_data_inodes_;
virtual void SetUp() {
+ if (base::GetBoolProperty("dalvik.vm.useartservice", false)) {
+ GTEST_SKIP() << "Skipping legacy dexopt tests when ART Service is enabled";
+ }
ProfileTest::SetUp();
intial_android_profiles_dir = android_profiles_dir;
@@ -1449,6 +1480,10 @@
}
virtual void TearDown() {
+ if (base::GetBoolProperty("dalvik.vm.useartservice", false)) {
+ GTEST_SKIP();
+ }
+
android_profiles_dir = intial_android_profiles_dir;
deleteAppProfilesForBootMerge();
ProfileTest::TearDown();
diff --git a/cmds/installd/tests/installd_service_test.cpp b/cmds/installd/tests/installd_service_test.cpp
index f86f1d5..858a92c 100644
--- a/cmds/installd/tests/installd_service_test.cpp
+++ b/cmds/installd/tests/installd_service_test.cpp
@@ -113,6 +113,10 @@
return create_cache_path_default(path, src, instruction_set);
}
+bool force_compile_without_image() {
+ return false;
+}
+
static std::string get_full_path(const std::string& path) {
return StringPrintf("%s/%s", kTestPath.c_str(), path.c_str());
}
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 4da0cd6..d4ce466 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -360,6 +360,10 @@
}
#endif // !VENDORSERVICEMANAGER
+ if ((dumpPriority & DUMP_FLAG_PRIORITY_ALL) == 0) {
+ ALOGW("Dump flag priority is not set when adding %s", name.c_str());
+ }
+
// implicitly unlinked when the binder is removed
if (binder->remoteBinder() != nullptr &&
binder->linkToDeath(sp<ServiceManager>::fromExisting(this)) != OK) {
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index bdd5172..754e7b2 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -77,6 +77,12 @@
}
prebuilt_etc {
+ name: "android.hardware.context_hub.prebuilt.xml",
+ src: "android.hardware.context_hub.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
name: "android.hardware.ethernet.prebuilt.xml",
src: "android.hardware.ethernet.xml",
defaults: ["frameworks_native_data_etc_defaults"],
@@ -107,30 +113,102 @@
}
prebuilt_etc {
+ name: "android.hardware.sensor.accelerometer_limited_axes_uncalibrated.prebuilt.xml",
+ src: "android.hardware.sensor.accelerometer_limited_axes_uncalibrated.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+ name: "android.hardware.sensor.accelerometer_limited_axes.prebuilt.xml",
+ src: "android.hardware.sensor.accelerometer_limited_axes.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+ name: "android.hardware.sensor.accelerometer.prebuilt.xml",
+ src: "android.hardware.sensor.accelerometer.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
name: "android.hardware.sensor.ambient_temperature.prebuilt.xml",
src: "android.hardware.sensor.ambient_temperature.xml",
defaults: ["frameworks_native_data_etc_defaults"],
}
prebuilt_etc {
+ name: "android.hardware.sensor.assist.prebuilt.xml",
+ src: "android.hardware.sensor.assist.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
name: "android.hardware.sensor.barometer.prebuilt.xml",
src: "android.hardware.sensor.barometer.xml",
defaults: ["frameworks_native_data_etc_defaults"],
}
prebuilt_etc {
+ name: "android.hardware.sensor.compass.prebuilt.xml",
+ src: "android.hardware.sensor.compass.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
name: "android.hardware.sensor.dynamic.head_tracker.prebuilt.xml",
src: "android.hardware.sensor.dynamic.head_tracker.xml",
defaults: ["frameworks_native_data_etc_defaults"],
}
prebuilt_etc {
+ name: "android.hardware.sensor.gyroscope_limited_axes_uncalibrated.prebuilt.xml",
+ src: "android.hardware.sensor.gyroscope_limited_axes_uncalibrated.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+ name: "android.hardware.sensor.gyroscope_limited_axes.prebuilt.xml",
+ src: "android.hardware.sensor.gyroscope_limited_axes.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
name: "android.hardware.sensor.gyroscope.prebuilt.xml",
src: "android.hardware.sensor.gyroscope.xml",
defaults: ["frameworks_native_data_etc_defaults"],
}
prebuilt_etc {
+ name: "android.hardware.sensor.heading.prebuilt.xml",
+ src: "android.hardware.sensor.heading.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+ name: "android.hardware.sensor.heartrate.ecg.prebuilt.xml",
+ src: "android.hardware.sensor.heartrate.ecg.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+ name: "android.hardware.sensor.heartrate.fitness.prebuilt.xml",
+ src: "android.hardware.sensor.heartrate.fitness.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+ name: "android.hardware.sensor.heartrate.prebuilt.xml",
+ src: "android.hardware.sensor.heartrate.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+ name: "android.hardware.sensor.hifi_sensors.prebuilt.xml",
+ src: "android.hardware.sensor.hifi_sensors.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
name: "android.hardware.sensor.hinge_angle.prebuilt.xml",
src: "android.hardware.sensor.hinge_angle.xml",
defaults: ["frameworks_native_data_etc_defaults"],
@@ -155,6 +233,18 @@
}
prebuilt_etc {
+ name: "android.hardware.sensor.stepcounter.prebuilt.xml",
+ src: "android.hardware.sensor.stepcounter.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+ name: "android.hardware.sensor.stepdetector.prebuilt.xml",
+ src: "android.hardware.sensor.stepdetector.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
name: "android.hardware.telephony.gsm.prebuilt.xml",
src: "android.hardware.telephony.gsm.xml",
defaults: ["frameworks_native_data_etc_defaults"],
@@ -167,6 +257,12 @@
}
prebuilt_etc {
+ name: "android.hardware.telephony.satellite.prebuilt.xml",
+ src: "android.hardware.telephony.satellite.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
name: "android.hardware.usb.accessory.prebuilt.xml",
src: "android.hardware.usb.accessory.xml",
defaults: ["frameworks_native_data_etc_defaults"],
diff --git a/data/etc/android.hardware.telephony.satellite.xml b/data/etc/android.hardware.telephony.satellite.xml
new file mode 100644
index 0000000..d36c958
--- /dev/null
+++ b/data/etc/android.hardware.telephony.satellite.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 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.
+-->
+
+<!-- Feature for devices that support satellite communication via satellite vendor service APIs. -->
+<permissions>
+ <feature name="android.hardware.telephony.satellite" />
+</permissions>
diff --git a/include/android/surface_control.h b/include/android/surface_control.h
index e4926a6..daeebec 100644
--- a/include/android/surface_control.h
+++ b/include/android/surface_control.h
@@ -555,6 +555,8 @@
* range in use.
*
* Must be finite && >= 1.0f
+ *
+ * Available since API level 34.
*/
void ASurfaceTransaction_setExtendedRangeBrightness(ASurfaceTransaction* transaction,
ASurfaceControl* surface_control,
diff --git a/include/input/PropertyMap.h b/include/input/PropertyMap.h
index 18ce16d..2e44142 100644
--- a/include/input/PropertyMap.h
+++ b/include/input/PropertyMap.h
@@ -19,6 +19,7 @@
#include <android-base/result.h>
#include <utils/Tokenizer.h>
+#include <optional>
#include <string>
#include <unordered_map>
#include <unordered_set>
@@ -63,15 +64,15 @@
/* Returns a set of all property keys starting with the given prefix. */
std::unordered_set<std::string> getKeysWithPrefix(const std::string& prefix) const;
- /* Gets the value of a property and parses it.
- * Returns true and sets outValue if the key was found and its value was parsed successfully.
- * Otherwise returns false and does not modify outValue. (Also logs a warning.)
+ /* Gets the value of a property and parses it. Returns nullopt if the key wasn't found or
+ * couldn't be parsed as the requested type. (Warnings are also logged in the case of parsing
+ * failures.)
*/
- bool tryGetProperty(const std::string& key, std::string& outValue) const;
- bool tryGetProperty(const std::string& key, bool& outValue) const;
- bool tryGetProperty(const std::string& key, int32_t& outValue) const;
- bool tryGetProperty(const std::string& key, float& outValue) const;
- bool tryGetProperty(const std::string& key, double& outValue) const;
+ std::optional<std::string> getString(const std::string& key) const;
+ std::optional<bool> getBool(const std::string& key) const;
+ std::optional<int32_t> getInt(const std::string& key) const;
+ std::optional<float> getFloat(const std::string& key) const;
+ std::optional<double> getDouble(const std::string& key) const;
/* Adds all values from the specified property map. */
void addAll(const PropertyMap* map);
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 6a354b4..49dd9c7 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -191,6 +191,7 @@
"google-*",
"misc-*",
"performance*",
+ "-performance-move-const-arg", // b/273486801
"portability*",
],
}
@@ -354,6 +355,7 @@
cc_library_static {
name: "libbinder_rpc_no_kernel",
+ vendor_available: true,
defaults: [
"libbinder_common_defaults",
"libbinder_android_defaults",
@@ -406,6 +408,7 @@
cc_defaults {
name: "libbinder_tls_defaults",
defaults: ["libbinder_tls_shared_deps"],
+ vendor_available: true,
host_supported: true,
header_libs: [
@@ -432,7 +435,7 @@
defaults: ["libbinder_tls_defaults"],
}
-cc_library_shared {
+cc_library {
name: "libbinder_trusty",
vendor: true,
srcs: [
diff --git a/libs/binder/IActivityManager.cpp b/libs/binder/IActivityManager.cpp
index 08169f5..ebdaa4c 100644
--- a/libs/binder/IActivityManager.cpp
+++ b/libs/binder/IActivityManager.cpp
@@ -131,6 +131,53 @@
*outResult = reply.readInt32();
return NO_ERROR;
}
+
+ virtual status_t logFgsApiBegin(int32_t apiType, int32_t appUid, int32_t appPid) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IActivityManager::getInterfaceDescriptor());
+ data.writeInt32(apiType);
+ data.writeInt32(appUid);
+ data.writeInt32(appPid);
+ status_t err = remote()->transact(LOG_FGS_API_BEGIN_TRANSACTION, data, &reply);
+ if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) {
+ ALOGD("FGS Logger Transaction failed");
+ ALOGD("%d", err);
+ return err;
+ }
+ return NO_ERROR;
+ }
+
+ virtual status_t logFgsApiEnd(int32_t apiType, int32_t appUid, int32_t appPid) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IActivityManager::getInterfaceDescriptor());
+ data.writeInt32(apiType);
+ data.writeInt32(appUid);
+ data.writeInt32(appPid);
+ status_t err = remote()->transact(LOG_FGS_API_END_TRANSACTION, data, &reply);
+ if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) {
+ ALOGD("FGS Logger Transaction failed");
+ ALOGD("%d", err);
+ return err;
+ }
+ return NO_ERROR;
+ }
+
+ virtual status_t logFgsApiStateChanged(int32_t apiType, int32_t state, int32_t appUid,
+ int32_t appPid) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IActivityManager::getInterfaceDescriptor());
+ data.writeInt32(apiType);
+ data.writeInt32(state);
+ data.writeInt32(appUid);
+ data.writeInt32(appPid);
+ status_t err = remote()->transact(LOG_FGS_API_BEGIN_TRANSACTION, data, &reply);
+ if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) {
+ ALOGD("FGS Logger Transaction failed");
+ ALOGD("%d", err);
+ return err;
+ }
+ return NO_ERROR;
+ }
};
// ------------------------------------------------------------------------------------
diff --git a/libs/binder/RpcTransportTipcAndroid.cpp b/libs/binder/RpcTransportTipcAndroid.cpp
index 8b3ddfb..d5a6da2 100644
--- a/libs/binder/RpcTransportTipcAndroid.cpp
+++ b/libs/binder/RpcTransportTipcAndroid.cpp
@@ -54,7 +54,7 @@
}
LOG_RPC_DETAIL("RpcTransport poll(): %s", strerror(savedErrno));
- return -savedErrno;
+ return adjustStatus(-savedErrno);
}
if (pfd.revents & POLLNVAL) {
@@ -87,8 +87,10 @@
"File descriptors are not supported on Trusty yet");
return TEMP_FAILURE_RETRY(tipc_send(mSocket.fd.get(), iovs, niovs, nullptr, 0));
};
- return interruptableReadOrWrite(mSocket, fdTrigger, iovs, niovs, writeFn, "tipc_send",
- POLLOUT, altPoll);
+
+ status_t status = interruptableReadOrWrite(mSocket, fdTrigger, iovs, niovs, writeFn,
+ "tipc_send", POLLOUT, altPoll);
+ return adjustStatus(status);
}
status_t interruptableReadFully(
@@ -121,13 +123,26 @@
return processSize;
};
- return interruptableReadOrWrite(mSocket, fdTrigger, iovs, niovs, readFn, "read", POLLIN,
- altPoll);
+
+ status_t status = interruptableReadOrWrite(mSocket, fdTrigger, iovs, niovs, readFn, "read",
+ POLLIN, altPoll);
+ return adjustStatus(status);
}
bool isWaiting() override { return mSocket.isInPollingState(); }
private:
+ status_t adjustStatus(status_t status) {
+ if (status == -ENOTCONN) {
+ // TIPC returns ENOTCONN on disconnect, but that's basically
+ // the same as DEAD_OBJECT and the latter is the common libbinder
+ // error code for dead connections
+ return DEAD_OBJECT;
+ }
+
+ return status;
+ }
+
status_t fillReadBuffer() {
if (mReadBufferPos < mReadBufferSize) {
return OK;
@@ -167,7 +182,7 @@
continue;
} else {
LOG_RPC_DETAIL("RpcTransport fillBuffer(): %s", strerror(savedErrno));
- return -savedErrno;
+ return adjustStatus(-savedErrno);
}
} else {
mReadBufferSize = static_cast<size_t>(processSize);
diff --git a/libs/binder/include_activitymanager/binder/IActivityManager.h b/libs/binder/include_activitymanager/binder/IActivityManager.h
index 4632b2e..20d12ae 100644
--- a/libs/binder/include_activitymanager/binder/IActivityManager.h
+++ b/libs/binder/include_activitymanager/binder/IActivityManager.h
@@ -42,6 +42,10 @@
const pid_t pid,
const uid_t uid,
int32_t* outResult) = 0;
+ virtual status_t logFgsApiBegin(int32_t apiType, int32_t appUid, int32_t appPid) = 0;
+ virtual status_t logFgsApiEnd(int32_t apiType, int32_t appUid, int32_t appPid) = 0;
+ virtual status_t logFgsApiStateChanged(int32_t apiType, int32_t state, int32_t appUid,
+ int32_t appPid) = 0;
enum {
OPEN_CONTENT_URI_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
@@ -50,6 +54,9 @@
IS_UID_ACTIVE_TRANSACTION,
GET_UID_PROCESS_STATE_TRANSACTION,
CHECK_PERMISSION_TRANSACTION,
+ LOG_FGS_API_BEGIN_TRANSACTION,
+ LOG_FGS_API_END_TRANSACTION,
+ LOG_FGS_API_STATE_CHANGED_TRANSACTION
};
};
diff --git a/libs/binder/ndk/include_platform/android/binder_manager.h b/libs/binder/ndk/include_platform/android/binder_manager.h
index 43159d8..89fd7a3 100644
--- a/libs/binder/ndk/include_platform/android/binder_manager.h
+++ b/libs/binder/ndk/include_platform/android/binder_manager.h
@@ -56,12 +56,12 @@
*
* \param binder object to register globally with the service manager.
* \param instance identifier of the service. This will be used to lookup the service.
- * \param flag an AServiceManager_AddServiceFlag enum to denote how the service should be added.
+ * \param flags an AServiceManager_AddServiceFlag enum to denote how the service should be added.
*
* \return EX_NONE on success.
*/
-__attribute__((warn_unused_result)) binder_exception_t AServiceManager_addServiceWithFlag(
- AIBinder* binder, const char* instance, const AServiceManager_AddServiceFlag flag)
+__attribute__((warn_unused_result)) binder_exception_t AServiceManager_addServiceWithFlags(
+ AIBinder* binder, const char* instance, const AServiceManager_AddServiceFlag flags)
__INTRODUCED_IN(34);
/**
diff --git a/libs/binder/ndk/include_platform/android/binder_process.h b/libs/binder/ndk/include_platform/android/binder_process.h
index ffcad55..3fbe90d 100644
--- a/libs/binder/ndk/include_platform/android/binder_process.h
+++ b/libs/binder/ndk/include_platform/android/binder_process.h
@@ -32,7 +32,7 @@
* Do not use this from a library. Apps setup their own threadpools, and otherwise, the main
* function should be responsible for configuring the threadpool for the entire application.
*/
-void ABinderProcess_startThreadPool();
+void ABinderProcess_startThreadPool(void);
/**
* This sets the maximum number of threads that can be started in the threadpool. By default, after
* startThreadPool is called, this is 15. If it is called additional times, it will only prevent
@@ -48,7 +48,7 @@
* you should use this in a library to abort if the threadpool is not started.
* Programs should configure binder threadpools once at the beginning.
*/
-bool ABinderProcess_isThreadPoolStarted();
+bool ABinderProcess_isThreadPoolStarted(void);
/**
* This adds the current thread to the threadpool. This may cause the threadpool to exceed the
* maximum size.
@@ -56,7 +56,7 @@
* Do not use this from a library. Apps setup their own threadpools, and otherwise, the main
* function should be responsible for configuring the threadpool for the entire application.
*/
-void ABinderProcess_joinThreadPool();
+void ABinderProcess_joinThreadPool(void);
/**
* This gives you an fd to wait on. Whenever data is available on the fd,
@@ -79,6 +79,6 @@
*
* \return STATUS_OK on success
*/
-__attribute__((weak)) binder_status_t ABinderProcess_handlePolledCommands() __INTRODUCED_IN(31);
+__attribute__((weak)) binder_status_t ABinderProcess_handlePolledCommands(void) __INTRODUCED_IN(31);
__END_DECLS
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 1078fb2..1c5f79f 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -158,7 +158,7 @@
AServiceManager_getUpdatableApexName; # systemapi
AServiceManager_registerForServiceNotifications; # systemapi llndk
AServiceManager_NotificationRegistration_delete; # systemapi llndk
- AServiceManager_addServiceWithFlag; # systemapi llndk
+ AServiceManager_addServiceWithFlags; # systemapi llndk
};
LIBBINDER_NDK_PLATFORM {
diff --git a/libs/binder/ndk/process.cpp b/libs/binder/ndk/process.cpp
index bc6610e..0fea57b 100644
--- a/libs/binder/ndk/process.cpp
+++ b/libs/binder/ndk/process.cpp
@@ -24,17 +24,17 @@
using ::android::IPCThreadState;
using ::android::ProcessState;
-void ABinderProcess_startThreadPool() {
+void ABinderProcess_startThreadPool(void) {
ProcessState::self()->startThreadPool();
ProcessState::self()->giveThreadPoolName();
}
bool ABinderProcess_setThreadPoolMaxThreadCount(uint32_t numThreads) {
return ProcessState::self()->setThreadPoolMaxThreadCount(numThreads) == 0;
}
-bool ABinderProcess_isThreadPoolStarted() {
+bool ABinderProcess_isThreadPoolStarted(void) {
return ProcessState::self()->isThreadPoolStarted();
}
-void ABinderProcess_joinThreadPool() {
+void ABinderProcess_joinThreadPool(void) {
IPCThreadState::self()->joinThreadPool();
}
@@ -42,6 +42,6 @@
return IPCThreadState::self()->setupPolling(fd);
}
-binder_status_t ABinderProcess_handlePolledCommands() {
+binder_status_t ABinderProcess_handlePolledCommands(void) {
return IPCThreadState::self()->handlePolledCommands();
}
diff --git a/libs/binder/ndk/service_manager.cpp b/libs/binder/ndk/service_manager.cpp
index 84da459..2977786 100644
--- a/libs/binder/ndk/service_manager.cpp
+++ b/libs/binder/ndk/service_manager.cpp
@@ -42,15 +42,15 @@
return PruneException(exception);
}
-binder_exception_t AServiceManager_addServiceWithFlag(AIBinder* binder, const char* instance,
- const AServiceManager_AddServiceFlag flag) {
+binder_exception_t AServiceManager_addServiceWithFlags(AIBinder* binder, const char* instance,
+ const AServiceManager_AddServiceFlag flags) {
if (binder == nullptr || instance == nullptr) {
return EX_ILLEGAL_ARGUMENT;
}
sp<IServiceManager> sm = defaultServiceManager();
- bool allowIsolated = flag & AServiceManager_AddServiceFlag::ADD_SERVICE_ALLOW_ISOLATED;
+ bool allowIsolated = flags & AServiceManager_AddServiceFlag::ADD_SERVICE_ALLOW_ISOLATED;
status_t exception = sm->addService(String16(instance), binder->getBinder(), allowIsolated);
return PruneException(exception);
}
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index 882f1d6..cefc42f 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -51,6 +51,7 @@
constexpr char kLazyBinderNdkUnitTestService[] = "LazyBinderNdkUnitTest";
constexpr char kForcePersistNdkUnitTestService[] = "ForcePersistNdkUnitTestService";
constexpr char kActiveServicesNdkUnitTestService[] = "ActiveServicesNdkUnitTestService";
+constexpr char kBinderNdkUnitTestServiceFlagged[] = "BinderNdkUnitTestFlagged";
constexpr unsigned int kShutdownWaitTime = 11;
constexpr uint64_t kContextTestValue = 0xb4e42fb4d9a1d715;
@@ -158,6 +159,24 @@
return 1; // should not return
}
+int generatedFlaggedService(const AServiceManager_AddServiceFlag flags, const char* instance) {
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+ auto service = ndk::SharedRefBase::make<MyBinderNdkUnitTest>();
+ auto binder = service->asBinder();
+
+ binder_exception_t exception =
+ AServiceManager_addServiceWithFlags(binder.get(), instance, flags);
+
+ if (exception != EX_NONE) {
+ LOG(FATAL) << "Could not register: " << exception << " " << instance;
+ }
+
+ ABinderProcess_joinThreadPool();
+
+ return 1; // should not return
+}
+
// manually-written parceling class considered bad practice
class MyFoo : public IFoo {
binder_status_t doubleNumber(int32_t in, int32_t* out) override {
@@ -847,6 +866,12 @@
EXPECT_EQ("CMD", shellCmdToString(testService, {"C", "M", "D"}));
}
+TEST(NdkBinder, FlaggedServiceAccessible) {
+ static const sp<android::IServiceManager> sm(android::defaultServiceManager());
+ sp<IBinder> testService = sm->getService(String16(kBinderNdkUnitTestServiceFlagged));
+ ASSERT_NE(nullptr, testService);
+}
+
TEST(NdkBinder, GetClassInterfaceDescriptor) {
ASSERT_STREQ(IFoo::kIFooDescriptor, AIBinder_Class_getDescriptor(IFoo::kClass));
}
@@ -901,6 +926,13 @@
prctl(PR_SET_PDEATHSIG, SIGHUP);
return generatedService();
}
+ if (fork() == 0) {
+ prctl(PR_SET_PDEATHSIG, SIGHUP);
+ // We may want to change this flag to be more generic ones for the future
+ AServiceManager_AddServiceFlag test_flags =
+ AServiceManager_AddServiceFlag::ADD_SERVICE_ALLOW_ISOLATED;
+ return generatedFlaggedService(test_flags, kBinderNdkUnitTestServiceFlagged);
+ }
ABinderProcess_setThreadPoolMaxThreadCount(1); // to receive death notifications/callbacks
ABinderProcess_startThreadPool();
diff --git a/libs/binder/rust/src/parcel/parcelable.rs b/libs/binder/rust/src/parcel/parcelable.rs
index 6f4c375..4b658fc 100644
--- a/libs/binder/rust/src/parcel/parcelable.rs
+++ b/libs/binder/rust/src/parcel/parcelable.rs
@@ -771,7 +771,13 @@
#[macro_export]
macro_rules! impl_serialize_for_parcelable {
($parcelable:ident) => {
- impl $crate::binder_impl::Serialize for $parcelable {
+ $crate::impl_serialize_for_parcelable!($parcelable < >);
+ };
+ ($parcelable:ident < $( $param:ident ),* , >) => {
+ $crate::impl_serialize_for_parcelable!($parcelable < $($param),* >);
+ };
+ ($parcelable:ident < $( $param:ident ),* > ) => {
+ impl < $($param),* > $crate::binder_impl::Serialize for $parcelable < $($param),* > {
fn serialize(
&self,
parcel: &mut $crate::binder_impl::BorrowedParcel<'_>,
@@ -780,9 +786,9 @@
}
}
- impl $crate::binder_impl::SerializeArray for $parcelable {}
+ impl < $($param),* > $crate::binder_impl::SerializeArray for $parcelable < $($param),* > {}
- impl $crate::binder_impl::SerializeOption for $parcelable {
+ impl < $($param),* > $crate::binder_impl::SerializeOption for $parcelable < $($param),* > {
fn serialize_option(
this: Option<&Self>,
parcel: &mut $crate::binder_impl::BorrowedParcel<'_>,
@@ -808,7 +814,13 @@
#[macro_export]
macro_rules! impl_deserialize_for_parcelable {
($parcelable:ident) => {
- impl $crate::binder_impl::Deserialize for $parcelable {
+ $crate::impl_deserialize_for_parcelable!($parcelable < >);
+ };
+ ($parcelable:ident < $( $param:ident ),* , >) => {
+ $crate::impl_deserialize_for_parcelable!($parcelable < $($param),* >);
+ };
+ ($parcelable:ident < $( $param:ident ),* > ) => {
+ impl < $($param: Default),* > $crate::binder_impl::Deserialize for $parcelable < $($param),* > {
fn deserialize(
parcel: &$crate::binder_impl::BorrowedParcel<'_>,
) -> std::result::Result<Self, $crate::StatusCode> {
@@ -830,9 +842,9 @@
}
}
- impl $crate::binder_impl::DeserializeArray for $parcelable {}
+ impl < $($param: Default),* > $crate::binder_impl::DeserializeArray for $parcelable < $($param),* > {}
- impl $crate::binder_impl::DeserializeOption for $parcelable {
+ impl < $($param: Default),* > $crate::binder_impl::DeserializeOption for $parcelable < $($param),* > {
fn deserialize_option(
parcel: &$crate::binder_impl::BorrowedParcel<'_>,
) -> std::result::Result<Option<Self>, $crate::StatusCode> {
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 0f0d64a..61a047b 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -138,6 +138,7 @@
aidl_interface {
name: "binderRpcTestIface",
+ vendor_available: true,
host_supported: true,
unstable: true,
srcs: [
@@ -159,6 +160,7 @@
cc_library_static {
name: "libbinder_tls_test_utils",
host_supported: true,
+ vendor_available: true,
target: {
darwin: {
enabled: false,
@@ -441,6 +443,37 @@
}
cc_test {
+ name: "binderRpcToTrustyTest",
+ vendor: true,
+ host_supported: false,
+ defaults: [
+ "binderRpcTest_common_defaults",
+ "binderRpcTest_static_defaults",
+ ],
+
+ srcs: [
+ "binderRpcTest.cpp",
+ "binderRpcTestCommon.cpp",
+ "binderRpcUniversalTests.cpp",
+ ],
+
+ cflags: [
+ "-DBINDER_RPC_TO_TRUSTY_TEST",
+ ],
+
+ static_libs: [
+ // We want to link libbinder statically so we can push the binary
+ // to the device for testing independently of the library
+ "libbinder_rpc_no_kernel",
+ "libbinder_trusty",
+ "libtrusty",
+ ],
+
+ test_suites: ["device-tests"],
+ require_root: true,
+}
+
+cc_test {
name: "RpcTlsUtilsTest",
host_supported: true,
target: {
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index efc314b..504b3ce 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -28,10 +28,10 @@
#include <sys/prctl.h>
#include <sys/socket.h>
-#ifdef __ANDROID_VENDOR__
+#ifdef BINDER_RPC_TO_TRUSTY_TEST
#include <binder/RpcTransportTipcAndroid.h>
#include <trusty/tipc.h>
-#endif // __ANDROID_VENDOR__
+#endif // BINDER_RPC_TO_TRUSTY_TEST
#include "binderRpcTestCommon.h"
#include "binderRpcTestFixture.h"
@@ -50,7 +50,7 @@
constexpr bool kEnableSharedLibs = true;
#endif
-#ifdef __ANDROID_VENDOR__
+#ifdef BINDER_RPC_TO_TRUSTY_TEST
constexpr char kTrustyIpcDevice[] = "/dev/trusty-ipc-dev0";
#endif
@@ -214,6 +214,7 @@
return serverFd;
}
+#ifndef BINDER_RPC_TO_TRUSTY_TEST
static base::unique_fd connectToUnixBootstrap(const RpcTransportFd& transportFd) {
base::unique_fd sockClient, sockServer;
if (!base::Socketpair(SOCK_STREAM, &sockClient, &sockServer)) {
@@ -232,22 +233,10 @@
}
return std::move(sockClient);
}
+#endif // BINDER_RPC_TO_TRUSTY_TEST
-std::string BinderRpc::PrintParamInfo(const testing::TestParamInfo<ParamType>& info) {
- auto [type, security, clientVersion, serverVersion, singleThreaded, noKernel] = info.param;
- auto ret = PrintToString(type) + "_" + newFactory(security)->toCString() + "_clientV" +
- std::to_string(clientVersion) + "_serverV" + std::to_string(serverVersion);
- if (singleThreaded) {
- ret += "_single_threaded";
- } else {
- ret += "_multi_threaded";
- }
- if (noKernel) {
- ret += "_no_kernel";
- } else {
- ret += "_with_kernel";
- }
- return ret;
+std::unique_ptr<RpcTransportCtxFactory> BinderRpc::newFactory(RpcSecurity rpcSecurity) {
+ return newTlsFactory(rpcSecurity);
}
// This creates a new process serving an interface on a certain number of
@@ -321,13 +310,13 @@
for (size_t i = 0; i < options.numSessions; i++) {
std::unique_ptr<RpcTransportCtxFactory> factory;
if (socketType == SocketType::TIPC) {
-#ifdef __ANDROID_VENDOR__
+#ifdef BINDER_RPC_TO_TRUSTY_TEST
factory = RpcTransportCtxFactoryTipcAndroid::make();
#else
LOG_ALWAYS_FATAL("TIPC socket type only supported on vendor");
#endif
} else {
- factory = newFactory(rpcSecurity, certVerifier);
+ factory = newTlsFactory(rpcSecurity, certVerifier);
}
sessions.emplace_back(RpcSession::make(std::move(factory)));
}
@@ -391,11 +380,18 @@
break;
case SocketType::TIPC:
status = session->setupPreconnectedClient({}, [=]() {
-#ifdef __ANDROID_VENDOR__
+#ifdef BINDER_RPC_TO_TRUSTY_TEST
auto port = trustyIpcPort(serverVersion);
- int tipcFd = tipc_connect(kTrustyIpcDevice, port.c_str());
- return tipcFd >= 0 ? android::base::unique_fd(tipcFd)
- : android::base::unique_fd();
+ for (size_t i = 0; i < 5; i++) {
+ // Try to connect several times,
+ // in case the service is slow to start
+ int tipcFd = tipc_connect(kTrustyIpcDevice, port.c_str());
+ if (tipcFd >= 0) {
+ return android::base::unique_fd(tipcFd);
+ }
+ usleep(50000);
+ }
+ return android::base::unique_fd();
#else
LOG_ALWAYS_FATAL("Tried to connect to Trusty outside of vendor");
return android::base::unique_fd();
@@ -477,7 +473,9 @@
constexpr size_t kNumThreads = 10;
constexpr size_t kNumCalls = kNumThreads + 3;
auto proc = createRpcTestSocketServerProcess({.numThreads = kNumThreads});
- testThreadPoolOverSaturated(proc.rootIface, kNumCalls, 250 /*ms*/);
+
+ // b/272429574 - below 500ms, the test fails
+ testThreadPoolOverSaturated(proc.rootIface, kNumCalls, 500 /*ms*/);
}
TEST_P(BinderRpc, ThreadPoolLimitOutgoing) {
@@ -490,7 +488,9 @@
constexpr size_t kNumCalls = kNumOutgoingConnections + 3;
auto proc = createRpcTestSocketServerProcess(
{.numThreads = kNumThreads, .numOutgoingConnections = kNumOutgoingConnections});
- testThreadPoolOverSaturated(proc.rootIface, kNumCalls, 250 /*ms*/);
+
+ // b/272429574 - below 500ms, the test fails
+ testThreadPoolOverSaturated(proc.rootIface, kNumCalls, 500 /*ms*/);
}
TEST_P(BinderRpc, ThreadingStressTest) {
@@ -1111,6 +1111,15 @@
ASSERT_EQ(beforeFds, countFds()) << (system("ls -l /proc/self/fd/"), "fd leak?");
}
+#ifdef BINDER_RPC_TO_TRUSTY_TEST
+INSTANTIATE_TEST_CASE_P(Trusty, BinderRpc,
+ ::testing::Combine(::testing::Values(SocketType::TIPC),
+ ::testing::Values(RpcSecurity::RAW),
+ ::testing::ValuesIn(testVersions()),
+ ::testing::ValuesIn(testVersions()),
+ ::testing::Values(true), ::testing::Values(true)),
+ BinderRpc::PrintParamInfo);
+#else // BINDER_RPC_TO_TRUSTY_TEST
static bool testSupportVsockLoopback() {
// We don't need to enable TLS to know if vsock is supported.
unsigned int vsockPort = allocateVsockPort();
@@ -1215,21 +1224,6 @@
return ret;
}
-static std::vector<SocketType> testTipcSocketTypes() {
-#ifdef __ANDROID_VENDOR__
- auto port = trustyIpcPort(RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL);
- int tipcFd = tipc_connect(kTrustyIpcDevice, port.c_str());
- if (tipcFd >= 0) {
- close(tipcFd);
- return {SocketType::TIPC};
- }
-#endif // __ANDROID_VENDOR__
-
- // TIPC is not supported on this device, most likely
- // because /dev/trusty-ipc-dev0 is missing
- return {};
-}
-
INSTANTIATE_TEST_CASE_P(PerSocket, BinderRpc,
::testing::Combine(::testing::ValuesIn(testSocketTypes()),
::testing::ValuesIn(RpcSecurityValues()),
@@ -1239,14 +1233,6 @@
::testing::Values(false, true)),
BinderRpc::PrintParamInfo);
-INSTANTIATE_TEST_CASE_P(Trusty, BinderRpc,
- ::testing::Combine(::testing::ValuesIn(testTipcSocketTypes()),
- ::testing::Values(RpcSecurity::RAW),
- ::testing::ValuesIn(testVersions()),
- ::testing::ValuesIn(testVersions()),
- ::testing::Values(true), ::testing::Values(true)),
- BinderRpc::PrintParamInfo);
-
class BinderRpcServerRootObject
: public ::testing::TestWithParam<std::tuple<bool, bool, RpcSecurity>> {};
@@ -1257,7 +1243,7 @@
};
auto [isStrong1, isStrong2, rpcSecurity] = GetParam();
- auto server = RpcServer::make(newFactory(rpcSecurity));
+ auto server = RpcServer::make(newTlsFactory(rpcSecurity));
auto binder1 = sp<BBinder>::make();
IBinder* binderRaw1 = binder1.get();
setRootObject(isStrong1)(server.get(), binder1);
@@ -1353,7 +1339,7 @@
class BinderRpcServerOnly : public ::testing::TestWithParam<std::tuple<RpcSecurity, uint32_t>> {
public:
static std::string PrintTestParam(const ::testing::TestParamInfo<ParamType>& info) {
- return std::string(newFactory(std::get<0>(info.param))->toCString()) + "_serverV" +
+ return std::string(newTlsFactory(std::get<0>(info.param))->toCString()) + "_serverV" +
std::to_string(std::get<1>(info.param));
}
};
@@ -1361,7 +1347,7 @@
TEST_P(BinderRpcServerOnly, SetExternalServerTest) {
base::unique_fd sink(TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR)));
int sinkFd = sink.get();
- auto server = RpcServer::make(newFactory(std::get<0>(GetParam())));
+ auto server = RpcServer::make(newTlsFactory(std::get<0>(GetParam())));
server->setProtocolVersion(std::get<1>(GetParam()));
ASSERT_FALSE(server->hasServer());
ASSERT_EQ(OK, server->setupExternalServer(std::move(sink)));
@@ -1377,7 +1363,7 @@
}
auto addr = allocateSocketAddress();
- auto server = RpcServer::make(newFactory(std::get<0>(GetParam())));
+ auto server = RpcServer::make(newTlsFactory(std::get<0>(GetParam())));
server->setProtocolVersion(std::get<1>(GetParam()));
ASSERT_EQ(OK, server->setupUnixDomainServer(addr.c_str()));
auto joinEnds = std::make_shared<OneOffSignal>();
@@ -1426,7 +1412,7 @@
const Param& param,
std::unique_ptr<RpcAuth> auth = std::make_unique<RpcAuthSelfSigned>()) {
auto [socketType, rpcSecurity, certificateFormat, serverVersion] = param;
- auto rpcServer = RpcServer::make(newFactory(rpcSecurity));
+ auto rpcServer = RpcServer::make(newTlsFactory(rpcSecurity));
rpcServer->setProtocolVersion(serverVersion);
switch (socketType) {
case SocketType::PRECONNECTED: {
@@ -1505,7 +1491,7 @@
}
mFd = rpcServer->releaseServer();
if (!mFd.fd.ok()) return AssertionFailure() << "releaseServer returns invalid fd";
- mCtx = newFactory(rpcSecurity, mCertVerifier, std::move(auth))->newServerCtx();
+ mCtx = newTlsFactory(rpcSecurity, mCertVerifier, std::move(auth))->newServerCtx();
if (mCtx == nullptr) return AssertionFailure() << "newServerCtx";
mSetup = true;
return AssertionSuccess();
@@ -1610,7 +1596,7 @@
auto [socketType, rpcSecurity, certificateFormat, serverVersion] = param;
(void)serverVersion;
mFdTrigger = FdTrigger::make();
- mCtx = newFactory(rpcSecurity, mCertVerifier)->newClientCtx();
+ mCtx = newTlsFactory(rpcSecurity, mCertVerifier)->newClientCtx();
if (mCtx == nullptr) return AssertionFailure() << "newClientCtx";
return AssertionSuccess();
}
@@ -1682,7 +1668,7 @@
using Client = RpcTransportTestUtils::Client;
static inline std::string PrintParamInfo(const testing::TestParamInfo<ParamType>& info) {
auto [socketType, rpcSecurity, certificateFormat, serverVersion] = info.param;
- auto ret = PrintToString(socketType) + "_" + newFactory(rpcSecurity)->toCString();
+ auto ret = PrintToString(socketType) + "_" + newTlsFactory(rpcSecurity)->toCString();
if (certificateFormat.has_value()) ret += "_" + PrintToString(*certificateFormat);
ret += "_serverV" + std::to_string(serverVersion);
return ret;
@@ -2015,6 +2001,7 @@
testing::Values(RpcKeyFormat::PEM, RpcKeyFormat::DER),
testing::ValuesIn(testVersions())),
RpcTransportTlsKeyTest::PrintParamInfo);
+#endif // BINDER_RPC_TO_TRUSTY_TEST
} // namespace android
diff --git a/libs/binder/tests/binderRpcTestCommon.h b/libs/binder/tests/binderRpcTestCommon.h
index a9f0df3..c1364dd 100644
--- a/libs/binder/tests/binderRpcTestCommon.h
+++ b/libs/binder/tests/binderRpcTestCommon.h
@@ -174,7 +174,7 @@
return object;
}
-static inline std::unique_ptr<RpcTransportCtxFactory> newFactory(
+static inline std::unique_ptr<RpcTransportCtxFactory> newTlsFactory(
RpcSecurity rpcSecurity, std::shared_ptr<RpcCertificateVerifier> verifier = nullptr,
std::unique_ptr<RpcAuth> auth = nullptr) {
switch (rpcSecurity) {
diff --git a/libs/binder/tests/binderRpcTestFixture.h b/libs/binder/tests/binderRpcTestFixture.h
index 20fb6bf..6cde9f7 100644
--- a/libs/binder/tests/binderRpcTestFixture.h
+++ b/libs/binder/tests/binderRpcTestFixture.h
@@ -148,9 +148,26 @@
return ret;
}
- static std::string PrintParamInfo(const testing::TestParamInfo<ParamType>& info);
+ static std::string PrintParamInfo(const testing::TestParamInfo<ParamType>& info) {
+ auto [type, security, clientVersion, serverVersion, singleThreaded, noKernel] = info.param;
+ auto ret = PrintToString(type) + "_" + newFactory(security)->toCString() + "_clientV" +
+ std::to_string(clientVersion) + "_serverV" + std::to_string(serverVersion);
+ if (singleThreaded) {
+ ret += "_single_threaded";
+ } else {
+ ret += "_multi_threaded";
+ }
+ if (noKernel) {
+ ret += "_no_kernel";
+ } else {
+ ret += "_with_kernel";
+ }
+ return ret;
+ }
protected:
+ static std::unique_ptr<RpcTransportCtxFactory> newFactory(RpcSecurity rpcSecurity);
+
std::unique_ptr<ProcessSession> createRpcTestSocketServerProcessEtc(
const BinderRpcOptions& options);
};
diff --git a/libs/binder/tests/binderRpcTestService.cpp b/libs/binder/tests/binderRpcTestService.cpp
index ca5a117..a9736d5 100644
--- a/libs/binder/tests/binderRpcTestService.cpp
+++ b/libs/binder/tests/binderRpcTestService.cpp
@@ -116,7 +116,7 @@
}
auto certVerifier = std::make_shared<RpcCertificateVerifierSimple>();
- sp<RpcServer> server = RpcServer::make(newFactory(rpcSecurity, certVerifier));
+ sp<RpcServer> server = RpcServer::make(newTlsFactory(rpcSecurity, certVerifier));
server->setProtocolVersion(serverConfig.serverVersion);
server->setMaxThreads(serverConfig.numThreads);
diff --git a/libs/binder/tests/binderRpcTestTrusty.cpp b/libs/binder/tests/binderRpcTestTrusty.cpp
index 85794bd..28be10d 100644
--- a/libs/binder/tests/binderRpcTestTrusty.cpp
+++ b/libs/binder/tests/binderRpcTestTrusty.cpp
@@ -39,31 +39,25 @@
void terminate() override { LOG_ALWAYS_FATAL("terminate() not supported"); }
};
-std::string BinderRpc::PrintParamInfo(const testing::TestParamInfo<ParamType>& info) {
- auto [type, security, clientVersion, serverVersion, singleThreaded, noKernel] = info.param;
- auto ret = PrintToString(type) + "_clientV" + std::to_string(clientVersion) + "_serverV" +
- std::to_string(serverVersion);
- if (singleThreaded) {
- ret += "_single_threaded";
- } else {
- ret += "_multi_threaded";
+std::unique_ptr<RpcTransportCtxFactory> BinderRpc::newFactory(RpcSecurity rpcSecurity) {
+ switch (rpcSecurity) {
+ case RpcSecurity::RAW:
+ return RpcTransportCtxFactoryTipcTrusty::make();
+ default:
+ LOG_ALWAYS_FATAL("Unknown RpcSecurity %d", rpcSecurity);
}
- if (noKernel) {
- ret += "_no_kernel";
- } else {
- ret += "_with_kernel";
- }
- return ret;
}
// This creates a new process serving an interface on a certain number of
// threads.
std::unique_ptr<ProcessSession> BinderRpc::createRpcTestSocketServerProcessEtc(
const BinderRpcOptions& options) {
- LOG_ALWAYS_FATAL_IF(options.numIncomingConnectionsBySession.size() != 0,
- "Non-zero incoming connections %zu on Trusty",
- options.numIncomingConnectionsBySession.size());
+ LOG_ALWAYS_FATAL_IF(std::any_of(options.numIncomingConnectionsBySession.begin(),
+ options.numIncomingConnectionsBySession.end(),
+ [](size_t n) { return n != 0; }),
+ "Non-zero incoming connections on Trusty");
+ RpcSecurity rpcSecurity = std::get<1>(GetParam());
uint32_t clientVersion = std::get<2>(GetParam());
uint32_t serverVersion = std::get<3>(GetParam());
@@ -71,8 +65,7 @@
status_t status;
for (size_t i = 0; i < options.numSessions; i++) {
- auto factory = android::RpcTransportCtxFactoryTipcTrusty::make();
- auto session = android::RpcSession::make(std::move(factory));
+ auto session = android::RpcSession::make(newFactory(rpcSecurity));
EXPECT_TRUE(session->setProtocolVersion(clientVersion));
session->setMaxOutgoingConnections(options.numOutgoingConnections);
diff --git a/libs/binder/tests/parcel_fuzzer/binder.cpp b/libs/binder/tests/parcel_fuzzer/binder.cpp
index 768fbe1..46d387c 100644
--- a/libs/binder/tests/parcel_fuzzer/binder.cpp
+++ b/libs/binder/tests/parcel_fuzzer/binder.cpp
@@ -367,13 +367,15 @@
FUZZ_LOG() << "about to call readFromParcel() with status for SingleDataParcelable";
parcelables::SingleDataParcelable singleDataParcelable;
status_t status = singleDataParcelable.readFromParcel(&p);
- FUZZ_LOG() <<" status: " << status;
+ FUZZ_LOG() << " status: " << status;
},
[] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to call readFromParcel() with status for GenericDataParcelable";
parcelables::GenericDataParcelable genericDataParcelable;
status_t status = genericDataParcelable.readFromParcel(&p);
- FUZZ_LOG() <<" status: " << status;
+ FUZZ_LOG() << " status: " << status;
+ std::string toString = genericDataParcelable.toString();
+ FUZZ_LOG() << " toString() result: " << toString;
},
};
// clang-format on
diff --git a/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp b/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
index 08eb27a..3a1471e 100644
--- a/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
+++ b/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
@@ -198,6 +198,8 @@
aidl::parcelables::GenericDataParcelable genericDataParcelable;
binder_status_t status = genericDataParcelable.readFromParcel(p.aParcel());
FUZZ_LOG() << "status: " << status;
+ std::string toString = genericDataParcelable.toString();
+ FUZZ_LOG() << "toString() result: " << toString;
},
[](const NdkParcelAdapter& p, FuzzedDataProvider& provider) {
FUZZ_LOG() << "about to marshal AParcel";
diff --git a/libs/binder/tests/parcel_fuzzer/parcelables/GenericDataParcelable.aidl b/libs/binder/tests/parcel_fuzzer/parcelables/GenericDataParcelable.aidl
index f1079e9..dd08f72 100644
--- a/libs/binder/tests/parcel_fuzzer/parcelables/GenericDataParcelable.aidl
+++ b/libs/binder/tests/parcel_fuzzer/parcelables/GenericDataParcelable.aidl
@@ -16,10 +16,23 @@
package parcelables;
parcelable GenericDataParcelable {
+ enum JustSomeEnum {
+ SOME_ENUMERATOR,
+ ANOTHER_ENUMERATOR,
+ MAYBE_ONE_MORE_ENUMERATOR,
+ }
+
+ const int COOL_CONSTANT = 0x1234;
+
int data;
float majorVersion;
float minorVersion;
IBinder binder;
ParcelFileDescriptor fileDescriptor;
int[] array;
-}
\ No newline at end of file
+ String greatString;
+ @utf8InCpp
+ String greaterString;
+ @nullable String nullableString;
+ JustSomeEnum gretEnum = JustSomeEnum.ANOTHER_ENUMERATOR;
+}
diff --git a/libs/binder/tests/unit_fuzzers/RecordedTransactionFileFuzz.cpp b/libs/binder/tests/unit_fuzzers/RecordedTransactionFileFuzz.cpp
index 73790fa..e494366 100644
--- a/libs/binder/tests/unit_fuzzers/RecordedTransactionFileFuzz.cpp
+++ b/libs/binder/tests/unit_fuzzers/RecordedTransactionFileFuzz.cpp
@@ -26,7 +26,7 @@
rewind(intermediateFile);
int fileNumber = fileno(intermediateFile);
- android::base::unique_fd fd(fileNumber);
+ android::base::unique_fd fd(dup(fileNumber));
auto transaction = android::binder::debug::RecordedTransaction::fromFile(fd);
diff --git a/libs/binderdebug/BinderDebug.cpp b/libs/binderdebug/BinderDebug.cpp
index d086b49..a8f2cbf 100644
--- a/libs/binderdebug/BinderDebug.cpp
+++ b/libs/binderdebug/BinderDebug.cpp
@@ -48,14 +48,12 @@
return -errno;
}
}
- static const std::regex kContextLine("^context (\\w+)$");
bool isDesiredContext = false;
std::string line;
- std::smatch match;
while (getline(ifs, line)) {
- if (std::regex_search(line, match, kContextLine)) {
- isDesiredContext = match.str(1) == contextName;
+ if (base::StartsWith(line, "context")) {
+ isDesiredContext = base::Split(line, " ").back() == contextName;
continue;
}
if (!isDesiredContext) {
@@ -66,57 +64,72 @@
return OK;
}
+// Examples of what we are looking at:
+// node 66730: u00007590061890e0 c0000759036130950 pri 0:120 hs 1 hw 1 ls 0 lw 0 is 2 iw 2 tr 1 proc 2300 1790
+// thread 2999: l 00 need_return 1 tr 0
status_t getBinderPidInfo(BinderDebugContext context, pid_t pid, BinderPidInfo* pidInfo) {
std::smatch match;
static const std::regex kReferencePrefix("^\\s*node \\d+:\\s+u([0-9a-f]+)\\s+c([0-9a-f]+)\\s+");
static const std::regex kThreadPrefix("^\\s*thread \\d+:\\s+l\\s+(\\d)(\\d)");
std::string contextStr = contextToString(context);
status_t ret = scanBinderContext(pid, contextStr, [&](const std::string& line) {
- if (std::regex_search(line, match, kReferencePrefix)) {
- const std::string& ptrString = "0x" + match.str(2); // use number after c
- uint64_t ptr;
- if (!::android::base::ParseUint(ptrString.c_str(), &ptr)) {
- // Should not reach here, but just be tolerant.
- return;
- }
- const std::string proc = " proc ";
- auto pos = line.rfind(proc);
- if (pos != std::string::npos) {
- for (const std::string& pidStr : base::Split(line.substr(pos + proc.size()), " ")) {
- int32_t pid;
- if (!::android::base::ParseInt(pidStr, &pid)) {
+ if (base::StartsWith(line, " node")) {
+ std::vector<std::string> splitString = base::Tokenize(line, " ");
+ bool pids = false;
+ uint64_t ptr = 0;
+ for (const auto& token : splitString) {
+ if (base::StartsWith(token, "u")) {
+ const std::string ptrString = "0x" + token.substr(1);
+ if (!::android::base::ParseUint(ptrString.c_str(), &ptr)) {
+ LOG(ERROR) << "Failed to parse pointer: " << ptrString;
return;
}
- pidInfo->refPids[ptr].push_back(pid);
+ } else {
+ // The last numbers in the line after "proc" are all client PIDs
+ if (token == "proc") {
+ pids = true;
+ } else if (pids) {
+ int32_t pid;
+ if (!::android::base::ParseInt(token, &pid)) {
+ LOG(ERROR) << "Failed to parse pid int: " << token;
+ return;
+ }
+ if (ptr == 0) {
+ LOG(ERROR) << "We failed to parse the pointer, so we can't add the refPids";
+ return;
+ }
+ pidInfo->refPids[ptr].push_back(pid);
+ }
}
}
+ } else if (base::StartsWith(line, " thread")) {
+ auto pos = line.find("l ");
+ if (pos != std::string::npos) {
+ // "1" is waiting in binder driver
+ // "2" is poll. It's impossible to tell if these are in use.
+ // and HIDL default code doesn't use it.
+ bool isInUse = line.at(pos + 2) != '1';
+ // "0" is a thread that has called into binder
+ // "1" is looper thread
+ // "2" is main looper thread
+ bool isBinderThread = line.at(pos + 3) != '0';
+ if (!isBinderThread) {
+ return;
+ }
+ if (isInUse) {
+ pidInfo->threadUsage++;
+ }
- return;
- }
- if (std::regex_search(line, match, kThreadPrefix)) {
- // "1" is waiting in binder driver
- // "2" is poll. It's impossible to tell if these are in use.
- // and HIDL default code doesn't use it.
- bool isInUse = match.str(1) != "1";
- // "0" is a thread that has called into binder
- // "1" is looper thread
- // "2" is main looper thread
- bool isBinderThread = match.str(2) != "0";
- if (!isBinderThread) {
- return;
+ pidInfo->threadCount++;
}
- if (isInUse) {
- pidInfo->threadUsage++;
- }
-
- pidInfo->threadCount++;
- return;
}
- return;
});
return ret;
}
+// Examples of what we are looking at:
+// ref 52493: desc 910 node 52492 s 1 w 1 d 0000000000000000
+// node 29413: u00007803fc982e80 c000078042c982210 pri 0:139 hs 1 hw 1 ls 0 lw 0 is 2 iw 2 tr 1 proc 488 683
status_t getBinderClientPids(BinderDebugContext context, pid_t pid, pid_t servicePid,
int32_t handle, std::vector<pid_t>* pids) {
std::smatch match;
@@ -124,51 +137,64 @@
std::string contextStr = contextToString(context);
int32_t node;
status_t ret = scanBinderContext(pid, contextStr, [&](const std::string& line) {
- if (std::regex_search(line, match, kNodeNumber)) {
- const std::string& descString = match.str(1);
- int32_t desc;
- if (!::android::base::ParseInt(descString.c_str(), &desc)) {
- LOG(ERROR) << "Failed to parse desc int: " << descString;
- return;
- }
- if (handle != desc) {
- return;
- }
- const std::string& nodeString = match.str(2);
- if (!::android::base::ParseInt(nodeString.c_str(), &node)) {
- LOG(ERROR) << "Failed to parse node int: " << nodeString;
- return;
- }
+ if (!base::StartsWith(line, " ref")) return;
+
+ std::vector<std::string> splitString = base::Tokenize(line, " ");
+ if (splitString.size() < 12) {
+ LOG(ERROR) << "Failed to parse binder_logs ref entry. Expecting size greater than 11, but got: " << splitString.size();
return;
}
- return;
+ int32_t desc;
+ if (!::android::base::ParseInt(splitString[3].c_str(), &desc)) {
+ LOG(ERROR) << "Failed to parse desc int: " << splitString[3];
+ return;
+ }
+ if (handle != desc) {
+ return;
+ }
+ if (!::android::base::ParseInt(splitString[5].c_str(), &node)) {
+ LOG(ERROR) << "Failed to parse node int: " << splitString[5];
+ return;
+ }
+ LOG(INFO) << "Parsed the node: " << node;
});
if (ret != OK) {
return ret;
}
- static const std::regex kClients("^\\s+node\\s+(\\d+).*proc\\s+([\\d+\\s*]*)");
+
ret = scanBinderContext(servicePid, contextStr, [&](const std::string& line) {
- if (std::regex_search(line, match, kClients)) {
- const std::string nodeString = match.str(1);
- int32_t matchedNode;
- if (!::android::base::ParseInt(nodeString.c_str(), &matchedNode)) {
- LOG(ERROR) << "Failed to parse node int: " << nodeString;
- return;
- }
- if (node != matchedNode) {
- return;
- }
- const std::string clients = match.str(2);
- for (const std::string& pidStr : base::Split(clients, " ")) {
+ if (!base::StartsWith(line, " node")) return;
+
+ std::vector<std::string> splitString = base::Tokenize(line, " ");
+ if (splitString.size() < 21) {
+ LOG(ERROR) << "Failed to parse binder_logs node entry. Expecting size greater than 20, but got: " << splitString.size();
+ return;
+ }
+
+ // remove the colon
+ const std::string nodeString = splitString[1].substr(0, splitString[1].size() - 1);
+ int32_t matchedNode;
+ if (!::android::base::ParseInt(nodeString.c_str(), &matchedNode)) {
+ LOG(ERROR) << "Failed to parse node int: " << nodeString;
+ return;
+ }
+
+ if (node != matchedNode) {
+ return;
+ }
+ bool pidsSection = false;
+ for (const auto& token : splitString) {
+ if (token == "proc") {
+ pidsSection = true;
+ } else if (pidsSection == true) {
int32_t pid;
- if (!::android::base::ParseInt(pidStr, &pid)) {
+ if (!::android::base::ParseInt(token.c_str(), &pid)) {
+ LOG(ERROR) << "Failed to parse PID int: " << token;
return;
}
pids->push_back(pid);
}
- return;
}
- return;
});
return ret;
}
diff --git a/libs/binderthreadstate/include/binderthreadstate/CallerUtils.h b/libs/binderthreadstate/include/binderthreadstate/CallerUtils.h
index a3e5026..54259d2 100644
--- a/libs/binderthreadstate/include/binderthreadstate/CallerUtils.h
+++ b/libs/binderthreadstate/include/binderthreadstate/CallerUtils.h
@@ -36,8 +36,12 @@
// Based on where we are in recursion of nested binder/hwbinder calls, determine
// which one we are closer to.
inline static BinderCallType getCurrentServingCall() {
- const void* hwbinderSp = android::hardware::IPCThreadState::self()->getServingStackPointer();
- const void* binderSp = android::IPCThreadState::self()->getServingStackPointer();
+ auto* hwState = android::hardware::IPCThreadState::selfOrNull();
+ auto* state = android::IPCThreadState::selfOrNull();
+
+ // getServingStackPointer can also return nullptr
+ const void* hwbinderSp = hwState ? hwState->getServingStackPointer() : nullptr;
+ const void* binderSp = state ? state->getServingStackPointer() : nullptr;
if (hwbinderSp == nullptr && binderSp == nullptr) return BinderCallType::NONE;
if (hwbinderSp == nullptr) return BinderCallType::BINDER;
diff --git a/libs/binderthreadstate/test.cpp b/libs/binderthreadstate/test.cpp
index df1f35d..b5c4010 100644
--- a/libs/binderthreadstate/test.cpp
+++ b/libs/binderthreadstate/test.cpp
@@ -16,11 +16,16 @@
#include <BnAidlStuff.h>
#include <android-base/logging.h>
+#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binderthreadstate/CallerUtils.h>
#include <binderthreadstateutilstest/1.0/IHidlStuff.h>
#include <gtest/gtest.h>
#include <hidl/HidlTransportSupport.h>
+#include <hwbinder/IPCThreadState.h>
+
+#include <thread>
+
#include <linux/prctl.h>
#include <sys/prctl.h>
@@ -154,6 +159,20 @@
EXPECT_TRUE(server->callLocal().isOk());
}
+TEST(BinderThreadState, DoesntInitializeBinderDriver) {
+ // this is on another thread, because it's testing thread-specific
+ // state and we expect it not to be initialized.
+ std::thread([&] {
+ EXPECT_EQ(nullptr, android::IPCThreadState::selfOrNull());
+ EXPECT_EQ(nullptr, android::hardware::IPCThreadState::selfOrNull());
+
+ (void)getCurrentServingCall();
+
+ EXPECT_EQ(nullptr, android::IPCThreadState::selfOrNull());
+ EXPECT_EQ(nullptr, android::hardware::IPCThreadState::selfOrNull());
+ }).join();
+}
+
TEST(BindThreadState, RemoteHidlCall) {
auto stuff = IHidlStuff::getService(id2name(kP1Id));
ASSERT_NE(nullptr, stuff);
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index b391337..1969496 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -190,8 +190,8 @@
}
SAFE_PARCEL(output.writeParcelable, trustedPresentationThresholds);
SAFE_PARCEL(output.writeParcelable, trustedPresentationListener);
- SAFE_PARCEL(output.writeFloat, currentSdrHdrRatio);
- SAFE_PARCEL(output.writeFloat, desiredSdrHdrRatio);
+ SAFE_PARCEL(output.writeFloat, currentHdrSdrRatio);
+ SAFE_PARCEL(output.writeFloat, desiredHdrSdrRatio);
SAFE_PARCEL(output.writeInt32, static_cast<int32_t>(cachingHint))
return NO_ERROR;
}
@@ -335,9 +335,9 @@
SAFE_PARCEL(input.readParcelable, &trustedPresentationListener);
SAFE_PARCEL(input.readFloat, &tmpFloat);
- currentSdrHdrRatio = tmpFloat;
+ currentHdrSdrRatio = tmpFloat;
SAFE_PARCEL(input.readFloat, &tmpFloat);
- desiredSdrHdrRatio = tmpFloat;
+ desiredHdrSdrRatio = tmpFloat;
int32_t tmpInt32;
SAFE_PARCEL(input.readInt32, &tmpInt32);
@@ -592,8 +592,8 @@
}
if (other.what & eExtendedRangeBrightnessChanged) {
what |= eExtendedRangeBrightnessChanged;
- desiredSdrHdrRatio = other.desiredSdrHdrRatio;
- currentSdrHdrRatio = other.currentSdrHdrRatio;
+ desiredHdrSdrRatio = other.desiredHdrSdrRatio;
+ currentHdrSdrRatio = other.currentHdrSdrRatio;
}
if (other.what & eCachingHintChanged) {
what |= eCachingHintChanged;
@@ -747,8 +747,8 @@
CHECK_DIFF(diff, eCropChanged, other, crop);
if (other.what & eBufferChanged) diff |= eBufferChanged;
CHECK_DIFF(diff, eDataspaceChanged, other, dataspace);
- CHECK_DIFF2(diff, eExtendedRangeBrightnessChanged, other, currentSdrHdrRatio,
- desiredSdrHdrRatio);
+ CHECK_DIFF2(diff, eExtendedRangeBrightnessChanged, other, currentHdrSdrRatio,
+ desiredHdrSdrRatio);
CHECK_DIFF(diff, eCachingHintChanged, other, cachingHint);
CHECK_DIFF(diff, eHdrMetadataChanged, other, hdrMetadata);
if (other.what & eSurfaceDamageRegionChanged &&
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 2f5830d..7700aa4 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1723,8 +1723,8 @@
return *this;
}
s->what |= layer_state_t::eExtendedRangeBrightnessChanged;
- s->currentSdrHdrRatio = currentBufferRatio;
- s->desiredSdrHdrRatio = desiredRatio;
+ s->currentHdrSdrRatio = currentBufferRatio;
+ s->desiredHdrSdrRatio = desiredRatio;
registerSurfaceControlForCallback(sc);
return *this;
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 6e3be5c..5c88a07 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -389,8 +389,8 @@
gui::DropInputMode dropInputMode;
bool dimmingEnabled;
- float currentSdrHdrRatio = 1.f;
- float desiredSdrHdrRatio = 1.f;
+ float currentHdrSdrRatio = 1.f;
+ float desiredHdrSdrRatio = 1.f;
gui::CachingHint cachingHint = gui::CachingHint::Enabled;
diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp
index 183acc1..cd35d2f 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -91,6 +91,9 @@
compile_multilib: "both",
header_libs: ["libsurfaceflinger_headers"],
+ data: [
+ ":libgui_test",
+ ],
}
cc_test {
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 3344e0b..5f80c16 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -512,6 +512,22 @@
bgSurface->expectTap(1, 1);
}
+TEST_F(InputSurfacesTest, input_respects_surface_insets_with_replaceTouchableRegionWithCrop) {
+ 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->mInputInfo.replaceTouchableRegionWithCrop = true;
+ fgSurface->showAt(100, 100);
+
+ injectTap(106, 106);
+ fgSurface->expectTap(1, 1);
+
+ injectTap(101, 101);
+ bgSurface->expectTap(1, 1);
+}
+
// Ensure a surface whose insets are cropped, handles the touch offset correctly. ref:b/120413463
TEST_F(InputSurfacesTest, input_respects_cropped_surface_insets) {
std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
diff --git a/libs/input/Keyboard.cpp b/libs/input/Keyboard.cpp
index 3f8467d..0b5c7ff 100644
--- a/libs/input/Keyboard.cpp
+++ b/libs/input/Keyboard.cpp
@@ -16,9 +16,10 @@
#define LOG_TAG "Keyboard"
+#include <limits.h>
#include <stdlib.h>
#include <unistd.h>
-#include <limits.h>
+#include <optional>
#include <input/InputDevice.h>
#include <input/InputEventLabels.h>
@@ -49,23 +50,25 @@
const PropertyMap* deviceConfiguration) {
// Use the configured key layout if available.
if (deviceConfiguration) {
- std::string keyLayoutName;
- if (deviceConfiguration->tryGetProperty("keyboard.layout", keyLayoutName)) {
- status_t status = loadKeyLayout(deviceIdentifier, keyLayoutName.c_str());
+ std::optional<std::string> keyLayoutName =
+ deviceConfiguration->getString("keyboard.layout");
+ if (keyLayoutName.has_value()) {
+ status_t status = loadKeyLayout(deviceIdentifier, *keyLayoutName);
if (status == NAME_NOT_FOUND) {
ALOGE("Configuration for keyboard device '%s' requested keyboard layout '%s' but "
"it was not found.",
- deviceIdentifier.name.c_str(), keyLayoutName.c_str());
+ deviceIdentifier.name.c_str(), keyLayoutName->c_str());
}
}
- std::string keyCharacterMapName;
- if (deviceConfiguration->tryGetProperty("keyboard.characterMap", keyCharacterMapName)) {
- status_t status = loadKeyCharacterMap(deviceIdentifier, keyCharacterMapName.c_str());
+ std::optional<std::string> keyCharacterMapName =
+ deviceConfiguration->getString("keyboard.characterMap");
+ if (keyCharacterMapName.has_value()) {
+ status_t status = loadKeyCharacterMap(deviceIdentifier, *keyCharacterMapName);
if (status == NAME_NOT_FOUND) {
ALOGE("Configuration for keyboard device '%s' requested keyboard character "
"map '%s' but it was not found.",
- deviceIdentifier.name.c_str(), keyCharacterMapName.c_str());
+ deviceIdentifier.name.c_str(), keyCharacterMapName->c_str());
}
}
@@ -162,9 +165,7 @@
if (config == nullptr) {
return false;
}
- bool isSpecialFunction = false;
- config->tryGetProperty("keyboard.specialFunction", isSpecialFunction);
- return isSpecialFunction;
+ return config->getBool("keyboard.specialFunction").value_or(false);
}
bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentifier,
@@ -177,8 +178,7 @@
}
if (deviceConfiguration) {
- bool builtIn = false;
- if (deviceConfiguration->tryGetProperty("keyboard.builtIn", builtIn) && builtIn) {
+ if (deviceConfiguration->getBool("keyboard.builtIn").value_or(false)) {
return true;
}
}
diff --git a/libs/input/PropertyMap.cpp b/libs/input/PropertyMap.cpp
index 9a4f10b..548f894 100644
--- a/libs/input/PropertyMap.cpp
+++ b/libs/input/PropertyMap.cpp
@@ -60,75 +60,62 @@
return mProperties.find(key) != mProperties.end();
}
-bool PropertyMap::tryGetProperty(const std::string& key, std::string& outValue) const {
+std::optional<std::string> PropertyMap::getString(const std::string& key) const {
auto it = mProperties.find(key);
- if (it == mProperties.end()) {
- return false;
- }
-
- outValue = it->second;
- return true;
+ return it != mProperties.end() ? std::make_optional(it->second) : std::nullopt;
}
-bool PropertyMap::tryGetProperty(const std::string& key, bool& outValue) const {
- int32_t intValue;
- if (!tryGetProperty(key, intValue)) {
- return false;
- }
-
- outValue = intValue;
- return true;
+std::optional<bool> PropertyMap::getBool(const std::string& key) const {
+ std::optional<int32_t> intValue = getInt(key);
+ return intValue.has_value() ? std::make_optional(*intValue != 0) : std::nullopt;
}
-bool PropertyMap::tryGetProperty(const std::string& key, int32_t& outValue) const {
- std::string stringValue;
- if (!tryGetProperty(key, stringValue) || stringValue.length() == 0) {
- return false;
+std::optional<int32_t> PropertyMap::getInt(const std::string& key) const {
+ std::optional<std::string> stringValue = getString(key);
+ if (!stringValue.has_value() || stringValue->length() == 0) {
+ return std::nullopt;
}
char* end;
- int32_t value = static_cast<int32_t>(strtol(stringValue.c_str(), &end, 10));
+ int32_t value = static_cast<int32_t>(strtol(stringValue->c_str(), &end, 10));
if (*end != '\0') {
ALOGW("Property key '%s' has invalid value '%s'. Expected an integer.", key.c_str(),
- stringValue.c_str());
- return false;
+ stringValue->c_str());
+ return std::nullopt;
}
- outValue = value;
- return true;
+ return value;
}
-bool PropertyMap::tryGetProperty(const std::string& key, float& outValue) const {
- std::string stringValue;
- if (!tryGetProperty(key, stringValue) || stringValue.length() == 0) {
- return false;
+std::optional<float> PropertyMap::getFloat(const std::string& key) const {
+ std::optional<std::string> stringValue = getString(key);
+ if (!stringValue.has_value() || stringValue->length() == 0) {
+ return std::nullopt;
}
char* end;
- float value = strtof(stringValue.c_str(), &end);
+ float value = strtof(stringValue->c_str(), &end);
if (*end != '\0') {
ALOGW("Property key '%s' has invalid value '%s'. Expected a float.", key.c_str(),
- stringValue.c_str());
- return false;
+ stringValue->c_str());
+ return std::nullopt;
}
- outValue = value;
- return true;
+ return value;
}
-bool PropertyMap::tryGetProperty(const std::string& key, double& outValue) const {
- std::string stringValue;
- if (!tryGetProperty(key, stringValue) || stringValue.length() == 0) {
- return false;
+std::optional<double> PropertyMap::getDouble(const std::string& key) const {
+ std::optional<std::string> stringValue = getString(key);
+ if (!stringValue.has_value() || stringValue->length() == 0) {
+ return std::nullopt;
}
char* end;
- double value = strtod(stringValue.c_str(), &end);
+ double value = strtod(stringValue->c_str(), &end);
if (*end != '\0') {
ALOGW("Property key '%s' has invalid value '%s'. Expected a double.", key.c_str(),
- stringValue.c_str());
- return false;
+ stringValue->c_str());
+ return std::nullopt;
}
- outValue = value;
- return true;
+ return value;
}
void PropertyMap::addAll(const PropertyMap* map) {
diff --git a/libs/input/PropertyMap_fuzz.cpp b/libs/input/PropertyMap_fuzz.cpp
old mode 100755
new mode 100644
index d985dc1..6299ca8
--- a/libs/input/PropertyMap_fuzz.cpp
+++ b/libs/input/PropertyMap_fuzz.cpp
@@ -29,8 +29,7 @@
},
[](FuzzedDataProvider* dataProvider, android::PropertyMap& propertyMap) -> void {
std::string key = dataProvider->ConsumeRandomLengthString(MAX_STR_LEN);
- std::string out;
- propertyMap.tryGetProperty(key, out);
+ propertyMap.getString(key);
},
[](FuzzedDataProvider* dataProvider, android::PropertyMap& /*unused*/) -> void {
TemporaryFile tf;
diff --git a/libs/input/TfLiteMotionPredictor.cpp b/libs/input/TfLiteMotionPredictor.cpp
index 691e87c..3b061d1 100644
--- a/libs/input/TfLiteMotionPredictor.cpp
+++ b/libs/input/TfLiteMotionPredictor.cpp
@@ -61,8 +61,21 @@
constexpr char OUTPUT_PHI[] = "phi";
constexpr char OUTPUT_PRESSURE[] = "pressure";
+// Ideally, we would just use std::filesystem::exists here, but it requires libc++fs, which causes
+// build issues in other parts of the system.
+#if defined(__ANDROID__)
+bool fileExists(const char* filename) {
+ struct stat buffer;
+ return stat(filename, &buffer) == 0;
+}
+#endif
+
std::string getModelPath() {
#if defined(__ANDROID__)
+ static const char* oemModel = "/vendor/etc/motion_predictor_model.fb";
+ if (fileExists(oemModel)) {
+ return oemModel;
+ }
return "/system/etc/motion_predictor_model.fb";
#else
return base::GetExecutableDirectory() + "/motion_predictor_model.fb";
@@ -217,7 +230,7 @@
std::unique_ptr<TfLiteMotionPredictorModel> TfLiteMotionPredictorModel::create() {
const std::string modelPath = getModelPath();
- const int fd = open(modelPath.c_str(), O_RDONLY);
+ android::base::unique_fd fd(open(modelPath.c_str(), O_RDONLY));
if (fd == -1) {
PLOG(FATAL) << "Could not read model from " << modelPath;
}
@@ -232,9 +245,6 @@
if (!modelBuffer) {
PLOG(FATAL) << "Failed to mmap model";
}
- if (close(fd) == -1) {
- PLOG(FATAL) << "Failed to close model fd";
- }
return std::unique_ptr<TfLiteMotionPredictorModel>(
new TfLiteMotionPredictorModel(std::move(modelBuffer)));
diff --git a/libs/jpegrecoverymap/include/jpegrecoverymap/jpegr.h b/libs/jpegrecoverymap/include/jpegrecoverymap/jpegr.h
index 9b2dde7..1ab1dd7 100644
--- a/libs/jpegrecoverymap/include/jpegrecoverymap/jpegr.h
+++ b/libs/jpegrecoverymap/include/jpegrecoverymap/jpegr.h
@@ -91,7 +91,10 @@
int length;
};
-struct jpegr_metadata {
+/*
+ * Holds information for recovery map related metadata.
+ */
+struct jpegr_metadata_struct {
// JPEG/R version
uint32_t version;
// Max Content Boost for the map
@@ -103,12 +106,14 @@
typedef struct jpegr_uncompressed_struct* jr_uncompressed_ptr;
typedef struct jpegr_compressed_struct* jr_compressed_ptr;
typedef struct jpegr_exif_struct* jr_exif_ptr;
-typedef struct jpegr_metadata* jr_metadata_ptr;
+typedef struct jpegr_metadata_struct* jr_metadata_ptr;
typedef struct jpegr_info_struct* jr_info_ptr;
class JpegR {
public:
/*
+ * Experimental only
+ *
* Encode API-0
* Compress JPEGR image from 10-bit HDR YUV.
*
@@ -199,21 +204,42 @@
* Decode API
* Decompress JPEGR image.
*
- * The output JPEGR image is in RGBA_1010102 data format if decoding to HDR.
- * @param compressed_jpegr_image compressed JPEGR image
- * @param dest destination of the uncompressed JPEGR image
- * @param exif destination of the decoded EXIF metadata.
- * @param output_format flag for setting output color format. if set to
- * {@code JPEGR_OUTPUT_SDR}, decoder will only decode the primary image
- * which is SDR. Default value is JPEGR_OUTPUT_HDR_LINEAR.
- * @param recovery_map destination of the decoded recovery map.
+ * @param compressed_jpegr_image compressed JPEGR image.
+ * @param dest destination of the uncompressed JPEGR image.
+ * @param max_display_boost (optional) the maximum available boost supported by a display
+ * @param exif destination of the decoded EXIF metadata. The default value is NULL where the
+ decoder will do nothing about it. If configured not NULL the decoder will write
+ EXIF data into this structure. The format is defined in {@code jpegr_exif_struct}
+ * @param output_format flag for setting output color format. Its value configures the output
+ color format. The default value is {@code JPEGR_OUTPUT_HDR_LINEAR}.
+ ----------------------------------------------------------------------
+ | output_format | decoded color format to be written |
+ ----------------------------------------------------------------------
+ | JPEGR_OUTPUT_SDR | RGBA_8888 |
+ ----------------------------------------------------------------------
+ | JPEGR_OUTPUT_HDR_LINEAR | (default)RGBA_F16 linear |
+ ----------------------------------------------------------------------
+ | JPEGR_OUTPUT_HDR_PQ | RGBA_1010102 PQ |
+ ----------------------------------------------------------------------
+ | JPEGR_OUTPUT_HDR_HLG | RGBA_1010102 HLG |
+ ----------------------------------------------------------------------
+ * @param recovery_map destination of the decoded recovery map. The default value is NULL where
+ the decoder will do nothing about it. If configured not NULL the decoder
+ will write the decoded recovery_map data into this structure. The format
+ is defined in {@code jpegr_uncompressed_struct}.
+ * @param metadata destination of the decoded metadata. The default value is NULL where the
+ decoder will do nothing about it. If configured not NULL the decoder will
+ write metadata into this structure. the format of metadata is defined in
+ {@code jpegr_metadata}.
* @return NO_ERROR if decoding succeeds, error code if error occurs.
*/
status_t decodeJPEGR(jr_compressed_ptr compressed_jpegr_image,
jr_uncompressed_ptr dest,
+ float max_display_boost = -1.0f,
jr_exif_ptr exif = nullptr,
jpegr_output_format output_format = JPEGR_OUTPUT_HDR_LINEAR,
- jr_uncompressed_ptr recovery_map = nullptr);
+ jr_uncompressed_ptr recovery_map = nullptr,
+ jr_metadata_ptr metadata = nullptr);
/*
* Gets Info from JPEGR file without decoding it.
@@ -257,6 +283,7 @@
* @param output_format flag for setting output color format. if set to
* {@code JPEGR_OUTPUT_SDR}, decoder will only decode the primary image
* which is SDR. Default value is JPEGR_OUTPUT_HDR_LINEAR.
+ * @param max_display_boost the maximum available boost supported by a display
* @param dest reconstructed HDR image
* @return NO_ERROR if calculation succeeds, error code if error occurs.
*/
@@ -264,6 +291,7 @@
jr_uncompressed_ptr uncompressed_recovery_map,
jr_metadata_ptr metadata,
jpegr_output_format output_format,
+ float max_display_boost,
jr_uncompressed_ptr dest);
private:
diff --git a/libs/jpegrecoverymap/include/jpegrecoverymap/jpegrutils.h b/libs/jpegrecoverymap/include/jpegrecoverymap/jpegrutils.h
index a381743..dd06fa2 100644
--- a/libs/jpegrecoverymap/include/jpegrecoverymap/jpegrutils.h
+++ b/libs/jpegrecoverymap/include/jpegrecoverymap/jpegrutils.h
@@ -45,7 +45,7 @@
#define Endian_SwapBE16(n) (n)
#endif
-struct jpegr_metadata;
+struct jpegr_metadata_struct;
/*
* Mutable data structure. Holds information for metadata.
*/
@@ -87,7 +87,7 @@
* @param metadata place to store HDR metadata values
* @return true if metadata is successfully retrieved, false otherwise
*/
-bool getMetadataFromXMP(uint8_t* xmp_data, size_t xmp_size, jpegr_metadata* metadata);
+bool getMetadataFromXMP(uint8_t* xmp_data, size_t xmp_size, jpegr_metadata_struct* metadata);
/*
* This method generates XMP metadata for the primary image.
@@ -156,7 +156,7 @@
* @param metadata JPEG/R metadata to encode as XMP
* @return XMP metadata in type of string
*/
- std::string generateXmpForSecondaryImage(jpegr_metadata& metadata);
+ std::string generateXmpForSecondaryImage(jpegr_metadata_struct& metadata);
} // namespace android::jpegrecoverymap
#endif //ANDROID_JPEGRECOVERYMAP_JPEGRUTILS_H
diff --git a/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymapmath.h b/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymapmath.h
index 8b5318f..67d2a6a 100644
--- a/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymapmath.h
+++ b/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymapmath.h
@@ -135,6 +135,16 @@
}
}
+ RecoveryLUT(jr_metadata_ptr metadata, float displayBoost) {
+ float boostFactor = displayBoost > 0 ? displayBoost / metadata->maxContentBoost : 1.0f;
+ for (int idx = 0; idx < kRecoveryFactorNumEntries; idx++) {
+ float value = static_cast<float>(idx) / static_cast<float>(kRecoveryFactorNumEntries - 1);
+ float logBoost = log2(metadata->minContentBoost) * (1.0f - value)
+ + log2(metadata->maxContentBoost) * value;
+ mRecoveryTable[idx] = exp2(logBoost * boostFactor);
+ }
+ }
+
~RecoveryLUT() {
}
@@ -357,6 +367,7 @@
* value, with the given hdr ratio, to the given sdr input in the range [0, 1].
*/
Color applyRecovery(Color e, float recovery, jr_metadata_ptr metadata);
+Color applyRecovery(Color e, float recovery, jr_metadata_ptr metadata, float displayBoost);
Color applyRecoveryLUT(Color e, float recovery, RecoveryLUT& recoveryLUT);
/*
diff --git a/libs/jpegrecoverymap/jpegr.cpp b/libs/jpegrecoverymap/jpegr.cpp
index f8763c6..e395d51 100644
--- a/libs/jpegrecoverymap/jpegr.cpp
+++ b/libs/jpegrecoverymap/jpegr.cpp
@@ -107,7 +107,7 @@
return ERROR_JPEGR_INVALID_INPUT_TYPE;
}
- jpegr_metadata metadata;
+ jpegr_metadata_struct metadata;
metadata.version = kJpegrVersion;
jpegr_uncompressed_struct uncompressed_yuv_420_image;
@@ -176,7 +176,7 @@
return ERROR_JPEGR_INVALID_INPUT_TYPE;
}
- jpegr_metadata metadata;
+ jpegr_metadata_struct metadata;
metadata.version = kJpegrVersion;
jpegr_uncompressed_struct map;
@@ -235,7 +235,7 @@
return ERROR_JPEGR_INVALID_INPUT_TYPE;
}
- jpegr_metadata metadata;
+ jpegr_metadata_struct metadata;
metadata.version = kJpegrVersion;
jpegr_uncompressed_struct map;
@@ -288,7 +288,7 @@
return ERROR_JPEGR_RESOLUTION_MISMATCH;
}
- jpegr_metadata metadata;
+ jpegr_metadata_struct metadata;
metadata.version = kJpegrVersion;
jpegr_uncompressed_struct map;
@@ -330,9 +330,11 @@
/* Decode API */
status_t JpegR::decodeJPEGR(jr_compressed_ptr compressed_jpegr_image,
jr_uncompressed_ptr dest,
+ float max_display_boost,
jr_exif_ptr exif,
jpegr_output_format output_format,
- jr_uncompressed_ptr recovery_map) {
+ jr_uncompressed_ptr recovery_map,
+ jr_metadata_ptr metadata) {
if (compressed_jpegr_image == nullptr || dest == nullptr) {
return ERROR_JPEGR_INVALID_NULL_PTR;
}
@@ -387,6 +389,18 @@
memcpy(recovery_map->data, recovery_map_decoder.getDecompressedImagePtr(), size);
}
+ jpegr_metadata_struct jr_metadata;
+ if (!getMetadataFromXMP(static_cast<uint8_t*>(recovery_map_decoder.getXMPPtr()),
+ recovery_map_decoder.getXMPSize(), &jr_metadata)) {
+ return ERROR_JPEGR_DECODE_ERROR;
+ }
+
+ if (metadata != nullptr) {
+ metadata->version = jr_metadata.version;
+ metadata->minContentBoost = jr_metadata.minContentBoost;
+ metadata->maxContentBoost = jr_metadata.maxContentBoost;
+ }
+
if (output_format == JPEGR_OUTPUT_SDR) {
return NO_ERROR;
}
@@ -417,13 +431,8 @@
uncompressed_yuv_420_image.width = jpeg_decoder.getDecompressedImageWidth();
uncompressed_yuv_420_image.height = jpeg_decoder.getDecompressedImageHeight();
- jpegr_metadata metadata;
- if (!getMetadataFromXMP(static_cast<uint8_t*>(recovery_map_decoder.getXMPPtr()),
- recovery_map_decoder.getXMPSize(), &metadata)) {
- return ERROR_JPEGR_DECODE_ERROR;
- }
-
- JPEGR_CHECK(applyRecoveryMap(&uncompressed_yuv_420_image, &map, &metadata, output_format, dest));
+ JPEGR_CHECK(applyRecoveryMap(&uncompressed_yuv_420_image, &map, &jr_metadata, output_format,
+ max_display_boost, dest));
return NO_ERROR;
}
@@ -659,6 +668,7 @@
jr_uncompressed_ptr uncompressed_recovery_map,
jr_metadata_ptr metadata,
jpegr_output_format output_format,
+ float max_display_boost,
jr_uncompressed_ptr dest) {
if (uncompressed_yuv_420_image == nullptr
|| uncompressed_recovery_map == nullptr
@@ -670,13 +680,15 @@
dest->width = uncompressed_yuv_420_image->width;
dest->height = uncompressed_yuv_420_image->height;
ShepardsIDW idwTable(kMapDimensionScaleFactor);
- RecoveryLUT recoveryLUT(metadata);
+ float display_boost = max_display_boost > 0 ?
+ std::min(max_display_boost, metadata->maxContentBoost)
+ : metadata->maxContentBoost;
+ RecoveryLUT recoveryLUT(metadata, display_boost);
JobQueue jobQueue;
std::function<void()> applyRecMap = [uncompressed_yuv_420_image, uncompressed_recovery_map,
metadata, dest, &jobQueue, &idwTable, output_format,
- &recoveryLUT]() -> void {
- const float hdr_ratio = metadata->maxContentBoost;
+ &recoveryLUT, display_boost]() -> void {
size_t width = uncompressed_yuv_420_image->width;
size_t height = uncompressed_yuv_420_image->height;
@@ -702,12 +714,13 @@
} else {
recovery = sampleMap(uncompressed_recovery_map, map_scale_factor, x, y, idwTable);
}
+
#if USE_APPLY_RECOVERY_LUT
Color rgb_hdr = applyRecoveryLUT(rgb_sdr, recovery, recoveryLUT);
#else
- Color rgb_hdr = applyRecovery(rgb_sdr, recovery, metadata);
+ Color rgb_hdr = applyRecovery(rgb_sdr, recovery, metadata, display_boost);
#endif
- rgb_hdr = rgb_hdr / metadata->maxContentBoost;
+ rgb_hdr = rgb_hdr / display_boost;
size_t pixel_idx = x + y * width;
switch (output_format) {
diff --git a/libs/jpegrecoverymap/jpegrutils.cpp b/libs/jpegrecoverymap/jpegrutils.cpp
index 38b78ad..ff96447 100644
--- a/libs/jpegrecoverymap/jpegrutils.cpp
+++ b/libs/jpegrecoverymap/jpegrutils.cpp
@@ -253,7 +253,7 @@
const string XMPXmlHandler::minContentBoostAttrName = kMapGainMapMin;
const string XMPXmlHandler::maxContentBoostAttrName = kMapGainMapMax;
-bool getMetadataFromXMP(uint8_t* xmp_data, size_t xmp_size, jpegr_metadata* metadata) {
+bool getMetadataFromXMP(uint8_t* xmp_data, size_t xmp_size, jpegr_metadata_struct* metadata) {
string nameSpace = "http://ns.adobe.com/xap/1.0/\0";
if (xmp_size < nameSpace.size()+2) {
@@ -327,7 +327,7 @@
return ss.str();
}
-string generateXmpForSecondaryImage(jpegr_metadata& metadata) {
+string generateXmpForSecondaryImage(jpegr_metadata_struct& metadata) {
const vector<string> kConDirSeq({kConDirectory, string("rdf:Seq")});
const vector<string> kLiItem({string("rdf:li"), kConItem});
diff --git a/libs/jpegrecoverymap/recoverymapmath.cpp b/libs/jpegrecoverymap/recoverymapmath.cpp
index 20c32ed..2cffde3 100644
--- a/libs/jpegrecoverymap/recoverymapmath.cpp
+++ b/libs/jpegrecoverymap/recoverymapmath.cpp
@@ -463,6 +463,13 @@
return e * recoveryFactor;
}
+Color applyRecovery(Color e, float recovery, jr_metadata_ptr metadata, float displayBoost) {
+ float logBoost = log2(metadata->minContentBoost) * (1.0f - recovery)
+ + log2(metadata->maxContentBoost) * recovery;
+ float recoveryFactor = exp2(logBoost * displayBoost / metadata->maxContentBoost);
+ return e * recoveryFactor;
+}
+
Color applyRecoveryLUT(Color e, float recovery, RecoveryLUT& recoveryLUT) {
float recoveryFactor = recoveryLUT.getRecoveryFactor(recovery);
return e * recoveryFactor;
diff --git a/libs/jpegrecoverymap/tests/jpegr_test.cpp b/libs/jpegrecoverymap/tests/jpegr_test.cpp
index 0a7d20a..df90f53 100644
--- a/libs/jpegrecoverymap/tests/jpegr_test.cpp
+++ b/libs/jpegrecoverymap/tests/jpegr_test.cpp
@@ -152,7 +152,8 @@
timerStart(&applyRecMapTime);
for (auto i = 0; i < kProfileCount; i++) {
- ASSERT_EQ(OK, applyRecoveryMap(yuv420Image, map, metadata, JPEGR_OUTPUT_HDR_HLG, dest));
+ ASSERT_EQ(OK, applyRecoveryMap(yuv420Image, map, metadata, JPEGR_OUTPUT_HDR_HLG,
+ metadata->maxContentBoost /* displayBoost */, dest));
}
timerStop(&applyRecMapTime);
@@ -170,11 +171,11 @@
jpegRCodec.encodeJPEGR(nullptr, nullptr, nullptr, static_cast<jpegr_transfer_function>(0),
nullptr);
jpegRCodec.encodeJPEGR(nullptr, nullptr, static_cast<jpegr_transfer_function>(0), nullptr);
- jpegRCodec.decodeJPEGR(nullptr, nullptr, nullptr);
+ jpegRCodec.decodeJPEGR(nullptr, nullptr);
}
TEST_F(JpegRTest, writeXmpThenRead) {
- jpegr_metadata metadata_expected;
+ jpegr_metadata_struct metadata_expected;
metadata_expected.maxContentBoost = 1.25;
metadata_expected.minContentBoost = 0.75;
const std::string nameSpace = "http://ns.adobe.com/xap/1.0/\0";
@@ -189,7 +190,7 @@
xmpData.insert(xmpData.end(), reinterpret_cast<const uint8_t*>(xmp.c_str()),
reinterpret_cast<const uint8_t*>(xmp.c_str()) + xmp.size());
- jpegr_metadata metadata_read;
+ jpegr_metadata_struct metadata_read;
EXPECT_TRUE(getMetadataFromXMP(xmpData.data(), xmpData.size(), &metadata_read));
ASSERT_EQ(metadata_expected.maxContentBoost, metadata_read.maxContentBoost);
ASSERT_EQ(metadata_expected.minContentBoost, metadata_read.minContentBoost);
@@ -476,7 +477,7 @@
JpegRBenchmark benchmark;
- jpegr_metadata metadata = { .version = 1,
+ jpegr_metadata_struct metadata = { .version = 1,
.maxContentBoost = 8.0f,
.minContentBoost = 1.0f / 8.0f };
diff --git a/libs/jpegrecoverymap/tests/recoverymapmath_test.cpp b/libs/jpegrecoverymap/tests/recoverymapmath_test.cpp
index 6c61ff1..5ef79e9 100644
--- a/libs/jpegrecoverymap/tests/recoverymapmath_test.cpp
+++ b/libs/jpegrecoverymap/tests/recoverymapmath_test.cpp
@@ -554,9 +554,10 @@
TEST_F(RecoveryMapMathTest, applyRecoveryLUT) {
for (int boost = 1; boost <= 10; boost++) {
- jpegr_metadata metadata = { .maxContentBoost = static_cast<float>(boost),
- .minContentBoost = 1.0f / static_cast<float>(boost) };
+ jpegr_metadata_struct metadata = { .maxContentBoost = static_cast<float>(boost),
+ .minContentBoost = 1.0f / static_cast<float>(boost) };
RecoveryLUT recoveryLUT(&metadata);
+ RecoveryLUT recoveryLUTWithBoost(&metadata, metadata.maxContentBoost);
for (int idx = 0; idx < kRecoveryFactorNumEntries; idx++) {
float value = static_cast<float>(idx) / static_cast<float>(kRecoveryFactorNumEntries - 1);
EXPECT_RGB_NEAR(applyRecovery(RgbBlack(), value, &metadata),
@@ -569,13 +570,24 @@
applyRecoveryLUT(RgbGreen(), value, recoveryLUT));
EXPECT_RGB_NEAR(applyRecovery(RgbBlue(), value, &metadata),
applyRecoveryLUT(RgbBlue(), value, recoveryLUT));
+ EXPECT_RGB_EQ(applyRecoveryLUT(RgbBlack(), value, recoveryLUT),
+ applyRecoveryLUT(RgbBlack(), value, recoveryLUTWithBoost));
+ EXPECT_RGB_EQ(applyRecoveryLUT(RgbWhite(), value, recoveryLUT),
+ applyRecoveryLUT(RgbWhite(), value, recoveryLUTWithBoost));
+ EXPECT_RGB_EQ(applyRecoveryLUT(RgbRed(), value, recoveryLUT),
+ applyRecoveryLUT(RgbRed(), value, recoveryLUTWithBoost));
+ EXPECT_RGB_EQ(applyRecoveryLUT(RgbGreen(), value, recoveryLUT),
+ applyRecoveryLUT(RgbGreen(), value, recoveryLUTWithBoost));
+ EXPECT_RGB_EQ(applyRecoveryLUT(RgbBlue(), value, recoveryLUT),
+ applyRecoveryLUT(RgbBlue(), value, recoveryLUTWithBoost));
}
}
for (int boost = 1; boost <= 10; boost++) {
- jpegr_metadata metadata = { .maxContentBoost = static_cast<float>(boost),
- .minContentBoost = 1.0f };
+ jpegr_metadata_struct metadata = { .maxContentBoost = static_cast<float>(boost),
+ .minContentBoost = 1.0f };
RecoveryLUT recoveryLUT(&metadata);
+ RecoveryLUT recoveryLUTWithBoost(&metadata, metadata.maxContentBoost);
for (int idx = 0; idx < kRecoveryFactorNumEntries; idx++) {
float value = static_cast<float>(idx) / static_cast<float>(kRecoveryFactorNumEntries - 1);
EXPECT_RGB_NEAR(applyRecovery(RgbBlack(), value, &metadata),
@@ -588,14 +600,25 @@
applyRecoveryLUT(RgbGreen(), value, recoveryLUT));
EXPECT_RGB_NEAR(applyRecovery(RgbBlue(), value, &metadata),
applyRecoveryLUT(RgbBlue(), value, recoveryLUT));
+ EXPECT_RGB_EQ(applyRecoveryLUT(RgbBlack(), value, recoveryLUT),
+ applyRecoveryLUT(RgbBlack(), value, recoveryLUTWithBoost));
+ EXPECT_RGB_EQ(applyRecoveryLUT(RgbWhite(), value, recoveryLUT),
+ applyRecoveryLUT(RgbWhite(), value, recoveryLUTWithBoost));
+ EXPECT_RGB_EQ(applyRecoveryLUT(RgbRed(), value, recoveryLUT),
+ applyRecoveryLUT(RgbRed(), value, recoveryLUTWithBoost));
+ EXPECT_RGB_EQ(applyRecoveryLUT(RgbGreen(), value, recoveryLUT),
+ applyRecoveryLUT(RgbGreen(), value, recoveryLUTWithBoost));
+ EXPECT_RGB_EQ(applyRecoveryLUT(RgbBlue(), value, recoveryLUT),
+ applyRecoveryLUT(RgbBlue(), value, recoveryLUTWithBoost));
}
}
for (int boost = 1; boost <= 10; boost++) {
- jpegr_metadata metadata = { .maxContentBoost = static_cast<float>(boost),
- .minContentBoost = 1.0f / pow(static_cast<float>(boost),
+ jpegr_metadata_struct metadata = { .maxContentBoost = static_cast<float>(boost),
+ .minContentBoost = 1.0f / pow(static_cast<float>(boost),
1.0f / 3.0f) };
RecoveryLUT recoveryLUT(&metadata);
+ RecoveryLUT recoveryLUTWithBoost(&metadata, metadata.maxContentBoost);
for (int idx = 0; idx < kRecoveryFactorNumEntries; idx++) {
float value = static_cast<float>(idx) / static_cast<float>(kRecoveryFactorNumEntries - 1);
EXPECT_RGB_NEAR(applyRecovery(RgbBlack(), value, &metadata),
@@ -608,6 +631,16 @@
applyRecoveryLUT(RgbGreen(), value, recoveryLUT));
EXPECT_RGB_NEAR(applyRecovery(RgbBlue(), value, &metadata),
applyRecoveryLUT(RgbBlue(), value, recoveryLUT));
+ EXPECT_RGB_EQ(applyRecoveryLUT(RgbBlack(), value, recoveryLUT),
+ applyRecoveryLUT(RgbBlack(), value, recoveryLUTWithBoost));
+ EXPECT_RGB_EQ(applyRecoveryLUT(RgbWhite(), value, recoveryLUT),
+ applyRecoveryLUT(RgbWhite(), value, recoveryLUTWithBoost));
+ EXPECT_RGB_EQ(applyRecoveryLUT(RgbRed(), value, recoveryLUT),
+ applyRecoveryLUT(RgbRed(), value, recoveryLUTWithBoost));
+ EXPECT_RGB_EQ(applyRecoveryLUT(RgbGreen(), value, recoveryLUT),
+ applyRecoveryLUT(RgbGreen(), value, recoveryLUTWithBoost));
+ EXPECT_RGB_EQ(applyRecoveryLUT(RgbBlue(), value, recoveryLUT),
+ applyRecoveryLUT(RgbBlue(), value, recoveryLUTWithBoost));
}
}
}
@@ -659,8 +692,8 @@
}
TEST_F(RecoveryMapMathTest, EncodeRecovery) {
- jpegr_metadata metadata = { .maxContentBoost = 4.0f,
- .minContentBoost = 1.0f / 4.0f };
+ jpegr_metadata_struct metadata = { .maxContentBoost = 4.0f,
+ .minContentBoost = 1.0f / 4.0f };
EXPECT_EQ(encodeRecovery(0.0f, 0.0f, &metadata), 127);
EXPECT_EQ(encodeRecovery(0.0f, 1.0f, &metadata), 127);
@@ -717,8 +750,9 @@
}
TEST_F(RecoveryMapMathTest, ApplyRecovery) {
- jpegr_metadata metadata = { .maxContentBoost = 4.0f,
- .minContentBoost = 1.0f / 4.0f };
+ jpegr_metadata_struct metadata = { .maxContentBoost = 4.0f,
+ .minContentBoost = 1.0f / 4.0f };
+ float displayBoost = metadata.maxContentBoost;
EXPECT_RGB_NEAR(applyRecovery(RgbBlack(), 0.0f, &metadata), RgbBlack());
EXPECT_RGB_NEAR(applyRecovery(RgbBlack(), 0.5f, &metadata), RgbBlack());
@@ -774,6 +808,19 @@
EXPECT_RGB_NEAR(applyRecovery(e, 0.5f, &metadata), e);
EXPECT_RGB_NEAR(applyRecovery(e, 0.75f, &metadata), e * 2.0f);
EXPECT_RGB_NEAR(applyRecovery(e, 1.0f, &metadata), e * 4.0f);
+
+ EXPECT_RGB_EQ(applyRecovery(RgbBlack(), 1.0f, &metadata),
+ applyRecovery(RgbBlack(), 1.0f, &metadata, displayBoost));
+ EXPECT_RGB_EQ(applyRecovery(RgbWhite(), 1.0f, &metadata),
+ applyRecovery(RgbWhite(), 1.0f, &metadata, displayBoost));
+ EXPECT_RGB_EQ(applyRecovery(RgbRed(), 1.0f, &metadata),
+ applyRecovery(RgbRed(), 1.0f, &metadata, displayBoost));
+ EXPECT_RGB_EQ(applyRecovery(RgbGreen(), 1.0f, &metadata),
+ applyRecovery(RgbGreen(), 1.0f, &metadata, displayBoost));
+ EXPECT_RGB_EQ(applyRecovery(RgbBlue(), 1.0f, &metadata),
+ applyRecovery(RgbBlue(), 1.0f, &metadata, displayBoost));
+ EXPECT_RGB_EQ(applyRecovery(e, 1.0f, &metadata),
+ applyRecovery(e, 1.0f, &metadata, displayBoost));
}
TEST_F(RecoveryMapMathTest, GetYuv420Pixel) {
@@ -981,8 +1028,8 @@
}
TEST_F(RecoveryMapMathTest, ApplyMap) {
- jpegr_metadata metadata = { .maxContentBoost = 8.0f,
- .minContentBoost = 1.0f / 8.0f };
+ jpegr_metadata_struct metadata = { .maxContentBoost = 8.0f,
+ .minContentBoost = 1.0f / 8.0f };
EXPECT_RGB_EQ(Recover(YuvWhite(), 1.0f, &metadata),
RgbWhite() * 8.0f);
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index cf927db..8060705 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -18,6 +18,7 @@
#include <android/hardware_buffer.h>
#include <android/hardware_buffer_aidl.h>
+#include <android/binder_libbinder.h>
#include <vndk/hardware_buffer.h>
#include <errno.h>
@@ -34,9 +35,6 @@
#include <android/hardware/graphics/common/1.1/types.h>
#include <aidl/android/hardware/graphics/common/PixelFormat.h>
-// TODO: Better way to handle this
-#include "../binder/ndk/parcel_internal.h"
-
static constexpr int kFdBufferSize = 128 * sizeof(int); // 128 ints
using namespace android;
@@ -421,7 +419,7 @@
AHardwareBuffer* _Nullable* _Nonnull outBuffer) {
if (!parcel || !outBuffer) return STATUS_BAD_VALUE;
auto buffer = sp<GraphicBuffer>::make();
- status_t status = parcel->get()->read(*buffer);
+ status_t status = AParcel_viewPlatformParcel(parcel)->read(*buffer);
if (status != STATUS_OK) return status;
*outBuffer = AHardwareBuffer_from_GraphicBuffer(buffer.get());
AHardwareBuffer_acquire(*outBuffer);
@@ -433,7 +431,7 @@
const GraphicBuffer* gb = AHardwareBuffer_to_GraphicBuffer(buffer);
if (!gb) return STATUS_BAD_VALUE;
if (!parcel) return STATUS_BAD_VALUE;
- return parcel->get()->write(*gb);
+ return AParcel_viewPlatformParcel(parcel)->write(*gb);
}
// ----------------------------------------------------------------------------
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 85a5249..21798d0 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -177,14 +177,14 @@
/**
* Corresponding formats:
* Vulkan: VK_FORMAT_R16_UINT
- * OpenGL ES: GR_GL_R16UI
+ * OpenGL ES: GL_R16UI
*/
AHARDWAREBUFFER_FORMAT_R16_UINT = 0x39,
/**
* Corresponding formats:
* Vulkan: VK_FORMAT_R16G16_UINT
- * OpenGL ES: GR_GL_RG16UI
+ * OpenGL ES: GL_RG16UI
*/
AHARDWAREBUFFER_FORMAT_R16G16_UINT = 0x3a,
diff --git a/libs/renderengine/skia/SkiaRenderEngine.cpp b/libs/renderengine/skia/SkiaRenderEngine.cpp
index 5965d41..e393fb2 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaRenderEngine.cpp
@@ -395,10 +395,14 @@
mRenderEngineType != RenderEngineType::SKIA_VK_THREADED) {
return;
}
- // We currently don't attempt to map a buffer if the buffer contains protected content
- // because GPU resources for protected buffers is much more limited.
+ // We don't attempt to map a buffer if the buffer contains protected content. In GL this is
+ // important because GPU resources for protected buffers are much more limited. (In Vk we
+ // simply match the existing behavior for protected buffers.) In Vk, we never cache any
+ // buffers while in a protected context, since Vk cannot share across contexts, and protected
+ // is less common.
const bool isProtectedBuffer = buffer->getUsage() & GRALLOC_USAGE_PROTECTED;
- if (isProtectedBuffer) {
+ if (isProtectedBuffer ||
+ (mRenderEngineType == RenderEngineType::SKIA_VK_THREADED && isProtected())) {
return;
}
ATRACE_CALL();
@@ -461,6 +465,20 @@
}
}
+std::shared_ptr<AutoBackendTexture::LocalRef> SkiaRenderEngine::getOrCreateBackendTexture(
+ const sp<GraphicBuffer>& buffer, bool isOutputBuffer) {
+ // Do not lookup the buffer in the cache for protected contexts with the SkiaVk back-end
+ if (mRenderEngineType == RenderEngineType::SKIA_GL_THREADED ||
+ (mRenderEngineType == RenderEngineType::SKIA_VK_THREADED && !isProtected())) {
+ if (const auto& it = mTextureCache.find(buffer->getId()); it != mTextureCache.end()) {
+ return it->second;
+ }
+ }
+ return std::make_shared<AutoBackendTexture::LocalRef>(getActiveGrContext(),
+ buffer->toAHardwareBuffer(),
+ isOutputBuffer, mTextureCleanupMgr);
+}
+
bool SkiaRenderEngine::canSkipPostRenderCleanup() const {
std::lock_guard<std::mutex> lock(mRenderingMutex);
return mTextureCleanupMgr.isEmpty();
@@ -651,21 +669,11 @@
validateOutputBufferUsage(buffer->getBuffer());
auto grContext = getActiveGrContext();
- auto& cache = mTextureCache;
// any AutoBackendTexture deletions will now be deferred until cleanupPostRender is called
DeferTextureCleanup dtc(mTextureCleanupMgr);
- std::shared_ptr<AutoBackendTexture::LocalRef> surfaceTextureRef;
- if (const auto& it = cache.find(buffer->getBuffer()->getId()); it != cache.end()) {
- surfaceTextureRef = it->second;
- } else {
- surfaceTextureRef =
- std::make_shared<AutoBackendTexture::LocalRef>(grContext,
- buffer->getBuffer()
- ->toAHardwareBuffer(),
- true, mTextureCleanupMgr);
- }
+ auto surfaceTextureRef = getOrCreateBackendTexture(buffer->getBuffer(), true);
// wait on the buffer to be ready to use prior to using it
waitFence(grContext, bufferFence);
@@ -904,21 +912,7 @@
ATRACE_NAME("DrawImage");
validateInputBufferUsage(layer.source.buffer.buffer->getBuffer());
const auto& item = layer.source.buffer;
- std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef = nullptr;
-
- if (const auto& iter = cache.find(item.buffer->getBuffer()->getId());
- iter != cache.end()) {
- imageTextureRef = iter->second;
- } else {
- // If we didn't find the image in the cache, then create a local ref but don't cache
- // it. If we're using skia, we're guaranteed to run on a dedicated GPU thread so if
- // we didn't find anything in the cache then we intentionally did not cache this
- // buffer's resources.
- imageTextureRef = std::make_shared<
- AutoBackendTexture::LocalRef>(grContext,
- item.buffer->getBuffer()->toAHardwareBuffer(),
- false, mTextureCleanupMgr);
- }
+ auto imageTextureRef = getOrCreateBackendTexture(item.buffer->getBuffer(), false);
// if the layer's buffer has a fence, then we must must respect the fence prior to using
// the buffer.
diff --git a/libs/renderengine/skia/SkiaRenderEngine.h b/libs/renderengine/skia/SkiaRenderEngine.h
index dd6646b..e4406b4 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.h
+++ b/libs/renderengine/skia/SkiaRenderEngine.h
@@ -133,6 +133,8 @@
void unmapExternalTextureBuffer(sp<GraphicBuffer>&& buffer) override final;
bool canSkipPostRenderCleanup() const override final;
+ std::shared_ptr<AutoBackendTexture::LocalRef> getOrCreateBackendTexture(
+ const sp<GraphicBuffer>& buffer, bool isOutputBuffer) REQUIRES(mRenderingMutex);
void initCanvas(SkCanvas* canvas, const DisplaySettings& display);
void drawShadow(SkCanvas* canvas, const SkRRect& casterRRect,
const ShadowSettings& shadowSettings);
@@ -167,7 +169,9 @@
// Number of external holders of ExternalTexture references, per GraphicBuffer ID.
std::unordered_map<GraphicBufferId, int32_t> mGraphicBufferExternalRefs
GUARDED_BY(mRenderingMutex);
- // Cache of GL textures that we'll store per GraphicBuffer ID, shared between GPU contexts.
+ // For GL, this cache is shared between protected and unprotected contexts. For Vulkan, it is
+ // only used for the unprotected context, because Vulkan does not allow sharing between
+ // contexts, and protected is less common.
std::unordered_map<GraphicBufferId, std::shared_ptr<AutoBackendTexture::LocalRef>> mTextureCache
GUARDED_BY(mRenderingMutex);
std::unordered_map<shaders::LinearEffect, sk_sp<SkRuntimeEffect>, shaders::LinearEffectHasher>
diff --git a/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp
index c3af996..b6274ab 100644
--- a/libs/ui/Gralloc4.cpp
+++ b/libs/ui/Gralloc4.cpp
@@ -766,162 +766,6 @@
gralloc4::encodeSmpte2094_10);
}
-template <class T>
-status_t Gralloc4Mapper::getDefault(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- const MetadataType& metadataType,
- DecodeFunction<T> decodeFunction, T* outMetadata) const {
- if (!outMetadata) {
- return BAD_VALUE;
- }
-
- IMapper::BufferDescriptorInfo descriptorInfo;
- if (auto error = sBufferDescriptorInfo("getDefault", width, height, format, layerCount, usage,
- &descriptorInfo) != OK) {
- return error;
- }
-
- hidl_vec<uint8_t> vec;
- Error error;
- auto ret = mMapper->getFromBufferDescriptorInfo(descriptorInfo, metadataType,
- [&](const auto& tmpError,
- const hidl_vec<uint8_t>& tmpVec) {
- error = tmpError;
- vec = tmpVec;
- });
-
- if (!ret.isOk()) {
- error = kTransactionError;
- }
-
- if (error != Error::NONE) {
- ALOGE("getDefault(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
- metadataType.value, error);
- return static_cast<status_t>(error);
- }
-
- return decodeFunction(vec, outMetadata);
-}
-
-status_t Gralloc4Mapper::getDefaultPixelFormatFourCC(uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- uint32_t* outPixelFormatFourCC) const {
- return getDefault(width, height, format, layerCount, usage,
- gralloc4::MetadataType_PixelFormatFourCC, gralloc4::decodePixelFormatFourCC,
- outPixelFormatFourCC);
-}
-
-status_t Gralloc4Mapper::getDefaultPixelFormatModifier(uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- uint64_t* outPixelFormatModifier) const {
- return getDefault(width, height, format, layerCount, usage,
- gralloc4::MetadataType_PixelFormatModifier,
- gralloc4::decodePixelFormatModifier, outPixelFormatModifier);
-}
-
-status_t Gralloc4Mapper::getDefaultAllocationSize(uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- uint64_t* outAllocationSize) const {
- return getDefault(width, height, format, layerCount, usage,
- gralloc4::MetadataType_AllocationSize, gralloc4::decodeAllocationSize,
- outAllocationSize);
-}
-
-status_t Gralloc4Mapper::getDefaultProtectedContent(uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- uint64_t* outProtectedContent) const {
- return getDefault(width, height, format, layerCount, usage,
- gralloc4::MetadataType_ProtectedContent, gralloc4::decodeProtectedContent,
- outProtectedContent);
-}
-
-status_t Gralloc4Mapper::getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- ExtendableType* outCompression) const {
- return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_Compression,
- gralloc4::decodeCompression, outCompression);
-}
-
-status_t Gralloc4Mapper::getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- ui::Compression* outCompression) const {
- if (!outCompression) {
- return BAD_VALUE;
- }
- ExtendableType compression;
- status_t error = getDefaultCompression(width, height, format, layerCount, usage, &compression);
- if (error) {
- return error;
- }
- if (!gralloc4::isStandardCompression(compression)) {
- return BAD_TYPE;
- }
- *outCompression = gralloc4::getStandardCompressionValue(compression);
- return NO_ERROR;
-}
-
-status_t Gralloc4Mapper::getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- ExtendableType* outInterlaced) const {
- return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_Interlaced,
- gralloc4::decodeInterlaced, outInterlaced);
-}
-
-status_t Gralloc4Mapper::getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- ui::Interlaced* outInterlaced) const {
- if (!outInterlaced) {
- return BAD_VALUE;
- }
- ExtendableType interlaced;
- status_t error = getDefaultInterlaced(width, height, format, layerCount, usage, &interlaced);
- if (error) {
- return error;
- }
- if (!gralloc4::isStandardInterlaced(interlaced)) {
- return BAD_TYPE;
- }
- *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
- return NO_ERROR;
-}
-
-status_t Gralloc4Mapper::getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- ExtendableType* outChromaSiting) const {
- return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_ChromaSiting,
- gralloc4::decodeChromaSiting, outChromaSiting);
-}
-
-status_t Gralloc4Mapper::getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- ui::ChromaSiting* outChromaSiting) const {
- if (!outChromaSiting) {
- return BAD_VALUE;
- }
- ExtendableType chromaSiting;
- status_t error =
- getDefaultChromaSiting(width, height, format, layerCount, usage, &chromaSiting);
- if (error) {
- return error;
- }
- if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
- return BAD_TYPE;
- }
- *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
- return NO_ERROR;
-}
-
-status_t Gralloc4Mapper::getDefaultPlaneLayouts(
- uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage,
- std::vector<ui::PlaneLayout>* outPlaneLayouts) const {
- return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_PlaneLayouts,
- gralloc4::decodePlaneLayouts, outPlaneLayouts);
-}
-
std::vector<MetadataTypeDescription> Gralloc4Mapper::listSupportedMetadataTypes() const {
hidl_vec<MetadataTypeDescription> descriptions;
Error error;
diff --git a/libs/ui/Gralloc5.cpp b/libs/ui/Gralloc5.cpp
index 6f196b8..514b45f 100644
--- a/libs/ui/Gralloc5.cpp
+++ b/libs/ui/Gralloc5.cpp
@@ -831,73 +831,4 @@
smpte2094_10);
}
-status_t Gralloc5Mapper::getDefaultPixelFormatFourCC(uint32_t, uint32_t, PixelFormat, uint32_t,
- uint64_t, uint32_t *) const {
- // TODO(b/261857910): Remove
- return UNKNOWN_TRANSACTION;
-}
-
-status_t Gralloc5Mapper::getDefaultPixelFormatModifier(uint32_t, uint32_t, PixelFormat, uint32_t,
- uint64_t, uint64_t *) const {
- // TODO(b/261857910): Remove
- return UNKNOWN_TRANSACTION;
-}
-
-status_t Gralloc5Mapper::getDefaultAllocationSize(uint32_t, uint32_t, PixelFormat, uint32_t,
- uint64_t, uint64_t *) const {
- // TODO(b/261857910): Remove
- return UNKNOWN_TRANSACTION;
-}
-
-status_t Gralloc5Mapper::getDefaultProtectedContent(uint32_t, uint32_t, PixelFormat, uint32_t,
- uint64_t, uint64_t *) const {
- // TODO(b/261857910): Remove
- return UNKNOWN_TRANSACTION;
-}
-
-status_t Gralloc5Mapper::getDefaultCompression(
- uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
- aidl::android::hardware::graphics::common::ExtendableType *) const {
- // TODO(b/261857910): Remove
- return UNKNOWN_TRANSACTION;
-}
-
-status_t Gralloc5Mapper::getDefaultCompression(uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
- ui::Compression *) const {
- // TODO(b/261857910): Remove
- return UNKNOWN_TRANSACTION;
-}
-
-status_t Gralloc5Mapper::getDefaultInterlaced(
- uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
- aidl::android::hardware::graphics::common::ExtendableType *) const {
- // TODO(b/261857910): Remove
- return UNKNOWN_TRANSACTION;
-}
-
-status_t Gralloc5Mapper::getDefaultInterlaced(uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
- ui::Interlaced *) const {
- // TODO(b/261857910): Remove
- return UNKNOWN_TRANSACTION;
-}
-
-status_t Gralloc5Mapper::getDefaultChromaSiting(
- uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
- aidl::android::hardware::graphics::common::ExtendableType *) const {
- // TODO(b/261857910): Remove
- return UNKNOWN_TRANSACTION;
-}
-
-status_t Gralloc5Mapper::getDefaultChromaSiting(uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
- ui::ChromaSiting *) const {
- // TODO(b/261857910): Remove
- return UNKNOWN_TRANSACTION;
-}
-
-status_t Gralloc5Mapper::getDefaultPlaneLayouts(uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
- std::vector<ui::PlaneLayout> *) const {
- // TODO(b/261857910): Remove
- return UNKNOWN_TRANSACTION;
-}
-
} // namespace android
\ No newline at end of file
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 6002a6d..7086e04 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -341,84 +341,5 @@
return mMapper->setSmpte2094_10(bufferHandle, smpte2094_10);
}
-status_t GraphicBufferMapper::getDefaultPixelFormatFourCC(uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- uint32_t* outPixelFormatFourCC) {
- return mMapper->getDefaultPixelFormatFourCC(width, height, format, layerCount, usage,
- outPixelFormatFourCC);
-}
-
-status_t GraphicBufferMapper::getDefaultPixelFormatModifier(uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- uint64_t* outPixelFormatModifier) {
- return mMapper->getDefaultPixelFormatModifier(width, height, format, layerCount, usage,
- outPixelFormatModifier);
-}
-
-status_t GraphicBufferMapper::getDefaultAllocationSize(uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- uint64_t* outAllocationSize) {
- return mMapper->getDefaultAllocationSize(width, height, format, layerCount, usage,
- outAllocationSize);
-}
-
-status_t GraphicBufferMapper::getDefaultProtectedContent(uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- uint64_t* outProtectedContent) {
- return mMapper->getDefaultProtectedContent(width, height, format, layerCount, usage,
- outProtectedContent);
-}
-
-status_t GraphicBufferMapper::getDefaultCompression(
- uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage,
- aidl::android::hardware::graphics::common::ExtendableType* outCompression) {
- return mMapper->getDefaultCompression(width, height, format, layerCount, usage, outCompression);
-}
-
-status_t GraphicBufferMapper::getDefaultCompression(uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- ui::Compression* outCompression) {
- return mMapper->getDefaultCompression(width, height, format, layerCount, usage, outCompression);
-}
-
-status_t GraphicBufferMapper::getDefaultInterlaced(
- uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage,
- aidl::android::hardware::graphics::common::ExtendableType* outInterlaced) {
- return mMapper->getDefaultInterlaced(width, height, format, layerCount, usage, outInterlaced);
-}
-
-status_t GraphicBufferMapper::getDefaultInterlaced(uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount,
- uint64_t usage, ui::Interlaced* outInterlaced) {
- return mMapper->getDefaultInterlaced(width, height, format, layerCount, usage, outInterlaced);
-}
-
-status_t GraphicBufferMapper::getDefaultChromaSiting(
- uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage,
- aidl::android::hardware::graphics::common::ExtendableType* outChromaSiting) {
- return mMapper->getDefaultChromaSiting(width, height, format, layerCount, usage,
- outChromaSiting);
-}
-
-status_t GraphicBufferMapper::getDefaultChromaSiting(uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- ui::ChromaSiting* outChromaSiting) {
- return mMapper->getDefaultChromaSiting(width, height, format, layerCount, usage,
- outChromaSiting);
-}
-
-status_t GraphicBufferMapper::getDefaultPlaneLayouts(
- uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage,
- std::vector<ui::PlaneLayout>* outPlaneLayouts) {
- return mMapper->getDefaultPlaneLayouts(width, height, format, layerCount, usage,
- outPlaneLayouts);
-}
-
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/libs/ui/include/ui/Gralloc.h b/libs/ui/include/ui/Gralloc.h
index b494cbe..496ba57 100644
--- a/libs/ui/include/ui/Gralloc.h
+++ b/libs/ui/include/ui/Gralloc.h
@@ -200,72 +200,6 @@
std::optional<std::vector<uint8_t>> /*smpte2094_10*/) const {
return INVALID_OPERATION;
}
- virtual status_t getDefaultPixelFormatFourCC(uint32_t /*width*/, uint32_t /*height*/,
- PixelFormat /*format*/, uint32_t /*layerCount*/,
- uint64_t /*usage*/,
- uint32_t* /*outPixelFormatFourCC*/) const {
- return INVALID_OPERATION;
- }
- virtual status_t getDefaultPixelFormatModifier(uint32_t /*width*/, uint32_t /*height*/,
- PixelFormat /*format*/, uint32_t /*layerCount*/,
- uint64_t /*usage*/,
- uint64_t* /*outPixelFormatModifier*/) const {
- return INVALID_OPERATION;
- }
- virtual status_t getDefaultAllocationSize(uint32_t /*width*/, uint32_t /*height*/,
- PixelFormat /*format*/, uint32_t /*layerCount*/,
- uint64_t /*usage*/,
- uint64_t* /*outAllocationSize*/) const {
- return INVALID_OPERATION;
- }
- virtual status_t getDefaultProtectedContent(uint32_t /*width*/, uint32_t /*height*/,
- PixelFormat /*format*/, uint32_t /*layerCount*/,
- uint64_t /*usage*/,
- uint64_t* /*outProtectedContent*/) const {
- return INVALID_OPERATION;
- }
- virtual status_t getDefaultCompression(
- uint32_t /*width*/, uint32_t /*height*/, PixelFormat /*format*/,
- uint32_t /*layerCount*/, uint64_t /*usage*/,
- aidl::android::hardware::graphics::common::ExtendableType* /*outCompression*/) const {
- return INVALID_OPERATION;
- }
- virtual status_t getDefaultCompression(uint32_t /*width*/, uint32_t /*height*/,
- PixelFormat /*format*/, uint32_t /*layerCount*/,
- uint64_t /*usage*/,
- ui::Compression* /*outCompression*/) const {
- return INVALID_OPERATION;
- }
- virtual status_t getDefaultInterlaced(
- uint32_t /*width*/, uint32_t /*height*/, PixelFormat /*format*/,
- uint32_t /*layerCount*/, uint64_t /*usage*/,
- aidl::android::hardware::graphics::common::ExtendableType* /*outInterlaced*/) const {
- return INVALID_OPERATION;
- }
- virtual status_t getDefaultInterlaced(uint32_t /*width*/, uint32_t /*height*/,
- PixelFormat /*format*/, uint32_t /*layerCount*/,
- uint64_t /*usage*/,
- ui::Interlaced* /*outInterlaced*/) const {
- return INVALID_OPERATION;
- }
- virtual status_t getDefaultChromaSiting(
- uint32_t /*width*/, uint32_t /*height*/, PixelFormat /*format*/,
- uint32_t /*layerCount*/, uint64_t /*usage*/,
- aidl::android::hardware::graphics::common::ExtendableType* /*outChromaSiting*/) const {
- return INVALID_OPERATION;
- }
- virtual status_t getDefaultChromaSiting(uint32_t /*width*/, uint32_t /*height*/,
- PixelFormat /*format*/, uint32_t /*layerCount*/,
- uint64_t /*usage*/,
- ui::ChromaSiting* /*outChromaSiting*/) const {
- return INVALID_OPERATION;
- }
- virtual status_t getDefaultPlaneLayouts(
- uint32_t /*width*/, uint32_t /*height*/, PixelFormat /*format*/,
- uint32_t /*layerCount*/, uint64_t /*usage*/,
- std::vector<ui::PlaneLayout>* /*outPlaneLayouts*/) const {
- return INVALID_OPERATION;
- }
};
// A wrapper to IAllocator
diff --git a/libs/ui/include/ui/Gralloc4.h b/libs/ui/include/ui/Gralloc4.h
index 6bc5ce5..df43be8 100644
--- a/libs/ui/include/ui/Gralloc4.h
+++ b/libs/ui/include/ui/Gralloc4.h
@@ -120,42 +120,6 @@
std::optional<std::vector<uint8_t>>* outSmpte2094_10) const override;
status_t setSmpte2094_10(buffer_handle_t bufferHandle,
std::optional<std::vector<uint8_t>> smpte2094_10) const override;
- status_t getDefaultPixelFormatFourCC(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- uint32_t* outPixelFormatFourCC) const override;
- status_t getDefaultPixelFormatModifier(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- uint64_t* outPixelFormatModifier) const override;
- status_t getDefaultAllocationSize(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- uint64_t* outAllocationSize) const override;
- status_t getDefaultProtectedContent(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- uint64_t* outProtectedContent) const override;
- status_t getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- aidl::android::hardware::graphics::common::ExtendableType*
- outCompression) const override;
- status_t getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- ui::Compression* outCompression) const override;
- status_t getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- aidl::android::hardware::graphics::common::ExtendableType*
- outInterlaced) const override;
- status_t getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- ui::Interlaced* outInterlaced) const override;
- status_t getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- aidl::android::hardware::graphics::common::ExtendableType*
- outChromaSiting) const override;
- status_t getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- ui::ChromaSiting* outChromaSiting) const override;
- status_t getDefaultPlaneLayouts(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- std::vector<ui::PlaneLayout>* outPlaneLayouts) const override;
std::vector<android::hardware::graphics::mapper::V4_0::IMapper::MetadataTypeDescription>
listSupportedMetadataTypes() const;
diff --git a/libs/ui/include/ui/Gralloc5.h b/libs/ui/include/ui/Gralloc5.h
index bc10169..44b97d1 100644
--- a/libs/ui/include/ui/Gralloc5.h
+++ b/libs/ui/include/ui/Gralloc5.h
@@ -156,60 +156,6 @@
buffer_handle_t bufferHandle,
std::optional<std::vector<uint8_t>> smpte2094_10) const override;
- [[nodiscard]] status_t getDefaultPixelFormatFourCC(
- uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
- uint64_t usage, uint32_t *outPixelFormatFourCC) const override;
-
- [[nodiscard]] status_t getDefaultPixelFormatModifier(
- uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
- uint64_t usage, uint64_t *outPixelFormatModifier) const override;
-
- [[nodiscard]] status_t getDefaultAllocationSize(uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- uint64_t *outAllocationSize) const override;
-
- [[nodiscard]] status_t getDefaultProtectedContent(uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- uint64_t *outProtectedContent) const override;
-
- [[nodiscard]] status_t getDefaultCompression(
- uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- aidl::android::hardware::graphics::common::ExtendableType *outCompression)
- const override;
-
- [[nodiscard]] status_t getDefaultCompression(uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- ui::Compression *outCompression) const override;
-
- [[nodiscard]] status_t getDefaultInterlaced(
- uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- aidl::android::hardware::graphics::common::ExtendableType *outInterlaced)
- const override;
-
- [[nodiscard]] status_t getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- ui::Interlaced *outInterlaced) const override;
-
- [[nodiscard]] status_t getDefaultChromaSiting(
- uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- aidl::android::hardware::graphics::common::ExtendableType *outChromaSiting)
- const override;
-
- [[nodiscard]] status_t getDefaultChromaSiting(uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- ui::ChromaSiting *outChromaSiting) const override;
-
- [[nodiscard]] status_t getDefaultPlaneLayouts(
- uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
- uint64_t usage, std::vector<ui::PlaneLayout> *outPlaneLayouts) const override;
-
private:
void unlockBlocking(buffer_handle_t bufferHandle) const;
diff --git a/libs/ui/include/ui/GraphicBufferMapper.h b/libs/ui/include/ui/GraphicBufferMapper.h
index 51c6e92..3a5167a 100644
--- a/libs/ui/include/ui/GraphicBufferMapper.h
+++ b/libs/ui/include/ui/GraphicBufferMapper.h
@@ -138,48 +138,6 @@
status_t setSmpte2094_10(buffer_handle_t bufferHandle,
std::optional<std::vector<uint8_t>> smpte2094_10);
- /**
- * Gets the default metadata for a gralloc buffer allocated with the given parameters.
- *
- * These functions are supported by gralloc 4.0+.
- */
- status_t getDefaultPixelFormatFourCC(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- uint32_t* outPixelFormatFourCC);
- status_t getDefaultPixelFormatModifier(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- uint64_t* outPixelFormatModifier);
- status_t getDefaultAllocationSize(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- uint64_t* outAllocationSize);
- status_t getDefaultProtectedContent(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- uint64_t* outProtectedContent);
- status_t getDefaultCompression(
- uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- aidl::android::hardware::graphics::common::ExtendableType* outCompression);
- status_t getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- ui::Compression* outCompression);
- status_t getDefaultInterlaced(
- uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- aidl::android::hardware::graphics::common::ExtendableType* outInterlaced);
- status_t getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- ui::Interlaced* outInterlaced);
- status_t getDefaultChromaSiting(
- uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
- uint64_t usage,
- aidl::android::hardware::graphics::common::ExtendableType* outChromaSiting);
- status_t getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- ui::ChromaSiting* outChromaSiting);
- status_t getDefaultPlaneLayouts(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage,
- std::vector<ui::PlaneLayout>* outPlaneLayouts);
-
const GrallocMapper& getGrallocMapper() const {
return reinterpret_cast<const GrallocMapper&>(*mMapper);
}
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 0b755aa..c2c856e 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -322,6 +322,16 @@
mExtensionString = gBuiltinExtensionString;
+ // b/269060366 Conditionally enabled EGL_ANDROID_get_frame_timestamps extension if the
+ // device's present timestamps are reliable (which may not be the case on emulators).
+ if (cnx->useAngle) {
+ if (android::base::GetBoolProperty("service.sf.present_timestamp", false)) {
+ mExtensionString.append("EGL_ANDROID_get_frame_timestamps");
+ }
+ } else {
+ mExtensionString.append("EGL_ANDROID_get_frame_timestamps");
+ }
+
hasColorSpaceSupport = findExtension(disp.queryString.extensions, "EGL_KHR_gl_colorspace");
// Note: CDD requires that devices supporting wide color and/or HDR color also support
@@ -361,6 +371,7 @@
findExtension(disp.queryString.extensions, "EGL_KHR_image_gl_colorspace")) {
mExtensionString.append("EGL_EXT_image_gl_colorspace ");
}
+
if (findExtension(disp.queryString.extensions, ext.c_str(), len)) {
mExtensionString.append(ext + " ");
}
diff --git a/opengl/libs/EGL/egl_platform_entries.cpp b/opengl/libs/EGL/egl_platform_entries.cpp
index 0527c8a..2bca14d 100644
--- a/opengl/libs/EGL/egl_platform_entries.cpp
+++ b/opengl/libs/EGL/egl_platform_entries.cpp
@@ -84,7 +84,8 @@
// Extensions implemented by the EGL wrapper.
const char* const gBuiltinExtensionString =
"EGL_ANDROID_front_buffer_auto_refresh "
- "EGL_ANDROID_get_frame_timestamps "
+ // b/269060366 Conditionally enabled during display initialization:
+ //"EGL_ANDROID_get_frame_timestamps "
"EGL_ANDROID_get_native_client_buffer "
"EGL_ANDROID_presentation_time "
"EGL_EXT_surface_CTA861_3_metadata "
@@ -2185,6 +2186,10 @@
return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
}
+ if (!dp->haveExtension("EGL_ANDROID_get_frame_timestamps")) {
+ return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
+ }
+
SurfaceRef _s(dp, surface);
if (!_s.get()) {
return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
@@ -2218,6 +2223,10 @@
return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
}
+ if (!dp->haveExtension("EGL_ANDROID_get_frame_timestamps")) {
+ return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
+ }
+
SurfaceRef _s(dp, surface);
if (!_s.get()) {
return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
@@ -2272,6 +2281,10 @@
return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
}
+ if (!dp->haveExtension("EGL_ANDROID_get_frame_timestamps")) {
+ return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
+ }
+
SurfaceRef _s(dp, surface);
if (!_s.get()) {
return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
@@ -2302,6 +2315,10 @@
return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
}
+ if (!dp->haveExtension("EGL_ANDROID_get_frame_timestamps")) {
+ return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
+ }
+
SurfaceRef _s(dp, surface);
if (!_s.get()) {
return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
@@ -2387,6 +2404,10 @@
return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
}
+ if (!dp->haveExtension("EGL_ANDROID_get_frame_timestamps")) {
+ return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
+ }
+
SurfaceRef _s(dp, surface);
if (!_s.get()) {
return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
diff --git a/services/gpuservice/vts/Android.bp b/services/gpuservice/vts/Android.bp
index 83a40e7..f4ea440 100644
--- a/services/gpuservice/vts/Android.bp
+++ b/services/gpuservice/vts/Android.bp
@@ -22,6 +22,7 @@
libs: [
"tradefed",
"vts-core-tradefed-harness",
+ "compatibility-host-util",
],
test_suites: [
"general-tests",
diff --git a/services/gpuservice/vts/OWNERS b/services/gpuservice/vts/OWNERS
index e789052..a63de1c 100644
--- a/services/gpuservice/vts/OWNERS
+++ b/services/gpuservice/vts/OWNERS
@@ -1,4 +1,5 @@
# Bug component: 653544
+kocdemir@google.com
paulthomson@google.com
pbaiget@google.com
lfy@google.com
diff --git a/services/gpuservice/vts/src/com/android/tests/gpuservice/GpuWorkTracepointTest.java b/services/gpuservice/vts/src/com/android/tests/gpuservice/GpuWorkTracepointTest.java
index 9fa9016..290a646 100644
--- a/services/gpuservice/vts/src/com/android/tests/gpuservice/GpuWorkTracepointTest.java
+++ b/services/gpuservice/vts/src/com/android/tests/gpuservice/GpuWorkTracepointTest.java
@@ -19,11 +19,16 @@
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
+import android.platform.test.annotations.RestrictedBuildTest;
+
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
import com.android.tradefed.util.CommandResult;
import com.android.tradefed.util.CommandStatus;
+import com.android.compatibility.common.util.PropertyUtil;
+import com.android.compatibility.common.util.GmsTest;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -57,15 +62,23 @@
commandResult.getStatus(), CommandStatus.SUCCESS);
}
+ @GmsTest(requirement = "VSR-3.3-004")
+ @RestrictedBuildTest
@Test
public void testGpuWorkPeriodTracepointFormat() throws Exception {
CommandResult commandResult = getDevice().executeShellV2Command(
String.format("cat %s", GPU_WORK_PERIOD_TRACEPOINT_FORMAT_PATH));
// If we failed to cat the tracepoint format then the test ends here.
- assumeTrue(String.format("Failed to cat the gpu_work_period tracepoint format at %s",
- GPU_WORK_PERIOD_TRACEPOINT_FORMAT_PATH),
- commandResult.getStatus().equals(CommandStatus.SUCCESS));
+ if (!commandResult.getStatus().equals(CommandStatus.SUCCESS)) {
+ String message = String.format(
+ "Failed to cat the gpu_work_period tracepoint format at %s\n",
+ GPU_WORK_PERIOD_TRACEPOINT_FORMAT_PATH);
+
+ // Tracepoint MUST exist on devices released with Android 14 or later
+ assumeTrue(message, PropertyUtil.getVsrApiLevel(getDevice()) >= 34);
+ fail(message);
+ }
// Otherwise, we check that the fields match the expected fields.
String actualFields = Arrays.stream(
diff --git a/services/inputflinger/host/InputDriver.cpp b/services/inputflinger/host/InputDriver.cpp
index 97d57e4..ec0388d 100644
--- a/services/inputflinger/host/InputDriver.cpp
+++ b/services/inputflinger/host/InputDriver.cpp
@@ -242,13 +242,13 @@
input_property_t* InputDriver::inputGetDeviceProperty(input_property_map_t* map, const char* key) {
if (map != nullptr) {
- std::string value;
- auto prop = std::make_unique<input_property_t>();
- if (!map->propertyMap->tryGetProperty(key, value)) {
+ std::optional<std::string> value = map->propertyMap->getString(key);
+ if (!value.has_value()) {
return nullptr;
}
+ auto prop = std::make_unique<input_property_t>();
prop->key = key;
- prop->value = value.c_str();
+ prop->value = value->c_str();
return prop.release();
}
return nullptr;
diff --git a/services/inputflinger/include/PointerControllerInterface.h b/services/inputflinger/include/PointerControllerInterface.h
index 9dbdd5a..95f819a 100644
--- a/services/inputflinger/include/PointerControllerInterface.h
+++ b/services/inputflinger/include/PointerControllerInterface.h
@@ -22,6 +22,20 @@
namespace android {
+struct FloatPoint {
+ float x;
+ float y;
+
+ inline FloatPoint(float x, float y) : x(x), y(y) {}
+
+ inline explicit FloatPoint(vec2 p) : x(p.x), y(p.y) {}
+
+ template <typename T, typename U>
+ operator std::tuple<T, U>() {
+ return {x, y};
+ }
+};
+
/**
* Interface for tracking a mouse / touch pad pointer and touch pad spots.
*
@@ -40,23 +54,16 @@
public:
/* Gets the bounds of the region that the pointer can traverse.
* Returns true if the bounds are available. */
- virtual bool getBounds(float* outMinX, float* outMinY,
- float* outMaxX, float* outMaxY) const = 0;
+ virtual std::optional<FloatRect> getBounds() const = 0;
/* Move the pointer. */
virtual void move(float deltaX, float deltaY) = 0;
- /* Sets a mask that indicates which buttons are pressed. */
- virtual void setButtonState(int32_t buttonState) = 0;
-
- /* Gets a mask that indicates which buttons are pressed. */
- virtual int32_t getButtonState() const = 0;
-
/* Sets the absolute location of the pointer. */
virtual void setPosition(float x, float y) = 0;
/* Gets the absolute location of the pointer. */
- virtual void getPosition(float* outX, float* outY) const = 0;
+ virtual FloatPoint getPosition() const = 0;
enum class Transition {
// Fade/unfade immediately.
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index 3d3a8ea..e65f3af 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -52,6 +52,7 @@
#include <utils/Timers.h>
#include <filesystem>
+#include <optional>
#include <regex>
#include <utility>
@@ -673,9 +674,9 @@
bool EventHub::Device::isExternalDeviceLocked() {
if (configuration) {
- bool value;
- if (configuration->tryGetProperty("device.internal", value)) {
- return !value;
+ std::optional<bool> isInternal = configuration->getBool("device.internal");
+ if (isInternal.has_value()) {
+ return !isInternal.value();
}
}
return identifier.bus == BUS_USB || identifier.bus == BUS_BLUETOOTH;
@@ -683,9 +684,9 @@
bool EventHub::Device::deviceHasMicLocked() {
if (configuration) {
- bool value;
- if (configuration->tryGetProperty("audio.mic", value)) {
- return value;
+ std::optional<bool> hasMic = configuration->getBool("audio.mic");
+ if (hasMic.has_value()) {
+ return hasMic.value();
}
}
return false;
@@ -2281,8 +2282,8 @@
}
// See if the device is specially configured to be of a certain type.
- std::string deviceType;
- if (device->configuration && device->configuration->tryGetProperty("device.type", deviceType)) {
+ if (device->configuration) {
+ std::string deviceType = device->configuration->getString("device.type").value_or("");
if (deviceType == "rotaryEncoder") {
device->classes |= InputDeviceClass::ROTARY_ENCODER;
} else if (deviceType == "externalStylus") {
diff --git a/services/inputflinger/reader/InputDevice.cpp b/services/inputflinger/reader/InputDevice.cpp
index 69363b6..ddf6c87 100644
--- a/services/inputflinger/reader/InputDevice.cpp
+++ b/services/inputflinger/reader/InputDevice.cpp
@@ -465,7 +465,7 @@
mHasMic, getAssociatedDisplayId().value_or(ADISPLAY_ID_NONE));
for_each_mapper(
- [&outDeviceInfo](InputMapper& mapper) { mapper.populateDeviceInfo(&outDeviceInfo); });
+ [&outDeviceInfo](InputMapper& mapper) { mapper.populateDeviceInfo(outDeviceInfo); });
if (mController) {
mController->populateDeviceInfo(&outDeviceInfo);
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
index 13e4d0c..83cf287 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
@@ -20,6 +20,8 @@
#include "CursorInputMapper.h"
+#include <optional>
+
#include "CursorButtonAccumulator.h"
#include "CursorScrollAccumulator.h"
#include "PointerControllerInterface.h"
@@ -79,30 +81,31 @@
return mSource;
}
-void CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+void CursorInputMapper::populateDeviceInfo(InputDeviceInfo& info) {
InputMapper::populateDeviceInfo(info);
if (mParameters.mode == Parameters::Mode::POINTER) {
- float minX, minY, maxX, maxY;
- if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
- info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f, 0.0f);
- info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, minY, maxY, 0.0f, 0.0f, 0.0f);
+ if (const auto bounds = mPointerController->getBounds(); bounds) {
+ info.addMotionRange(AMOTION_EVENT_AXIS_X, mSource, bounds->left, bounds->right, 0.0f,
+ 0.0f, 0.0f);
+ info.addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, bounds->top, bounds->bottom, 0.0f,
+ 0.0f, 0.0f);
}
} else {
- info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale, 0.0f);
- info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale, 0.0f);
- info->addMotionRange(AMOTION_EVENT_AXIS_RELATIVE_X, mSource, -1.0f, 1.0f, 0.0f, mXScale,
- 0.0f);
- info->addMotionRange(AMOTION_EVENT_AXIS_RELATIVE_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale,
- 0.0f);
+ info.addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale, 0.0f);
+ info.addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale, 0.0f);
+ info.addMotionRange(AMOTION_EVENT_AXIS_RELATIVE_X, mSource, -1.0f, 1.0f, 0.0f, mXScale,
+ 0.0f);
+ info.addMotionRange(AMOTION_EVENT_AXIS_RELATIVE_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale,
+ 0.0f);
}
- info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
+ info.addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
if (mCursorScrollAccumulator.haveRelativeVWheel()) {
- info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
+ info.addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
}
if (mCursorScrollAccumulator.haveRelativeHWheel()) {
- info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
+ info.addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
}
}
@@ -250,18 +253,17 @@
void CursorInputMapper::configureParameters() {
mParameters.mode = Parameters::Mode::POINTER;
- std::string cursorModeString;
- if (getDeviceContext().getConfiguration().tryGetProperty("cursor.mode", cursorModeString)) {
- if (cursorModeString == "navigation") {
+ const PropertyMap& config = getDeviceContext().getConfiguration();
+ std::optional<std::string> cursorModeString = config.getString("cursor.mode");
+ if (cursorModeString.has_value()) {
+ if (*cursorModeString == "navigation") {
mParameters.mode = Parameters::Mode::NAVIGATION;
- } else if (cursorModeString != "pointer" && cursorModeString != "default") {
- ALOGW("Invalid value for cursor.mode: '%s'", cursorModeString.c_str());
+ } else if (*cursorModeString != "pointer" && *cursorModeString != "default") {
+ ALOGW("Invalid value for cursor.mode: '%s'", cursorModeString->c_str());
}
}
- mParameters.orientationAware = false;
- getDeviceContext().getConfiguration().tryGetProperty("cursor.orientationAware",
- mParameters.orientationAware);
+ mParameters.orientationAware = config.getBool("cursor.orientationAware").value_or(false);
mParameters.hasAssociatedDisplay = false;
if (mParameters.mode == Parameters::Mode::POINTER || mParameters.orientationAware) {
@@ -371,15 +373,10 @@
if (moved) {
mPointerController->move(deltaX, deltaY);
}
-
- if (buttonsChanged) {
- mPointerController->setButtonState(currentButtonState);
- }
-
mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
}
- mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
+ std::tie(xCursorPosition, yCursorPosition) = mPointerController->getPosition();
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, xCursorPosition);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition);
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.h b/services/inputflinger/reader/mapper/CursorInputMapper.h
index 939cceb..5f02203 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.h
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.h
@@ -57,7 +57,7 @@
virtual ~CursorInputMapper();
virtual uint32_t getSources() const override;
- virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
+ virtual void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
virtual void dump(std::string& dump) override;
[[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
const InputReaderConfiguration* config,
diff --git a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp
index 2809939..a44d15b 100644
--- a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp
@@ -30,11 +30,11 @@
return AINPUT_SOURCE_STYLUS;
}
-void ExternalStylusInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+void ExternalStylusInputMapper::populateDeviceInfo(InputDeviceInfo& info) {
InputMapper::populateDeviceInfo(info);
if (mRawPressureAxis.valid) {
- info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, AINPUT_SOURCE_STYLUS, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f);
+ info.addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, AINPUT_SOURCE_STYLUS, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f);
}
}
diff --git a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h
index b6c9055..11b5315 100644
--- a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h
+++ b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h
@@ -30,7 +30,7 @@
virtual ~ExternalStylusInputMapper() = default;
uint32_t getSources() const override;
- void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
+ void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
void dump(std::string& dump) override;
[[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
const InputReaderConfiguration* config,
diff --git a/services/inputflinger/reader/mapper/InputMapper.cpp b/services/inputflinger/reader/mapper/InputMapper.cpp
index ba2ea99..9cf3696 100644
--- a/services/inputflinger/reader/mapper/InputMapper.cpp
+++ b/services/inputflinger/reader/mapper/InputMapper.cpp
@@ -29,8 +29,8 @@
InputMapper::~InputMapper() {}
-void InputMapper::populateDeviceInfo(InputDeviceInfo* info) {
- info->addSource(getSources());
+void InputMapper::populateDeviceInfo(InputDeviceInfo& info) {
+ info.addSource(getSources());
}
void InputMapper::dump(std::string& dump) {}
diff --git a/services/inputflinger/reader/mapper/InputMapper.h b/services/inputflinger/reader/mapper/InputMapper.h
index 104305b..2722edd 100644
--- a/services/inputflinger/reader/mapper/InputMapper.h
+++ b/services/inputflinger/reader/mapper/InputMapper.h
@@ -51,7 +51,7 @@
inline InputReaderPolicyInterface* getPolicy() { return getContext()->getPolicy(); }
virtual uint32_t getSources() const = 0;
- virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+ virtual void populateDeviceInfo(InputDeviceInfo& deviceInfo);
virtual void dump(std::string& dump);
[[nodiscard]] virtual std::list<NotifyArgs> configure(nsecs_t when,
const InputReaderConfiguration* config,
diff --git a/services/inputflinger/reader/mapper/JoystickInputMapper.cpp b/services/inputflinger/reader/mapper/JoystickInputMapper.cpp
index d7f8b17..7724cf7 100644
--- a/services/inputflinger/reader/mapper/JoystickInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/JoystickInputMapper.cpp
@@ -29,7 +29,7 @@
return AINPUT_SOURCE_JOYSTICK;
}
-void JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+void JoystickInputMapper::populateDeviceInfo(InputDeviceInfo& info) {
InputMapper::populateDeviceInfo(info);
for (const auto& [_, axis] : mAxes) {
@@ -41,16 +41,16 @@
}
}
-void JoystickInputMapper::addMotionRange(int32_t axisId, const Axis& axis, InputDeviceInfo* info) {
- info->addMotionRange(axisId, AINPUT_SOURCE_JOYSTICK, axis.min, axis.max, axis.flat, axis.fuzz,
- axis.resolution);
+void JoystickInputMapper::addMotionRange(int32_t axisId, const Axis& axis, InputDeviceInfo& info) {
+ info.addMotionRange(axisId, AINPUT_SOURCE_JOYSTICK, axis.min, axis.max, axis.flat, axis.fuzz,
+ axis.resolution);
/* In order to ease the transition for developers from using the old axes
* to the newer, more semantically correct axes, we'll continue to register
* the old axes as duplicates of their corresponding new ones. */
int32_t compatAxis = getCompatAxis(axisId);
if (compatAxis >= 0) {
- info->addMotionRange(compatAxis, AINPUT_SOURCE_JOYSTICK, axis.min, axis.max, axis.flat,
- axis.fuzz, axis.resolution);
+ info.addMotionRange(compatAxis, AINPUT_SOURCE_JOYSTICK, axis.min, axis.max, axis.flat,
+ axis.fuzz, axis.resolution);
}
}
diff --git a/services/inputflinger/reader/mapper/JoystickInputMapper.h b/services/inputflinger/reader/mapper/JoystickInputMapper.h
index 72b8a52..9ca4176 100644
--- a/services/inputflinger/reader/mapper/JoystickInputMapper.h
+++ b/services/inputflinger/reader/mapper/JoystickInputMapper.h
@@ -26,7 +26,7 @@
virtual ~JoystickInputMapper();
virtual uint32_t getSources() const override;
- virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
+ virtual void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
virtual void dump(std::string& dump) override;
[[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
const InputReaderConfiguration* config,
@@ -106,7 +106,7 @@
static bool isCenteredAxis(int32_t axis);
static int32_t getCompatAxis(int32_t axis);
- static void addMotionRange(int32_t axisId, const Axis& axis, InputDeviceInfo* info);
+ static void addMotionRange(int32_t axisId, const Axis& axis, InputDeviceInfo& info);
static void setPointerCoordsAxisValue(PointerCoords* pointerCoords, int32_t axis, float value);
};
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
index dc0454d..269c106 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
@@ -85,18 +85,18 @@
return ADISPLAY_ID_NONE;
}
-void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo& info) {
InputMapper::populateDeviceInfo(info);
- info->setKeyboardType(mKeyboardType);
- info->setKeyCharacterMap(getDeviceContext().getKeyCharacterMap());
+ info.setKeyboardType(mKeyboardType);
+ info.setKeyCharacterMap(getDeviceContext().getKeyCharacterMap());
if (mKeyboardLayoutInfo) {
- info->setKeyboardLayoutInfo(*mKeyboardLayoutInfo);
+ info.setKeyboardLayoutInfo(*mKeyboardLayoutInfo);
} else {
std::optional<RawLayoutInfo> layoutInfo = getDeviceContext().getRawLayoutInfo();
if (layoutInfo) {
- info->setKeyboardLayoutInfo(
+ info.setKeyboardLayoutInfo(
KeyboardLayoutInfo(layoutInfo->languageTag, layoutInfo->layoutType));
}
}
@@ -154,15 +154,10 @@
}
void KeyboardInputMapper::configureParameters() {
- mParameters.orientationAware = false;
const PropertyMap& config = getDeviceContext().getConfiguration();
- config.tryGetProperty("keyboard.orientationAware", mParameters.orientationAware);
-
- mParameters.handlesKeyRepeat = false;
- config.tryGetProperty("keyboard.handlesKeyRepeat", mParameters.handlesKeyRepeat);
-
- mParameters.doNotWakeByDefault = false;
- config.tryGetProperty("keyboard.doNotWakeByDefault", mParameters.doNotWakeByDefault);
+ mParameters.orientationAware = config.getBool("keyboard.orientationAware").value_or(false);
+ mParameters.handlesKeyRepeat = config.getBool("keyboard.handlesKeyRepeat").value_or(false);
+ mParameters.doNotWakeByDefault = config.getBool("keyboard.doNotWakeByDefault").value_or(false);
}
void KeyboardInputMapper::dumpParameters(std::string& dump) const {
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.h b/services/inputflinger/reader/mapper/KeyboardInputMapper.h
index da5b8ee..2fc82c3 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.h
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.h
@@ -27,7 +27,7 @@
~KeyboardInputMapper() override = default;
uint32_t getSources() const override;
- void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
+ void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
void dump(std::string& dump) override;
[[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
const InputReaderConfiguration* config,
diff --git a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
index 19a79d7..94cc145 100644
--- a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
@@ -20,6 +20,8 @@
#include "RotaryEncoderInputMapper.h"
+#include <optional>
+
#include "CursorScrollAccumulator.h"
namespace android {
@@ -35,22 +37,23 @@
return mSource;
}
-void RotaryEncoderInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+void RotaryEncoderInputMapper::populateDeviceInfo(InputDeviceInfo& info) {
InputMapper::populateDeviceInfo(info);
if (mRotaryEncoderScrollAccumulator.haveRelativeVWheel()) {
- float res = 0.0f;
- if (!getDeviceContext().getConfiguration().tryGetProperty("device.res", res)) {
+ const PropertyMap& config = getDeviceContext().getConfiguration();
+ std::optional<float> res = config.getFloat("device.res");
+ if (!res.has_value()) {
ALOGW("Rotary Encoder device configuration file didn't specify resolution!\n");
}
- if (!getDeviceContext().getConfiguration().tryGetProperty("device.scalingFactor",
- mScalingFactor)) {
+ std::optional<float> scalingFactor = config.getFloat("device.scalingFactor");
+ if (!scalingFactor.has_value()) {
ALOGW("Rotary Encoder device configuration file didn't specify scaling factor,"
"default to 1.0!\n");
- mScalingFactor = 1.0f;
}
- info->addMotionRange(AMOTION_EVENT_AXIS_SCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
- res * mScalingFactor);
+ mScalingFactor = scalingFactor.value_or(1.0f);
+ info.addMotionRange(AMOTION_EVENT_AXIS_SCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
+ res.value_or(0.0f) * mScalingFactor);
}
}
diff --git a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
index cb5fd88..a0516c4 100644
--- a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
+++ b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
@@ -29,7 +29,7 @@
virtual ~RotaryEncoderInputMapper();
virtual uint32_t getSources() const override;
- virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
+ virtual void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
virtual void dump(std::string& dump) override;
[[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
const InputReaderConfiguration* config,
diff --git a/services/inputflinger/reader/mapper/SensorInputMapper.cpp b/services/inputflinger/reader/mapper/SensorInputMapper.cpp
index 3d60bfd..60e6727 100644
--- a/services/inputflinger/reader/mapper/SensorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/SensorInputMapper.cpp
@@ -61,12 +61,6 @@
return AINPUT_SOURCE_SENSOR;
}
-template <typename T>
-bool SensorInputMapper::tryGetProperty(std::string keyName, T& outValue) {
- const auto& config = getDeviceContext().getConfiguration();
- return config.tryGetProperty(keyName, outValue);
-}
-
void SensorInputMapper::parseSensorConfiguration(InputDeviceSensorType sensorType, int32_t absCode,
int32_t sensorDataIndex, const Axis& axis) {
auto it = mSensors.find(sensorType);
@@ -79,12 +73,12 @@
}
}
-void SensorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+void SensorInputMapper::populateDeviceInfo(InputDeviceInfo& info) {
InputMapper::populateDeviceInfo(info);
for (const auto& [sensorType, sensor] : mSensors) {
- info->addSensorInfo(sensor.sensorInfo);
- info->setHasSensor(true);
+ info.addSensorInfo(sensor.sensorInfo);
+ info.setHasSensor(true);
}
}
@@ -201,6 +195,17 @@
SensorInputMapper::Sensor SensorInputMapper::createSensor(InputDeviceSensorType sensorType,
const Axis& axis) {
InputDeviceIdentifier identifier = getDeviceContext().getDeviceIdentifier();
+ const auto& config = getDeviceContext().getConfiguration();
+
+ std::string prefix = "sensor." + ftl::enum_string(sensorType);
+ transform(prefix.begin(), prefix.end(), prefix.begin(), ::tolower);
+
+ int32_t flags = 0;
+ std::optional<int32_t> reportingMode = config.getInt(prefix + ".reportingMode");
+ if (reportingMode.has_value()) {
+ flags |= (*reportingMode & REPORTING_MODE_MASK) << REPORTING_MODE_SHIFT;
+ }
+
// Sensor Id will be assigned to device Id to distinguish same sensor from multiple input
// devices, in such a way that the sensor Id will be same as input device Id.
// The sensorType is to distinguish different sensors within one device.
@@ -209,28 +214,15 @@
identifier.version, sensorType,
InputDeviceSensorAccuracy::ACCURACY_HIGH,
/*maxRange=*/axis.max, /*resolution=*/axis.scale,
- /*power=*/0.0f, /*minDelay=*/0,
- /*fifoReservedEventCount=*/0, /*fifoMaxEventCount=*/0,
- ftl::enum_string(sensorType), /*maxDelay=*/0, /*flags=*/0,
- getDeviceId());
-
- std::string prefix = "sensor." + ftl::enum_string(sensorType);
- transform(prefix.begin(), prefix.end(), prefix.begin(), ::tolower);
-
- int32_t reportingMode = 0;
- if (tryGetProperty(prefix + ".reportingMode", reportingMode)) {
- sensorInfo.flags |= (reportingMode & REPORTING_MODE_MASK) << REPORTING_MODE_SHIFT;
- }
-
- tryGetProperty(prefix + ".maxDelay", sensorInfo.maxDelay);
-
- tryGetProperty(prefix + ".minDelay", sensorInfo.minDelay);
-
- tryGetProperty(prefix + ".power", sensorInfo.power);
-
- tryGetProperty(prefix + ".fifoReservedEventCount", sensorInfo.fifoReservedEventCount);
-
- tryGetProperty(prefix + ".fifoMaxEventCount", sensorInfo.fifoMaxEventCount);
+ /*power=*/config.getFloat(prefix + ".power").value_or(0.0f),
+ /*minDelay=*/config.getInt(prefix + ".minDelay").value_or(0),
+ /*fifoReservedEventCount=*/
+ config.getInt(prefix + ".fifoReservedEventCount").value_or(0),
+ /*fifoMaxEventCount=*/
+ config.getInt(prefix + ".fifoMaxEventCount").value_or(0),
+ ftl::enum_string(sensorType),
+ /*maxDelay=*/config.getInt(prefix + ".maxDelay").value_or(0),
+ /*flags=*/flags, getDeviceId());
return Sensor(sensorInfo);
}
diff --git a/services/inputflinger/reader/mapper/SensorInputMapper.h b/services/inputflinger/reader/mapper/SensorInputMapper.h
index 457567b..7f47df7 100644
--- a/services/inputflinger/reader/mapper/SensorInputMapper.h
+++ b/services/inputflinger/reader/mapper/SensorInputMapper.h
@@ -16,6 +16,9 @@
#pragma once
+#include <optional>
+#include <string>
+
#include "InputMapper.h"
namespace android {
@@ -28,7 +31,7 @@
~SensorInputMapper() override;
uint32_t getSources() const override;
- void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
+ void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
void dump(std::string& dump) override;
[[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
const InputReaderConfiguration* config,
@@ -120,9 +123,6 @@
[[nodiscard]] std::list<NotifyArgs> sync(nsecs_t when, bool force);
- template <typename T>
- bool tryGetProperty(std::string keyName, T& outValue);
-
void parseSensorConfiguration(InputDeviceSensorType sensorType, int32_t absCode,
int32_t sensorDataIndex, const Axis& axis);
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index 96c163d..df7ba49 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -134,16 +134,16 @@
return mSource;
}
-void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+void TouchInputMapper::populateDeviceInfo(InputDeviceInfo& info) {
InputMapper::populateDeviceInfo(info);
if (mDeviceMode == DeviceMode::DISABLED) {
return;
}
- info->addMotionRange(mOrientedRanges.x);
- info->addMotionRange(mOrientedRanges.y);
- info->addMotionRange(mOrientedRanges.pressure);
+ info.addMotionRange(mOrientedRanges.x);
+ info.addMotionRange(mOrientedRanges.y);
+ info.addMotionRange(mOrientedRanges.pressure);
if (mDeviceMode == DeviceMode::UNSCALED && mSource == AINPUT_SOURCE_TOUCHPAD) {
// Populate RELATIVE_X and RELATIVE_Y motion ranges for touchpad capture mode.
@@ -153,46 +153,46 @@
// touchpad in one sample cycle.
const InputDeviceInfo::MotionRange& x = mOrientedRanges.x;
const InputDeviceInfo::MotionRange& y = mOrientedRanges.y;
- info->addMotionRange(AMOTION_EVENT_AXIS_RELATIVE_X, mSource, -x.max, x.max, x.flat, x.fuzz,
- x.resolution);
- info->addMotionRange(AMOTION_EVENT_AXIS_RELATIVE_Y, mSource, -y.max, y.max, y.flat, y.fuzz,
- y.resolution);
+ info.addMotionRange(AMOTION_EVENT_AXIS_RELATIVE_X, mSource, -x.max, x.max, x.flat, x.fuzz,
+ x.resolution);
+ info.addMotionRange(AMOTION_EVENT_AXIS_RELATIVE_Y, mSource, -y.max, y.max, y.flat, y.fuzz,
+ y.resolution);
}
if (mOrientedRanges.size) {
- info->addMotionRange(*mOrientedRanges.size);
+ info.addMotionRange(*mOrientedRanges.size);
}
if (mOrientedRanges.touchMajor) {
- info->addMotionRange(*mOrientedRanges.touchMajor);
- info->addMotionRange(*mOrientedRanges.touchMinor);
+ info.addMotionRange(*mOrientedRanges.touchMajor);
+ info.addMotionRange(*mOrientedRanges.touchMinor);
}
if (mOrientedRanges.toolMajor) {
- info->addMotionRange(*mOrientedRanges.toolMajor);
- info->addMotionRange(*mOrientedRanges.toolMinor);
+ info.addMotionRange(*mOrientedRanges.toolMajor);
+ info.addMotionRange(*mOrientedRanges.toolMinor);
}
if (mOrientedRanges.orientation) {
- info->addMotionRange(*mOrientedRanges.orientation);
+ info.addMotionRange(*mOrientedRanges.orientation);
}
if (mOrientedRanges.distance) {
- info->addMotionRange(*mOrientedRanges.distance);
+ info.addMotionRange(*mOrientedRanges.distance);
}
if (mOrientedRanges.tilt) {
- info->addMotionRange(*mOrientedRanges.tilt);
+ info.addMotionRange(*mOrientedRanges.tilt);
}
if (mCursorScrollAccumulator.haveRelativeVWheel()) {
- info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
+ info.addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
}
if (mCursorScrollAccumulator.haveRelativeHWheel()) {
- info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
+ info.addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
}
- info->setButtonUnderPad(mParameters.hasButtonUnderPad);
- info->setUsiVersion(mParameters.usiVersion);
+ info.setButtonUnderPad(mParameters.hasButtonUnderPad);
+ info.setUsiVersion(mParameters.usiVersion);
}
void TouchInputMapper::dump(std::string& dump) {
@@ -366,15 +366,15 @@
? Parameters::GestureMode::SINGLE_TOUCH
: Parameters::GestureMode::MULTI_TOUCH;
- std::string gestureModeString;
- if (getDeviceContext().getConfiguration().tryGetProperty("touch.gestureMode",
- gestureModeString)) {
- if (gestureModeString == "single-touch") {
+ const PropertyMap& config = getDeviceContext().getConfiguration();
+ std::optional<std::string> gestureModeString = config.getString("touch.gestureMode");
+ if (gestureModeString.has_value()) {
+ if (*gestureModeString == "single-touch") {
mParameters.gestureMode = Parameters::GestureMode::SINGLE_TOUCH;
- } else if (gestureModeString == "multi-touch") {
+ } else if (*gestureModeString == "multi-touch") {
mParameters.gestureMode = Parameters::GestureMode::MULTI_TOUCH;
- } else if (gestureModeString != "default") {
- ALOGW("Invalid value for touch.gestureMode: '%s'", gestureModeString.c_str());
+ } else if (*gestureModeString != "default") {
+ ALOGW("Invalid value for touch.gestureMode: '%s'", gestureModeString->c_str());
}
}
@@ -382,24 +382,23 @@
mParameters.hasButtonUnderPad = getDeviceContext().hasInputProperty(INPUT_PROP_BUTTONPAD);
- mParameters.orientationAware = mParameters.deviceType == Parameters::DeviceType::TOUCH_SCREEN;
- getDeviceContext().getConfiguration().tryGetProperty("touch.orientationAware",
- mParameters.orientationAware);
+ mParameters.orientationAware =
+ config.getBool("touch.orientationAware")
+ .value_or(mParameters.deviceType == Parameters::DeviceType::TOUCH_SCREEN);
mParameters.orientation = ui::ROTATION_0;
- std::string orientationString;
- if (getDeviceContext().getConfiguration().tryGetProperty("touch.orientation",
- orientationString)) {
+ std::optional<std::string> orientationString = config.getString("touch.orientation");
+ if (orientationString.has_value()) {
if (mParameters.deviceType != Parameters::DeviceType::TOUCH_SCREEN) {
ALOGW("The configuration 'touch.orientation' is only supported for touchscreens.");
- } else if (orientationString == "ORIENTATION_90") {
+ } else if (*orientationString == "ORIENTATION_90") {
mParameters.orientation = ui::ROTATION_90;
- } else if (orientationString == "ORIENTATION_180") {
+ } else if (*orientationString == "ORIENTATION_180") {
mParameters.orientation = ui::ROTATION_180;
- } else if (orientationString == "ORIENTATION_270") {
+ } else if (*orientationString == "ORIENTATION_270") {
mParameters.orientation = ui::ROTATION_270;
- } else if (orientationString != "ORIENTATION_0") {
- ALOGW("Invalid value for touch.orientation: '%s'", orientationString.c_str());
+ } else if (*orientationString != "ORIENTATION_0") {
+ ALOGW("Invalid value for touch.orientation: '%s'", orientationString->c_str());
}
}
@@ -413,10 +412,7 @@
mParameters.hasAssociatedDisplay = true;
if (mParameters.deviceType == Parameters::DeviceType::TOUCH_SCREEN) {
mParameters.associatedDisplayIsExternal = getDeviceContext().isExternal();
- std::string uniqueDisplayId;
- getDeviceContext().getConfiguration().tryGetProperty("touch.displayId",
- uniqueDisplayId);
- mParameters.uniqueDisplayId = uniqueDisplayId.c_str();
+ mParameters.uniqueDisplayId = config.getString("touch.displayId").value_or("").c_str();
}
}
if (getDeviceContext().getAssociatedDisplayPort()) {
@@ -426,20 +422,19 @@
// Initial downs on external touch devices should wake the device.
// Normally we don't do this for internal touch screens to prevent them from waking
// up in your pocket but you can enable it using the input device configuration.
- mParameters.wake = getDeviceContext().isExternal();
- getDeviceContext().getConfiguration().tryGetProperty("touch.wake", mParameters.wake);
+ mParameters.wake = config.getBool("touch.wake").value_or(getDeviceContext().isExternal());
- InputDeviceUsiVersion usiVersion;
- if (getDeviceContext().getConfiguration().tryGetProperty("touch.usiVersionMajor",
- usiVersion.majorVersion) &&
- getDeviceContext().getConfiguration().tryGetProperty("touch.usiVersionMinor",
- usiVersion.minorVersion)) {
- mParameters.usiVersion = usiVersion;
+ std::optional<int32_t> usiVersionMajor = config.getInt("touch.usiVersionMajor");
+ std::optional<int32_t> usiVersionMinor = config.getInt("touch.usiVersionMinor");
+ if (usiVersionMajor.has_value() && usiVersionMinor.has_value()) {
+ mParameters.usiVersion = {
+ .majorVersion = *usiVersionMajor,
+ .minorVersion = *usiVersionMinor,
+ };
}
- mParameters.enableForInactiveViewport = false;
- getDeviceContext().getConfiguration().tryGetProperty("touch.enableForInactiveViewport",
- mParameters.enableForInactiveViewport);
+ mParameters.enableForInactiveViewport =
+ config.getBool("touch.enableForInactiveViewport").value_or(false);
}
void TouchInputMapper::configureDeviceType() {
@@ -457,7 +452,8 @@
// Type association takes precedence over the device type found in the idc file.
std::string deviceTypeString = getDeviceContext().getDeviceTypeAssociation().value_or("");
if (deviceTypeString.empty()) {
- getDeviceContext().getConfiguration().tryGetProperty("touch.deviceType", deviceTypeString);
+ deviceTypeString =
+ getDeviceContext().getConfiguration().getString("touch.deviceType").value_or("");
}
if (deviceTypeString == "touchScreen") {
mParameters.deviceType = Parameters::DeviceType::TOUCH_SCREEN;
@@ -1160,92 +1156,79 @@
// Size
out.sizeCalibration = Calibration::SizeCalibration::DEFAULT;
- std::string sizeCalibrationString;
- if (in.tryGetProperty("touch.size.calibration", sizeCalibrationString)) {
- if (sizeCalibrationString == "none") {
+ std::optional<std::string> sizeCalibrationString = in.getString("touch.size.calibration");
+ if (sizeCalibrationString.has_value()) {
+ if (*sizeCalibrationString == "none") {
out.sizeCalibration = Calibration::SizeCalibration::NONE;
- } else if (sizeCalibrationString == "geometric") {
+ } else if (*sizeCalibrationString == "geometric") {
out.sizeCalibration = Calibration::SizeCalibration::GEOMETRIC;
- } else if (sizeCalibrationString == "diameter") {
+ } else if (*sizeCalibrationString == "diameter") {
out.sizeCalibration = Calibration::SizeCalibration::DIAMETER;
- } else if (sizeCalibrationString == "box") {
+ } else if (*sizeCalibrationString == "box") {
out.sizeCalibration = Calibration::SizeCalibration::BOX;
- } else if (sizeCalibrationString == "area") {
+ } else if (*sizeCalibrationString == "area") {
out.sizeCalibration = Calibration::SizeCalibration::AREA;
- } else if (sizeCalibrationString != "default") {
- ALOGW("Invalid value for touch.size.calibration: '%s'", sizeCalibrationString.c_str());
+ } else if (*sizeCalibrationString != "default") {
+ ALOGW("Invalid value for touch.size.calibration: '%s'", sizeCalibrationString->c_str());
}
}
- float sizeScale;
-
- if (in.tryGetProperty("touch.size.scale", sizeScale)) {
- out.sizeScale = sizeScale;
- }
- float sizeBias;
- if (in.tryGetProperty("touch.size.bias", sizeBias)) {
- out.sizeBias = sizeBias;
- }
- bool sizeIsSummed;
- if (in.tryGetProperty("touch.size.isSummed", sizeIsSummed)) {
- out.sizeIsSummed = sizeIsSummed;
- }
+ out.sizeScale = in.getFloat("touch.size.scale");
+ out.sizeBias = in.getFloat("touch.size.bias");
+ out.sizeIsSummed = in.getBool("touch.size.isSummed");
// Pressure
out.pressureCalibration = Calibration::PressureCalibration::DEFAULT;
- std::string pressureCalibrationString;
- if (in.tryGetProperty("touch.pressure.calibration", pressureCalibrationString)) {
- if (pressureCalibrationString == "none") {
+ std::optional<std::string> pressureCalibrationString =
+ in.getString("touch.pressure.calibration");
+ if (pressureCalibrationString.has_value()) {
+ if (*pressureCalibrationString == "none") {
out.pressureCalibration = Calibration::PressureCalibration::NONE;
- } else if (pressureCalibrationString == "physical") {
+ } else if (*pressureCalibrationString == "physical") {
out.pressureCalibration = Calibration::PressureCalibration::PHYSICAL;
- } else if (pressureCalibrationString == "amplitude") {
+ } else if (*pressureCalibrationString == "amplitude") {
out.pressureCalibration = Calibration::PressureCalibration::AMPLITUDE;
- } else if (pressureCalibrationString != "default") {
+ } else if (*pressureCalibrationString != "default") {
ALOGW("Invalid value for touch.pressure.calibration: '%s'",
- pressureCalibrationString.c_str());
+ pressureCalibrationString->c_str());
}
}
- float pressureScale;
- if (in.tryGetProperty("touch.pressure.scale", pressureScale)) {
- out.pressureScale = pressureScale;
- }
+ out.pressureScale = in.getFloat("touch.pressure.scale");
// Orientation
out.orientationCalibration = Calibration::OrientationCalibration::DEFAULT;
- std::string orientationCalibrationString;
- if (in.tryGetProperty("touch.orientation.calibration", orientationCalibrationString)) {
- if (orientationCalibrationString == "none") {
+ std::optional<std::string> orientationCalibrationString =
+ in.getString("touch.orientation.calibration");
+ if (orientationCalibrationString.has_value()) {
+ if (*orientationCalibrationString == "none") {
out.orientationCalibration = Calibration::OrientationCalibration::NONE;
- } else if (orientationCalibrationString == "interpolated") {
+ } else if (*orientationCalibrationString == "interpolated") {
out.orientationCalibration = Calibration::OrientationCalibration::INTERPOLATED;
- } else if (orientationCalibrationString == "vector") {
+ } else if (*orientationCalibrationString == "vector") {
out.orientationCalibration = Calibration::OrientationCalibration::VECTOR;
- } else if (orientationCalibrationString != "default") {
+ } else if (*orientationCalibrationString != "default") {
ALOGW("Invalid value for touch.orientation.calibration: '%s'",
- orientationCalibrationString.c_str());
+ orientationCalibrationString->c_str());
}
}
// Distance
out.distanceCalibration = Calibration::DistanceCalibration::DEFAULT;
- std::string distanceCalibrationString;
- if (in.tryGetProperty("touch.distance.calibration", distanceCalibrationString)) {
- if (distanceCalibrationString == "none") {
+ std::optional<std::string> distanceCalibrationString =
+ in.getString("touch.distance.calibration");
+ if (distanceCalibrationString.has_value()) {
+ if (*distanceCalibrationString == "none") {
out.distanceCalibration = Calibration::DistanceCalibration::NONE;
- } else if (distanceCalibrationString == "scaled") {
+ } else if (*distanceCalibrationString == "scaled") {
out.distanceCalibration = Calibration::DistanceCalibration::SCALED;
- } else if (distanceCalibrationString != "default") {
+ } else if (*distanceCalibrationString != "default") {
ALOGW("Invalid value for touch.distance.calibration: '%s'",
- distanceCalibrationString.c_str());
+ distanceCalibrationString->c_str());
}
}
- float distanceScale;
- if (in.tryGetProperty("touch.distance.scale", distanceScale)) {
- out.distanceScale = distanceScale;
- }
+ out.distanceScale = in.getFloat("touch.distance.scale");
}
void TouchInputMapper::resolveCalibration() {
@@ -1675,7 +1658,6 @@
mPointerController->setPresentation(PointerControllerInterface::Presentation::SPOT);
mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
- mPointerController->setButtonState(mCurrentRawState.buttonState);
mPointerController->setSpots(mCurrentCookedState.cookedPointerData.pointerCoords.cbegin(),
mCurrentCookedState.cookedPointerData.idToIndex.cbegin(),
mCurrentCookedState.cookedPointerData.touchingIdBits |
@@ -2691,8 +2673,7 @@
// the pointer is hovering again even if the user is not currently touching
// the touch pad. This ensures that a view will receive a fresh hover enter
// event after a tap.
- float x, y;
- mPointerController->getPosition(&x, &y);
+ const auto [x, y] = mPointerController->getPosition();
PointerProperties pointerProperties;
pointerProperties.clear();
@@ -2898,8 +2879,7 @@
mPointerVelocityControl.reset();
}
- float x, y;
- mPointerController->getPosition(&x, &y);
+ const auto [x, y] = mPointerController->getPosition();
mPointerGesture.currentGestureMode = PointerGesture::Mode::BUTTON_CLICK_OR_DRAG;
mPointerGesture.currentGestureIdBits.clear();
@@ -2925,8 +2905,7 @@
mPointerGesture.lastGestureMode == PointerGesture::Mode::TAP_DRAG) &&
lastFingerCount == 1) {
if (when <= mPointerGesture.tapDownTime + mConfig.pointerGestureTapInterval) {
- float x, y;
- mPointerController->getPosition(&x, &y);
+ const auto [x, y] = mPointerController->getPosition();
if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop &&
fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
ALOGD_IF(DEBUG_GESTURES, "Gestures: TAP");
@@ -2988,8 +2967,7 @@
mPointerGesture.currentGestureMode = PointerGesture::Mode::HOVER;
if (mPointerGesture.lastGestureMode == PointerGesture::Mode::TAP) {
if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
- float x, y;
- mPointerController->getPosition(&x, &y);
+ const auto [x, y] = mPointerController->getPosition();
if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop &&
fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
mPointerGesture.currentGestureMode = PointerGesture::Mode::TAP_DRAG;
@@ -3025,8 +3003,7 @@
down = false;
}
- float x, y;
- mPointerController->getPosition(&x, &y);
+ const auto [x, y] = mPointerController->getPosition();
mPointerGesture.currentGestureIdBits.clear();
mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
@@ -3051,8 +3028,6 @@
prepareMultiFingerPointerGestures(when, outCancelPreviousGesture, outFinishPreviousGesture);
}
- mPointerController->setButtonState(mCurrentRawState.buttonState);
-
if (DEBUG_GESTURES) {
ALOGD("Gestures: finishPreviousGesture=%s, cancelPreviousGesture=%s, "
"currentGestureMode=%d, currentGestureIdBits=0x%08x, "
@@ -3193,8 +3168,8 @@
mCurrentRawState.rawPointerData
.getCentroidOfTouchingPointers(&mPointerGesture.referenceTouchX,
&mPointerGesture.referenceTouchY);
- mPointerController->getPosition(&mPointerGesture.referenceGestureX,
- &mPointerGesture.referenceGestureY);
+ std::tie(mPointerGesture.referenceGestureX, mPointerGesture.referenceGestureY) =
+ mPointerController->getPosition();
}
// Clear the reference deltas for fingers not yet included in the reference calculation.
@@ -3509,8 +3484,7 @@
hovering = mCurrentCookedState.cookedPointerData.hoveringIdBits.hasBit(id);
down = !hovering;
- float x, y;
- mPointerController->getPosition(&x, &y);
+ const auto [x, y] = mPointerController->getPosition();
mPointerSimple.currentCoords.copyFrom(
mCurrentCookedState.cookedPointerData.pointerCoords[index]);
mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
@@ -3548,9 +3522,8 @@
down = isPointerDown(mCurrentRawState.buttonState);
hovering = !down;
- float x, y;
- mPointerController->getPosition(&x, &y);
- uint32_t currentIndex = mCurrentRawState.rawPointerData.idToIndex[id];
+ const auto [x, y] = mPointerController->getPosition();
+ const uint32_t currentIndex = mCurrentRawState.rawPointerData.idToIndex[id];
mPointerSimple.currentCoords.copyFrom(
mCurrentCookedState.cookedPointerData.pointerCoords[currentIndex]);
mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
@@ -3590,15 +3563,13 @@
if (down || hovering) {
mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
mPointerController->clearSpots();
- mPointerController->setButtonState(mCurrentRawState.buttonState);
mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
} else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
}
int32_t displayId = mPointerController->getDisplayId();
- float xCursorPosition, yCursorPosition;
- mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
+ const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
if (mPointerSimple.down && !down) {
mPointerSimple.down = false;
@@ -3819,7 +3790,7 @@
float xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
if (mDeviceMode == DeviceMode::POINTER) {
- mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
+ std::tie(xCursorPosition, yCursorPosition) = mPointerController->getPosition();
}
const int32_t deviceId = getDeviceId();
std::vector<TouchVideoFrame> frames = getDeviceContext().getVideoFrames();
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h
index 7b464ef..ae7faa9 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.h
@@ -16,6 +16,9 @@
#pragma once
+#include <optional>
+#include <string>
+
#include <stdint.h>
#include <ui/Rotation.h>
@@ -147,7 +150,7 @@
~TouchInputMapper() override;
uint32_t getSources() const override;
- void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
+ void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
void dump(std::string& dump) override;
[[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
const InputReaderConfiguration* config,
diff --git a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
index 3309767..661461b 100644
--- a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
@@ -206,6 +206,11 @@
return AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD;
}
+void TouchpadInputMapper::populateDeviceInfo(InputDeviceInfo& info) {
+ InputMapper::populateDeviceInfo(info);
+ mGestureConverter.populateMotionRanges(info);
+}
+
void TouchpadInputMapper::dump(std::string& dump) {
dump += INDENT2 "Touchpad Input Mapper:\n";
dump += INDENT3 "Gesture converter:\n";
@@ -251,8 +256,9 @@
std::list<NotifyArgs> TouchpadInputMapper::reset(nsecs_t when) {
mStateConverter.reset();
- mGestureConverter.reset();
- return InputMapper::reset(when);
+ std::list<NotifyArgs> out = mGestureConverter.reset(when);
+ out += InputMapper::reset(when);
+ return out;
}
std::list<NotifyArgs> TouchpadInputMapper::process(const RawEvent* rawEvent) {
diff --git a/services/inputflinger/reader/mapper/TouchpadInputMapper.h b/services/inputflinger/reader/mapper/TouchpadInputMapper.h
index d693bca..fb36d92 100644
--- a/services/inputflinger/reader/mapper/TouchpadInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchpadInputMapper.h
@@ -41,6 +41,7 @@
~TouchpadInputMapper();
uint32_t getSources() const override;
+ void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
void dump(std::string& dump) override;
[[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
diff --git a/services/inputflinger/reader/mapper/VibratorInputMapper.cpp b/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
index 7645b12..2c77fc4 100644
--- a/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
@@ -29,10 +29,10 @@
return 0;
}
-void VibratorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+void VibratorInputMapper::populateDeviceInfo(InputDeviceInfo& info) {
InputMapper::populateDeviceInfo(info);
- info->setVibrator(true);
+ info.setVibrator(true);
}
std::list<NotifyArgs> VibratorInputMapper::process(const RawEvent* rawEvent) {
diff --git a/services/inputflinger/reader/mapper/VibratorInputMapper.h b/services/inputflinger/reader/mapper/VibratorInputMapper.h
index e98f63a..e665973 100644
--- a/services/inputflinger/reader/mapper/VibratorInputMapper.h
+++ b/services/inputflinger/reader/mapper/VibratorInputMapper.h
@@ -26,7 +26,7 @@
virtual ~VibratorInputMapper();
virtual uint32_t getSources() const override;
- virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
+ virtual void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
[[nodiscard]] std::list<NotifyArgs> process(const RawEvent* rawEvent) override;
[[nodiscard]] std::list<NotifyArgs> vibrate(const VibrationSequence& sequence, ssize_t repeat,
diff --git a/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp b/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp
index d636d44..fd2be5f 100644
--- a/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp
+++ b/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp
@@ -16,13 +16,14 @@
#include "gestures/GestureConverter.h"
+#include <optional>
#include <sstream>
#include <android-base/stringprintf.h>
-#include <android/input.h>
#include <ftl/enum.h>
#include <linux/input-event-codes.h>
#include <log/log_main.h>
+#include <ui/FloatRect.h>
#include "TouchCursorInputMapperCommon.h"
#include "input/Input.h"
@@ -71,8 +72,54 @@
return out.str();
}
-void GestureConverter::reset() {
- mButtonState = 0;
+std::list<NotifyArgs> GestureConverter::reset(nsecs_t when) {
+ std::list<NotifyArgs> out;
+ switch (mCurrentClassification) {
+ case MotionClassification::TWO_FINGER_SWIPE:
+ out.push_back(endScroll(when, when));
+ break;
+ case MotionClassification::MULTI_FINGER_SWIPE:
+ out += handleMultiFingerSwipeLift(when, when);
+ break;
+ case MotionClassification::PINCH:
+ out += endPinch(when, when);
+ break;
+ case MotionClassification::NONE:
+ // When a button is pressed, the Gestures library always ends the current gesture,
+ // so we don't have to worry about the case where buttons need to be lifted during a
+ // pinch or swipe.
+ if (mButtonState) {
+ out += releaseAllButtons(when, when);
+ }
+ break;
+ default:
+ break;
+ }
+ mCurrentClassification = MotionClassification::NONE;
+ mDownTime = 0;
+ return out;
+}
+
+void GestureConverter::populateMotionRanges(InputDeviceInfo& info) const {
+ info.addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, SOURCE, 0.0f, 1.0f, 0, 0, 0);
+
+ // TODO(b/259547750): set this using the raw axis ranges from the touchpad when pointer capture
+ // is enabled.
+ if (std::optional<FloatRect> rect = mPointerController->getBounds(); rect.has_value()) {
+ info.addMotionRange(AMOTION_EVENT_AXIS_X, SOURCE, rect->left, rect->right, 0, 0, 0);
+ info.addMotionRange(AMOTION_EVENT_AXIS_Y, SOURCE, rect->top, rect->bottom, 0, 0, 0);
+ }
+
+ info.addMotionRange(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET, SOURCE, -1.0f, 1.0f, 0, 0, 0);
+ info.addMotionRange(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET, SOURCE, -1.0f, 1.0f, 0, 0, 0);
+
+ // The other axes that can be reported don't have ranges that are easy to define. RELATIVE_X/Y
+ // and GESTURE_SCROLL_X/Y_DISTANCE are the result of acceleration functions being applied to
+ // finger movements, so their maximum values can't simply be derived from the size of the
+ // touchpad. GESTURE_PINCH_SCALE_FACTOR's maximum value depends on the minimum finger separation
+ // that the pad can report, which cannot be determined from its raw axis information. (Assuming
+ // a minimum finger separation of 1 unit would let us calculate a theoretical maximum, but it
+ // would be orders of magnitude too high, so probably not very useful.)
}
std::list<NotifyArgs> GestureConverter::handleGesture(nsecs_t when, nsecs_t readTime,
@@ -98,7 +145,6 @@
case kGestureTypePinch:
return handlePinch(when, readTime, gesture);
default:
- // TODO(b/251196347): handle more gesture types.
return {};
}
}
@@ -111,8 +157,8 @@
mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
mPointerController->move(deltaX, deltaY);
mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
- float xCursorPosition, yCursorPosition;
- mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
+
+ const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
PointerCoords coords;
coords.clear();
@@ -136,8 +182,7 @@
mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
- float xCursorPosition, yCursorPosition;
- mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
+ const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
PointerCoords coords;
coords.clear();
@@ -198,22 +243,56 @@
return out;
}
+std::list<NotifyArgs> GestureConverter::releaseAllButtons(nsecs_t when, nsecs_t readTime) {
+ std::list<NotifyArgs> out;
+ const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
+
+ PointerCoords coords;
+ coords.clear();
+ coords.setAxisValue(AMOTION_EVENT_AXIS_X, xCursorPosition);
+ coords.setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition);
+ coords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0);
+ coords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0);
+ const bool pointerDown = isPointerDown(mButtonState);
+ coords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pointerDown ? 1.0f : 0.0f);
+ uint32_t newButtonState = mButtonState;
+ for (uint32_t button = AMOTION_EVENT_BUTTON_PRIMARY; button <= AMOTION_EVENT_BUTTON_FORWARD;
+ button <<= 1) {
+ if (mButtonState & button) {
+ newButtonState &= ~button;
+ out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_BUTTON_RELEASE,
+ button, newButtonState, /*pointerCount=*/1,
+ mFingerProps.data(), &coords, xCursorPosition,
+ yCursorPosition));
+ }
+ }
+ if (pointerDown) {
+ coords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.0f);
+ out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_UP, /*actionButton=*/0,
+ newButtonState, /*pointerCount=*/1, mFingerProps.data(),
+ &coords, xCursorPosition, yCursorPosition));
+ }
+ mButtonState = 0;
+ return out;
+}
+
std::list<NotifyArgs> GestureConverter::handleScroll(nsecs_t when, nsecs_t readTime,
const Gesture& gesture) {
std::list<NotifyArgs> out;
PointerCoords& coords = mFakeFingerCoords[0];
- float xCursorPosition, yCursorPosition;
- mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
+ const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
if (mCurrentClassification != MotionClassification::TWO_FINGER_SWIPE) {
mCurrentClassification = MotionClassification::TWO_FINGER_SWIPE;
coords.setAxisValue(AMOTION_EVENT_AXIS_X, xCursorPosition);
coords.setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition);
coords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
mDownTime = when;
- out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_DOWN,
- /* actionButton= */ 0, mButtonState, /* pointerCount= */ 1,
- mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition,
- yCursorPosition));
+ NotifyMotionArgs args =
+ makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_DOWN, /* actionButton= */ 0,
+ mButtonState, /* pointerCount= */ 1, mFingerProps.data(),
+ mFakeFingerCoords.data(), xCursorPosition, yCursorPosition);
+ args.flags |= AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE;
+ out.push_back(args);
}
float deltaX = gesture.details.scroll.dx;
float deltaY = gesture.details.scroll.dy;
@@ -224,9 +303,12 @@
// TODO(b/262876643): set AXIS_GESTURE_{X,Y}_OFFSET.
coords.setAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_X_DISTANCE, -gesture.details.scroll.dx);
coords.setAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_Y_DISTANCE, -gesture.details.scroll.dy);
- out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_MOVE, /* actionButton= */ 0,
- mButtonState, /* pointerCount= */ 1, mFingerProps.data(),
- mFakeFingerCoords.data(), xCursorPosition, yCursorPosition));
+ NotifyMotionArgs args =
+ makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_MOVE, /* actionButton= */ 0,
+ mButtonState, /* pointerCount= */ 1, mFingerProps.data(),
+ mFakeFingerCoords.data(), xCursorPosition, yCursorPosition);
+ args.flags |= AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE;
+ out.push_back(args);
return out;
}
@@ -239,14 +321,18 @@
return {};
}
- float xCursorPosition, yCursorPosition;
- mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
+ return endScroll(when, readTime);
+}
+
+NotifyArgs GestureConverter::endScroll(nsecs_t when, nsecs_t readTime) {
+ const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_X_DISTANCE, 0);
mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_Y_DISTANCE, 0);
- NotifyArgs args = makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_UP,
- /* actionButton= */ 0, mButtonState, /* pointerCount= */ 1,
- mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition,
- yCursorPosition);
+ NotifyMotionArgs args =
+ makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_UP, /* actionButton= */ 0,
+ mButtonState, /* pointerCount= */ 1, mFingerProps.data(),
+ mFakeFingerCoords.data(), xCursorPosition, yCursorPosition);
+ args.flags |= AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE;
mCurrentClassification = MotionClassification::NONE;
return args;
}
@@ -256,8 +342,8 @@
uint32_t fingerCount,
float dx, float dy) {
std::list<NotifyArgs> out = {};
- float xCursorPosition, yCursorPosition;
- mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
+
+ const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
if (mCurrentClassification != MotionClassification::MULTI_FINGER_SWIPE) {
// If the user changes the number of fingers mid-way through a swipe (e.g. they start with
// three and then put a fourth finger down), the gesture library will treat it as two
@@ -292,8 +378,6 @@
yCursorPosition));
}
}
- // TODO(b/251196347): Set the gesture properties appropriately to avoid needing to negate the Y
- // values.
float rotatedDeltaX = dx, rotatedDeltaY = -dy;
rotateDelta(mOrientation, &rotatedDeltaX, &rotatedDeltaY);
for (size_t i = 0; i < mSwipeFingerCount; i++) {
@@ -304,8 +388,6 @@
coords.getAxisValue(AMOTION_EVENT_AXIS_Y) + rotatedDeltaY);
}
float xOffset = dx / (mXAxisInfo.maxValue - mXAxisInfo.minValue);
- // TODO(b/251196347): Set the gesture properties appropriately to avoid needing to negate the Y
- // values.
float yOffset = -dy / (mYAxisInfo.maxValue - mYAxisInfo.minValue);
mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET, xOffset);
mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET, yOffset);
@@ -322,8 +404,7 @@
if (mCurrentClassification != MotionClassification::MULTI_FINGER_SWIPE) {
return out;
}
- float xCursorPosition, yCursorPosition;
- mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
+ const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET, 0);
mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET, 0);
@@ -346,9 +427,7 @@
[[nodiscard]] std::list<NotifyArgs> GestureConverter::handlePinch(nsecs_t when, nsecs_t readTime,
const Gesture& gesture) {
- std::list<NotifyArgs> out;
- float xCursorPosition, yCursorPosition;
- mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
+ const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
// Pinch gesture phases are reported a little differently from others, in that the same details
// struct is used for all phases of the gesture, just with different zoom_state values. When
@@ -371,6 +450,7 @@
mFakeFingerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition);
mFakeFingerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
mDownTime = when;
+ std::list<NotifyArgs> out;
out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_DOWN,
/* actionButton= */ 0, mButtonState, /* pointerCount= */ 1,
mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition,
@@ -385,19 +465,7 @@
}
if (gesture.details.pinch.zoom_state == GESTURES_ZOOM_END) {
- mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_PINCH_SCALE_FACTOR, 1.0);
- out.push_back(makeMotionArgs(when, readTime,
- AMOTION_EVENT_ACTION_POINTER_UP |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT,
- /* actionButton= */ 0, mButtonState, /* pointerCount= */ 2,
- mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition,
- yCursorPosition));
- out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_UP, /* actionButton= */ 0,
- mButtonState, /* pointerCount= */ 1, mFingerProps.data(),
- mFakeFingerCoords.data(), xCursorPosition, yCursorPosition));
- mCurrentClassification = MotionClassification::NONE;
- mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_PINCH_SCALE_FACTOR, 0);
- return out;
+ return endPinch(when, readTime);
}
mPinchFingerSeparation *= gesture.details.pinch.dz;
@@ -409,9 +477,27 @@
mFakeFingerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X,
xCursorPosition + mPinchFingerSeparation / 2);
mFakeFingerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition);
- out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_MOVE, /* actionButton= */ 0,
- mButtonState, /* pointerCount= */ 2, mFingerProps.data(),
+ return {makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_MOVE, /*actionButton=*/0,
+ mButtonState, /*pointerCount=*/2, mFingerProps.data(),
+ mFakeFingerCoords.data(), xCursorPosition, yCursorPosition)};
+}
+
+std::list<NotifyArgs> GestureConverter::endPinch(nsecs_t when, nsecs_t readTime) {
+ std::list<NotifyArgs> out;
+ const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
+
+ mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_PINCH_SCALE_FACTOR, 1.0);
+ out.push_back(makeMotionArgs(when, readTime,
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT,
+ /*actionButton=*/0, mButtonState, /*pointerCount=*/2,
+ mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition,
+ yCursorPosition));
+ out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_UP, /*actionButton=*/0,
+ mButtonState, /*pointerCount=*/1, mFingerProps.data(),
mFakeFingerCoords.data(), xCursorPosition, yCursorPosition));
+ mCurrentClassification = MotionClassification::NONE;
+ mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_PINCH_SCALE_FACTOR, 0);
return out;
}
@@ -421,10 +507,7 @@
const PointerProperties* pointerProperties,
const PointerCoords* pointerCoords,
float xCursorPosition, float yCursorPosition) {
- // TODO(b/260226362): consider what the appropriate source for these events is.
- const uint32_t source = AINPUT_SOURCE_MOUSE;
-
- return NotifyMotionArgs(mReaderContext.getNextId(), when, readTime, mDeviceId, source,
+ return NotifyMotionArgs(mReaderContext.getNextId(), when, readTime, mDeviceId, SOURCE,
mPointerController->getDisplayId(), /* policyFlags= */ POLICY_FLAG_WAKE,
action, /* actionButton= */ actionButton, /* flags= */ 0,
mReaderContext.getGlobalMetaState(), buttonState,
diff --git a/services/inputflinger/reader/mapper/gestures/GestureConverter.h b/services/inputflinger/reader/mapper/gestures/GestureConverter.h
index 2ec5841..2714d03 100644
--- a/services/inputflinger/reader/mapper/gestures/GestureConverter.h
+++ b/services/inputflinger/reader/mapper/gestures/GestureConverter.h
@@ -21,6 +21,7 @@
#include <memory>
#include <PointerControllerInterface.h>
+#include <android/input.h>
#include <utils/Timers.h>
#include "EventHub.h"
@@ -43,7 +44,9 @@
std::string dump() const;
void setOrientation(ui::Rotation orientation) { mOrientation = orientation; }
- void reset();
+ [[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when);
+
+ void populateMotionRanges(InputDeviceInfo& info) const;
[[nodiscard]] std::list<NotifyArgs> handleGesture(nsecs_t when, nsecs_t readTime,
const Gesture& gesture);
@@ -52,15 +55,19 @@
[[nodiscard]] NotifyArgs handleMove(nsecs_t when, nsecs_t readTime, const Gesture& gesture);
[[nodiscard]] std::list<NotifyArgs> handleButtonsChange(nsecs_t when, nsecs_t readTime,
const Gesture& gesture);
+ [[nodiscard]] std::list<NotifyArgs> releaseAllButtons(nsecs_t when, nsecs_t readTime);
[[nodiscard]] std::list<NotifyArgs> handleScroll(nsecs_t when, nsecs_t readTime,
const Gesture& gesture);
[[nodiscard]] NotifyArgs handleFling(nsecs_t when, nsecs_t readTime, const Gesture& gesture);
+ [[nodiscard]] NotifyArgs endScroll(nsecs_t when, nsecs_t readTime);
+
[[nodiscard]] std::list<NotifyArgs> handleMultiFingerSwipe(nsecs_t when, nsecs_t readTime,
uint32_t fingerCount, float dx,
float dy);
[[nodiscard]] std::list<NotifyArgs> handleMultiFingerSwipeLift(nsecs_t when, nsecs_t readTime);
[[nodiscard]] std::list<NotifyArgs> handlePinch(nsecs_t when, nsecs_t readTime,
const Gesture& gesture);
+ [[nodiscard]] std::list<NotifyArgs> endPinch(nsecs_t when, nsecs_t readTime);
NotifyMotionArgs makeMotionArgs(nsecs_t when, nsecs_t readTime, int32_t action,
int32_t actionButton, int32_t buttonState,
@@ -98,6 +105,9 @@
{.id = 3, .toolType = AMOTION_EVENT_TOOL_TYPE_FINGER},
}};
std::array<PointerCoords, MAX_FAKE_FINGERS> mFakeFingerCoords = {};
+
+ // TODO(b/260226362): consider what the appropriate source for these events is.
+ static constexpr uint32_t SOURCE = AINPUT_SOURCE_MOUSE;
};
} // namespace android
diff --git a/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.cpp b/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.cpp
index c091a51..d344bab 100644
--- a/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.cpp
+++ b/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.cpp
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+// clang-format off
+#include "../Macros.h"
+// clang-format on
#include "gestures/HardwareStateConverter.h"
#include <chrono>
@@ -80,14 +83,9 @@
schs.fingers.clear();
for (size_t i = 0; i < mMotionAccumulator.getSlotCount(); i++) {
MultiTouchMotionAccumulator::Slot slot = mMotionAccumulator.getSlot(i);
- if (!slot.isInUse()) {
- continue;
- }
// Some touchpads continue to report contacts even after they've identified them as palms.
- // We want to exclude these contacts from the HardwareStates, but still need to report a
- // tracking ID of -1 if a finger turns into a palm.
- const bool isPalm = slot.getToolType() == AMOTION_EVENT_TOOL_TYPE_PALM;
- if (isPalm && mFingerSlots.find(i) == mFingerSlots.end()) {
+ // We want to exclude these contacts from the HardwareStates.
+ if (!slot.isInUse() || slot.getToolType() == AMOTION_EVENT_TOOL_TYPE_PALM) {
continue;
}
@@ -101,12 +99,7 @@
fingerState.orientation = slot.getOrientation();
fingerState.position_x = slot.getX();
fingerState.position_y = slot.getY();
- fingerState.tracking_id = isPalm ? -1 : slot.getTrackingId();
- if (fingerState.tracking_id == -1) {
- mFingerSlots.erase(i);
- } else {
- mFingerSlots.insert(i);
- }
+ fingerState.tracking_id = slot.getTrackingId();
}
schs.state.fingers = schs.fingers.data();
schs.state.finger_cnt = schs.fingers.size();
@@ -117,7 +110,6 @@
void HardwareStateConverter::reset() {
mCursorButtonAccumulator.reset(mDeviceContext);
mTouchButtonAccumulator.reset();
- mFingerSlots.clear();
mMscTimestamp = 0;
}
diff --git a/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.h b/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.h
index d6787b7..c314b0d 100644
--- a/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.h
+++ b/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.h
@@ -54,7 +54,6 @@
MultiTouchMotionAccumulator mMotionAccumulator;
TouchButtonAccumulator mTouchButtonAccumulator;
int32_t mMscTimestamp = 0;
- std::set<size_t> mFingerSlots;
};
} // namespace android
diff --git a/services/inputflinger/reader/mapper/gestures/PropertyProvider.cpp b/services/inputflinger/reader/mapper/gestures/PropertyProvider.cpp
index 3d88338..be2bfed 100644
--- a/services/inputflinger/reader/mapper/gestures/PropertyProvider.cpp
+++ b/services/inputflinger/reader/mapper/gestures/PropertyProvider.cpp
@@ -19,6 +19,7 @@
#include "gestures/PropertyProvider.h"
#include <algorithm>
+#include <optional>
#include <utility>
#include <android-base/stringprintf.h>
@@ -255,36 +256,34 @@
bool parsedSuccessfully = false;
Visitor setVisitor{
[&](int*) {
- int32_t value;
- parsedSuccessfully = idcProperties.tryGetProperty(propertyName, value);
- if (parsedSuccessfully) {
- setIntValues({value});
+ if (std::optional<int32_t> value = idcProperties.getInt(propertyName); value) {
+ parsedSuccessfully = true;
+ setIntValues({*value});
}
},
[&](GesturesPropBool*) {
- bool value;
- parsedSuccessfully = idcProperties.tryGetProperty(propertyName, value);
- if (parsedSuccessfully) {
- setBoolValues({value});
+ if (std::optional<bool> value = idcProperties.getBool(propertyName); value) {
+ parsedSuccessfully = true;
+ setBoolValues({*value});
}
},
[&](double*) {
- double value;
- parsedSuccessfully = idcProperties.tryGetProperty(propertyName, value);
- if (parsedSuccessfully) {
- setRealValues({value});
+ if (std::optional<double> value = idcProperties.getDouble(propertyName); value) {
+ parsedSuccessfully = true;
+ setRealValues({*value});
}
},
[&](const char**) {
ALOGE("Gesture property \"%s\" is a string, and so cannot be set in an IDC file.",
mName.c_str());
+ // We've already reported the type mismatch, so set parsedSuccessfully.
+ parsedSuccessfully = true;
},
};
std::visit(setVisitor, mDataPointer);
- ALOGE_IF(!parsedSuccessfully, "Gesture property \"%s\" could set due to a type mismatch.",
+ ALOGE_IF(!parsedSuccessfully, "Gesture property \"%s\" couldn't be set due to a type mismatch.",
mName.c_str());
- return;
}
template <typename T, typename U>
diff --git a/services/inputflinger/tests/FakePointerController.cpp b/services/inputflinger/tests/FakePointerController.cpp
index 28dad95..ca517f3 100644
--- a/services/inputflinger/tests/FakePointerController.cpp
+++ b/services/inputflinger/tests/FakePointerController.cpp
@@ -37,17 +37,8 @@
mY = y;
}
-void FakePointerController::setButtonState(int32_t buttonState) {
- mButtonState = buttonState;
-}
-
-int32_t FakePointerController::getButtonState() const {
- return mButtonState;
-}
-
-void FakePointerController::getPosition(float* outX, float* outY) const {
- *outX = mX;
- *outY = mY;
+FloatPoint FakePointerController::getPosition() const {
+ return {mX, mY};
}
int32_t FakePointerController::getDisplayId() const {
@@ -59,8 +50,7 @@
}
void FakePointerController::assertPosition(float x, float y) {
- float actualX, actualY;
- getPosition(&actualX, &actualY);
+ const auto [actualX, actualY] = getPosition();
ASSERT_NEAR(x, actualX, 1);
ASSERT_NEAR(y, actualY, 1);
}
@@ -69,13 +59,8 @@
return mIsPointerShown;
}
-bool FakePointerController::getBounds(float* outMinX, float* outMinY, float* outMaxX,
- float* outMaxY) const {
- *outMinX = mMinX;
- *outMinY = mMinY;
- *outMaxX = mMaxX;
- *outMaxY = mMaxY;
- return mHaveBounds;
+std::optional<FloatRect> FakePointerController::getBounds() const {
+ return mHaveBounds ? std::make_optional<FloatRect>(mMinX, mMinY, mMaxX, mMaxY) : std::nullopt;
}
void FakePointerController::move(float deltaX, float deltaY) {
diff --git a/services/inputflinger/tests/FakePointerController.h b/services/inputflinger/tests/FakePointerController.h
index dd56e65..c374267 100644
--- a/services/inputflinger/tests/FakePointerController.h
+++ b/services/inputflinger/tests/FakePointerController.h
@@ -32,9 +32,7 @@
const std::map<int32_t, std::vector<int32_t>>& getSpots();
void setPosition(float x, float y) override;
- void setButtonState(int32_t buttonState) override;
- int32_t getButtonState() const override;
- void getPosition(float* outX, float* outY) const override;
+ FloatPoint getPosition() const override;
int32_t getDisplayId() const override;
void setDisplayViewport(const DisplayViewport& viewport) override;
@@ -42,7 +40,7 @@
bool isPointerShown();
private:
- bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const override;
+ std::optional<FloatRect> getBounds() const override;
void move(float deltaX, float deltaY) override;
void fade(Transition) override;
void unfade(Transition) override;
@@ -54,7 +52,6 @@
bool mHaveBounds{false};
float mMinX{0}, mMinY{0}, mMaxX{0}, mMaxY{0};
float mX{0}, mY{0};
- int32_t mButtonState{0};
int32_t mDisplayId{ADISPLAY_ID_DEFAULT};
bool mIsPointerShown{false};
diff --git a/services/inputflinger/tests/GestureConverter_test.cpp b/services/inputflinger/tests/GestureConverter_test.cpp
index 9c624ba..33f404d 100644
--- a/services/inputflinger/tests/GestureConverter_test.cpp
+++ b/services/inputflinger/tests/GestureConverter_test.cpp
@@ -252,14 +252,16 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithCoords(POINTER_X, POINTER_Y),
WithGestureScrollDistance(0, 0, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER), WithDownTime(downTime)));
+ WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER), WithDownTime(downTime),
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
WithCoords(POINTER_X, POINTER_Y - 10),
WithGestureScrollDistance(0, 10, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER),
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE)));
Gesture continueGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -5);
args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture);
@@ -269,7 +271,8 @@
WithCoords(POINTER_X, POINTER_Y - 15),
WithGestureScrollDistance(0, 5, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER),
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE)));
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
GESTURES_FLING_START);
@@ -280,7 +283,8 @@
WithCoords(POINTER_X, POINTER_Y - 15),
WithGestureScrollDistance(0, 0, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER),
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE)));
}
TEST_F(GestureConverterTest, Scroll_Rotated) {
@@ -781,4 +785,107 @@
WithGesturePinchScaleFactor(0, EPSILON)));
}
+TEST_F(GestureConverterTest, ResetWithButtonPressed) {
+ InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
+ GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+
+ Gesture downGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
+ /*down=*/GESTURES_BUTTON_LEFT | GESTURES_BUTTON_RIGHT,
+ /*up=*/GESTURES_BUTTON_NONE, /*is_tap=*/false);
+ (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, downGesture);
+
+ std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME);
+ ASSERT_EQ(3u, args.size());
+
+ EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ args.pop_front();
+ EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY), WithButtonState(0),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ args.pop_front();
+ ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+}
+
+TEST_F(GestureConverterTest, ResetDuringScroll) {
+ InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
+ GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+
+ Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
+ (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+
+ std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME);
+ ASSERT_EQ(1u, args.size());
+ ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithCoords(POINTER_X, POINTER_Y - 10),
+ WithGestureScrollDistance(0, 0, EPSILON),
+ WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER),
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE)));
+}
+
+TEST_F(GestureConverterTest, ResetDuringThreeFingerSwipe) {
+ InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
+ GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+
+ Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0,
+ /*dy=*/10);
+ (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+
+ std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME);
+ ASSERT_EQ(3u, args.size());
+ EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
+ 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON),
+ WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(3u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ args.pop_front();
+ EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON),
+ WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(2u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ args.pop_front();
+ EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON),
+ WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(1u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+}
+
+TEST_F(GestureConverterTest, ResetDuringPinch) {
+ InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
+ GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+
+ Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
+ GESTURES_ZOOM_START);
+ (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+
+ std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME);
+ ASSERT_EQ(2u, args.size());
+ EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(2u),
+ WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ args.pop_front();
+ EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(1u),
+ WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+}
+
} // namespace android
diff --git a/services/inputflinger/tests/HardwareStateConverter_test.cpp b/services/inputflinger/tests/HardwareStateConverter_test.cpp
index 36b9bab..3e97241 100644
--- a/services/inputflinger/tests/HardwareStateConverter_test.cpp
+++ b/services/inputflinger/tests/HardwareStateConverter_test.cpp
@@ -231,8 +231,7 @@
schs = processSync(conv, time);
ASSERT_TRUE(schs.has_value());
- ASSERT_EQ(1, schs->state.finger_cnt);
- EXPECT_EQ(-1, schs->state.fingers[0].tracking_id);
+ ASSERT_EQ(0, schs->state.finger_cnt);
processAxis(conv, time, EV_ABS, ABS_MT_POSITION_X, 53);
processAxis(conv, time, EV_ABS, ABS_MT_POSITION_Y, 97);
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index eb58d0b..853c5b0 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -16,6 +16,7 @@
#include <cinttypes>
#include <memory>
+#include <optional>
#include <CursorInputMapper.h>
#include <InputDevice.h>
@@ -122,7 +123,7 @@
static void assertAxisResolution(MultiTouchInputMapper& mapper, int axis, float resolution) {
InputDeviceInfo info;
- mapper.populateDeviceInfo(&info);
+ mapper.populateDeviceInfo(info);
const InputDeviceInfo::MotionRange* motionRange =
info.getMotionRange(axis, AINPUT_SOURCE_TOUCHSCREEN);
@@ -131,7 +132,7 @@
static void assertAxisNotPresent(MultiTouchInputMapper& mapper, int axis) {
InputDeviceInfo info;
- mapper.populateDeviceInfo(&info);
+ mapper.populateDeviceInfo(info);
const InputDeviceInfo::MotionRange* motionRange =
info.getMotionRange(axis, AINPUT_SOURCE_TOUCHSCREEN);
@@ -254,11 +255,11 @@
private:
uint32_t getSources() const override { return mSources; }
- void populateDeviceInfo(InputDeviceInfo* deviceInfo) override {
+ void populateDeviceInfo(InputDeviceInfo& deviceInfo) override {
InputMapper::populateDeviceInfo(deviceInfo);
if (mKeyboardType != AINPUT_KEYBOARD_TYPE_NONE) {
- deviceInfo->setKeyboardType(mKeyboardType);
+ deviceInfo.setKeyboardType(mKeyboardType);
}
}
@@ -2355,10 +2356,10 @@
InputReaderConfiguration config;
std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, &config, 0);
- std::string propertyValue;
- ASSERT_TRUE(mDevice->getConfiguration().tryGetProperty("key", propertyValue))
+ std::optional<std::string> propertyValue = mDevice->getConfiguration().getString("key");
+ ASSERT_TRUE(propertyValue.has_value())
<< "Device should have read configuration during configuration phase.";
- ASSERT_EQ("value", propertyValue);
+ ASSERT_EQ("value", *propertyValue);
ASSERT_NO_FATAL_FAILURE(mapper1.assertConfigureWasCalled());
ASSERT_NO_FATAL_FAILURE(mapper2.assertConfigureWasCalled());
@@ -3807,7 +3808,7 @@
CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
InputDeviceInfo info;
- mapper.populateDeviceInfo(&info);
+ mapper.populateDeviceInfo(info);
// Initially there may not be a valid motion range.
ASSERT_EQ(nullptr, info.getMotionRange(AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE));
@@ -3819,7 +3820,7 @@
mFakePointerController->setBounds(1, 2, 800 - 1, 480 - 1);
InputDeviceInfo info2;
- mapper.populateDeviceInfo(&info2);
+ mapper.populateDeviceInfo(info2);
ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE,
@@ -3837,7 +3838,7 @@
CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
InputDeviceInfo info;
- mapper.populateDeviceInfo(&info);
+ mapper.populateDeviceInfo(info);
ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_TRACKBALL,
@@ -4113,7 +4114,6 @@
mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
mFakePointerController->setPosition(100, 200);
- mFakePointerController->setButtonState(0);
NotifyMotionArgs motionArgs;
NotifyKeyArgs keyArgs;
@@ -4124,14 +4124,12 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
- ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
- ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
@@ -4140,21 +4138,18 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
ASSERT_EQ(0, motionArgs.buttonState);
- ASSERT_EQ(0, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
ASSERT_EQ(0, motionArgs.buttonState);
- ASSERT_EQ(0, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
ASSERT_EQ(0, motionArgs.buttonState);
- ASSERT_EQ(0, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
@@ -4165,26 +4160,20 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
- motionArgs.buttonState);
- ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
- mFakePointerController->getButtonState());
+ motionArgs.buttonState);
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
- ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
- mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
- motionArgs.buttonState);
- ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
- mFakePointerController->getButtonState());
+ motionArgs.buttonState);
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
@@ -4193,14 +4182,12 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
- ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
- ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
@@ -4209,7 +4196,6 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
ASSERT_EQ(0, motionArgs.buttonState);
- ASSERT_EQ(0, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 0);
@@ -4217,14 +4203,12 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(0, motionArgs.buttonState);
- ASSERT_EQ(0, mFakePointerController->getButtonState());
ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(0, motionArgs.buttonState);
- ASSERT_EQ(0, mFakePointerController->getButtonState());
ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
@@ -4239,14 +4223,12 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
- ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
- ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
@@ -4255,14 +4237,12 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
ASSERT_EQ(0, motionArgs.buttonState);
- ASSERT_EQ(0, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
ASSERT_EQ(0, motionArgs.buttonState);
- ASSERT_EQ(0, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
@@ -4280,14 +4260,12 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
- ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
- ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
@@ -4296,14 +4274,12 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
ASSERT_EQ(0, motionArgs.buttonState);
- ASSERT_EQ(0, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
ASSERT_EQ(0, motionArgs.buttonState);
- ASSERT_EQ(0, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
@@ -4321,14 +4297,12 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
- ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
- ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
@@ -4337,14 +4311,12 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
ASSERT_EQ(0, motionArgs.buttonState);
- ASSERT_EQ(0, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
ASSERT_EQ(0, motionArgs.buttonState);
- ASSERT_EQ(0, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
@@ -4362,14 +4334,12 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
- ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
- ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
@@ -4378,14 +4348,12 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
ASSERT_EQ(0, motionArgs.buttonState);
- ASSERT_EQ(0, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
ASSERT_EQ(0, motionArgs.buttonState);
- ASSERT_EQ(0, mFakePointerController->getButtonState());
ASSERT_NO_FATAL_FAILURE(
assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
@@ -4400,7 +4368,6 @@
mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
mFakePointerController->setPosition(100, 200);
- mFakePointerController->setButtonState(0);
NotifyMotionArgs args;
@@ -4427,7 +4394,6 @@
mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
mFakePointerController->setPosition(100, 200);
- mFakePointerController->setButtonState(0);
NotifyMotionArgs args;
@@ -4606,7 +4572,6 @@
mFakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
mFakePointerController->setPosition(100, 200);
- mFakePointerController->setButtonState(0);
// Ensure input events are generated for the secondary display.
process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
@@ -4634,7 +4599,6 @@
mFakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
mFakePointerController->setPosition(100, 200);
- mFakePointerController->setButtonState(0);
process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
@@ -8480,7 +8444,7 @@
MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
InputDeviceInfo info;
- mapper.populateDeviceInfo(&info);
+ mapper.populateDeviceInfo(info);
ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TOUCHSCREEN,
0.0f, RAW_PRESSURE_MAX * 0.01, 0.0f, 0.0f));
@@ -9163,7 +9127,6 @@
std::make_shared<FakePointerController>();
fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
fakePointerController->setPosition(100, 200);
- fakePointerController->setButtonState(0);
mFakePolicy->setPointerController(fakePointerController);
mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
@@ -10158,7 +10121,6 @@
std::make_shared<FakePointerController>();
fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
fakePointerController->setPosition(0, 0);
- fakePointerController->setButtonState(0);
// prepare device and capture
prepareDisplay(ui::ROTATION_0);
@@ -10308,7 +10270,6 @@
std::make_shared<FakePointerController>();
fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
fakePointerController->setPosition(0, 0);
- fakePointerController->setButtonState(0);
// prepare device and capture
prepareDisplay(ui::ROTATION_0);
@@ -10448,7 +10409,6 @@
std::make_shared<FakePointerController>();
fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
fakePointerController->setPosition(0, 0);
- fakePointerController->setButtonState(0);
prepareDisplay(ui::ROTATION_0);
prepareAxes(POSITION);
diff --git a/services/inputflinger/tests/TestInputListenerMatchers.h b/services/inputflinger/tests/TestInputListenerMatchers.h
index edd14f8..09f7ae8 100644
--- a/services/inputflinger/tests/TestInputListenerMatchers.h
+++ b/services/inputflinger/tests/TestInputListenerMatchers.h
@@ -145,7 +145,7 @@
MATCHER_P(WithFlags, flags, "InputEvent with specified flags") {
*result_listener << "expected flags " << flags << ", but got " << arg.flags;
- return arg.flags == flags;
+ return arg.flags == static_cast<int32_t>(flags);
}
MATCHER_P(WithMotionClassification, classification,
diff --git a/services/inputflinger/tests/fuzzers/CursorInputFuzzer.cpp b/services/inputflinger/tests/fuzzers/CursorInputFuzzer.cpp
index be85026..9a19b97 100644
--- a/services/inputflinger/tests/fuzzers/CursorInputFuzzer.cpp
+++ b/services/inputflinger/tests/fuzzers/CursorInputFuzzer.cpp
@@ -60,7 +60,7 @@
std::list<NotifyArgs> unused =
mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig, 0);
InputDeviceInfo info;
- mapper.populateDeviceInfo(&info);
+ mapper.populateDeviceInfo(info);
},
[&]() -> void {
int32_t type, code;
diff --git a/services/inputflinger/tests/fuzzers/KeyboardInputFuzzer.cpp b/services/inputflinger/tests/fuzzers/KeyboardInputFuzzer.cpp
index 8e2d677..33e7dbf 100644
--- a/services/inputflinger/tests/fuzzers/KeyboardInputFuzzer.cpp
+++ b/services/inputflinger/tests/fuzzers/KeyboardInputFuzzer.cpp
@@ -59,7 +59,7 @@
},
[&]() -> void {
InputDeviceInfo info;
- mapper.populateDeviceInfo(&info);
+ mapper.populateDeviceInfo(info);
},
[&]() -> void { mapper.getSources(); },
[&]() -> void {
diff --git a/services/inputflinger/tests/fuzzers/MapperHelpers.h b/services/inputflinger/tests/fuzzers/MapperHelpers.h
index 546121d..2cb5cdf 100644
--- a/services/inputflinger/tests/fuzzers/MapperHelpers.h
+++ b/services/inputflinger/tests/fuzzers/MapperHelpers.h
@@ -225,14 +225,21 @@
public:
FuzzPointerController(std::shared_ptr<ThreadSafeFuzzedDataProvider> mFdp) : mFdp(mFdp) {}
~FuzzPointerController() {}
- bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const override {
- return mFdp->ConsumeBool();
+ std::optional<FloatRect> getBounds() const override {
+ if (mFdp->ConsumeBool()) {
+ return {};
+ } else {
+ return FloatRect{mFdp->ConsumeFloatingPoint<float>(),
+ mFdp->ConsumeFloatingPoint<float>(),
+ mFdp->ConsumeFloatingPoint<float>(),
+ mFdp->ConsumeFloatingPoint<float>()};
+ }
}
void move(float deltaX, float deltaY) override {}
- void setButtonState(int32_t buttonState) override {}
- int32_t getButtonState() const override { return mFdp->ConsumeIntegral<int32_t>(); }
void setPosition(float x, float y) override {}
- void getPosition(float* outX, float* outY) const override {}
+ FloatPoint getPosition() const override {
+ return {mFdp->ConsumeFloatingPoint<float>(), mFdp->ConsumeFloatingPoint<float>()};
+ }
void fade(Transition transition) override {}
void unfade(Transition transition) override {}
void setPresentation(Presentation presentation) override {}
diff --git a/services/inputflinger/tests/fuzzers/MultiTouchInputFuzzer.cpp b/services/inputflinger/tests/fuzzers/MultiTouchInputFuzzer.cpp
index 011455b..59cb94a 100644
--- a/services/inputflinger/tests/fuzzers/MultiTouchInputFuzzer.cpp
+++ b/services/inputflinger/tests/fuzzers/MultiTouchInputFuzzer.cpp
@@ -74,7 +74,7 @@
},
[&]() -> void {
InputDeviceInfo info;
- mapper.populateDeviceInfo(&info);
+ mapper.populateDeviceInfo(info);
},
[&]() -> void { mapper.getSources(); },
[&]() -> void {
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 0fb3cad..398d602 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -1648,7 +1648,7 @@
int deviceId = c->getDeviceId();
int sensorDeviceId = getDeviceIdFromHandle(sensorHandle);
if (sensorDeviceId != c->getDeviceId()) {
- ALOGE("Cannot configure direct channel created for device %d with a sensor that belongs"
+ ALOGE("Cannot configure direct channel created for device %d with a sensor that belongs "
"to device %d", c->getDeviceId(), sensorDeviceId);
return BAD_VALUE;
}
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
index eae5871..35ca3a5 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
@@ -210,8 +210,8 @@
// The dimming flag
bool dimmingEnabled{true};
- float currentSdrHdrRatio = 1.f;
- float desiredSdrHdrRatio = 1.f;
+ float currentHdrSdrRatio = 1.f;
+ float desiredHdrSdrRatio = 1.f;
gui::CachingHint cachingHint = gui::CachingHint::Enabled;
virtual ~LayerFECompositionState();
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
index d5c488e..ce2b96f 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
@@ -247,6 +247,10 @@
ui::Dataspace getDataspace() const { return mOutputDataspace.get(); }
+ float getHdrSdrRatio() const {
+ return getOutputLayer()->getLayerFE().getCompositionState()->currentHdrSdrRatio;
+ };
+
wp<GraphicBuffer> getBuffer() const { return mBuffer.get(); }
bool isProtected() const { return mIsProtected.get(); }
diff --git a/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
index 615d04b..426cc57 100644
--- a/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
@@ -121,9 +121,9 @@
dumpVal(out, "dataspace", toString(dataspace), dataspace);
dumpVal(out, "hdr metadata types", hdrMetadata.validTypes);
dumpVal(out, "dimming enabled", dimmingEnabled);
- if (currentSdrHdrRatio > 1.01f || desiredSdrHdrRatio > 1.01f) {
- dumpVal(out, "current sdr/hdr ratio", currentSdrHdrRatio);
- dumpVal(out, "desired sdr/hdr ratio", desiredSdrHdrRatio);
+ if (currentHdrSdrRatio > 1.01f || desiredHdrSdrRatio > 1.01f) {
+ dumpVal(out, "current hdr/sdr ratio", currentHdrSdrRatio);
+ dumpVal(out, "desired hdr/sdr ratio", desiredHdrSdrRatio);
}
dumpVal(out, "colorTransform", colorTransform);
dumpVal(out, "caching hint", toString(cachingHint));
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 1b86cd3..0ac0ecb 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -344,8 +344,8 @@
// RANGE_EXTENDED can "self-promote" to HDR, but is still rendered for a particular
// range that we may need to re-adjust to the current display conditions
if ((state.dataspace & HAL_DATASPACE_RANGE_MASK) == HAL_DATASPACE_RANGE_EXTENDED &&
- layerFEState->currentSdrHdrRatio > 1.01f) {
- layerBrightnessNits *= layerFEState->currentSdrHdrRatio;
+ layerFEState->currentHdrSdrRatio > 1.01f) {
+ layerBrightnessNits *= layerFEState->currentHdrSdrRatio;
}
state.dimmingRatio =
std::clamp(layerBrightnessNits / getOutput().getState().displayBrightnessNits, 0.f,
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
index a00ce57..8ced0ac 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
@@ -378,6 +378,10 @@
// to avoid flickering/color differences.
return true;
}
+ // TODO(b/274804887): temp fix of overdimming issue, skip caching if hsdr/sdr ratio > 1.01f
+ if (layer.getState()->getHdrSdrRatio() > 1.01f) {
+ return true;
+ }
return false;
});
}
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
index ca5ba69..bd030d0 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
@@ -662,6 +662,26 @@
EXPECT_FALSE(cachedSet.requiresHolePunch());
}
+TEST_F(CachedSetTest, holePunch_requiresNonHdrWithExtendedBrightness) {
+ const auto dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_DCI_P3 |
+ ui::Dataspace::TRANSFER_SRGB |
+ ui::Dataspace::RANGE_EXTENDED);
+ mTestLayers[0]->outputLayerCompositionState.dataspace = dataspace;
+ mTestLayers[0]->layerFECompositionState.currentHdrSdrRatio = 5.f;
+ mTestLayers[0]->layerState->update(&mTestLayers[0]->outputLayer);
+
+ CachedSet::Layer& layer = *mTestLayers[0]->cachedSetLayer.get();
+ auto& layerFECompositionState = mTestLayers[0]->layerFECompositionState;
+ layerFECompositionState.buffer = sp<GraphicBuffer>::make();
+ layerFECompositionState.blendMode = hal::BlendMode::NONE;
+ sp<mock::LayerFE> layerFE = mTestLayers[0]->layerFE;
+
+ CachedSet cachedSet(layer);
+ EXPECT_CALL(*layerFE, hasRoundedCorners()).WillRepeatedly(Return(true));
+
+ EXPECT_FALSE(cachedSet.requiresHolePunch());
+}
+
TEST_F(CachedSetTest, holePunch_requiresNoBlending) {
CachedSet::Layer& layer = *mTestLayers[0]->cachedSetLayer.get();
auto& layerFECompositionState = mTestLayers[0]->layerFECompositionState;
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 064bbd2..01db0cd 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -182,11 +182,23 @@
getCompositionDisplay()->applyDisplayBrightness(true);
}
- mPowerMode = mode;
+ if (mPowerMode) {
+ *mPowerMode = mode;
+ } else {
+ mPowerMode.emplace("PowerMode -" + to_string(getId()), mode);
+ }
getCompositionDisplay()->setCompositionEnabled(isPoweredOn());
}
+void DisplayDevice::tracePowerMode() {
+ // assign the same value for tracing
+ if (mPowerMode) {
+ const hal::PowerMode powerMode = *mPowerMode;
+ *mPowerMode = powerMode;
+ }
+}
+
void DisplayDevice::enableLayerCaching(bool enable) {
getCompositionDisplay()->setLayerCachingEnabled(enable);
}
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index d9c3e1c..51876e7 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -175,6 +175,7 @@
std::optional<hardware::graphics::composer::hal::PowerMode> getPowerMode() const;
void setPowerMode(hardware::graphics::composer::hal::PowerMode mode);
bool isPoweredOn() const;
+ void tracePowerMode();
// Enables layer caching on this DisplayDevice
void enableLayerCaching(bool enable);
@@ -276,7 +277,8 @@
static ui::Transform::RotationFlags sPrimaryDisplayRotationFlags;
// Allow nullopt as initial power mode.
- std::optional<hardware::graphics::composer::hal::PowerMode> mPowerMode;
+ using TracedPowerMode = TracedOrdinal<hardware::graphics::composer::hal::PowerMode>;
+ std::optional<TracedPowerMode> mPowerMode;
std::optional<float> mStagedBrightness;
std::optional<float> mBrightness;
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
index 925f111..ded734e 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
@@ -885,15 +885,17 @@
void FrameTimeline::DisplayFrame::classifyJank(nsecs_t& deadlineDelta, nsecs_t& deltaToVsync,
nsecs_t previousPresentTime) {
- if (mPredictionState == PredictionState::Expired ||
- mSurfaceFlingerActuals.presentTime == Fence::SIGNAL_TIME_INVALID) {
+ const bool presentTimeValid =
+ mSurfaceFlingerActuals.presentTime >= mSurfaceFlingerActuals.startTime;
+ if (mPredictionState == PredictionState::Expired || !presentTimeValid) {
// Cannot do jank classification with expired predictions or invalid signal times. Set the
// deltas to 0 as both negative and positive deltas are used as real values.
mJankType = JankType::Unknown;
deadlineDelta = 0;
deltaToVsync = 0;
- if (mSurfaceFlingerActuals.presentTime == Fence::SIGNAL_TIME_INVALID) {
+ if (!presentTimeValid) {
mSurfaceFlingerActuals.presentTime = mSurfaceFlingerActuals.endTime;
+ mJankType |= JankType::DisplayHAL;
}
return;
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
index 5e7c259..2d6d8ad 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
@@ -44,6 +44,8 @@
inputInfo.id = static_cast<int32_t>(uniqueSequence);
inputInfo.ownerUid = static_cast<int32_t>(state.ownerUid);
inputInfo.ownerPid = state.ownerPid;
+ uid = state.ownerUid;
+ pid = state.ownerPid;
changes = RequestedLayerState::Changes::Created;
mirrorRootPath = path.variant == LayerHierarchy::Variant::Mirror
? path
@@ -179,7 +181,12 @@
std::stringstream debug;
debug << "Snapshot{" << path.toString() << name << " isVisible=" << isVisible << " {"
<< getIsVisibleReason() << "} changes=" << changes.string()
- << " layerStack=" << outputFilter.layerStack.id << "}";
+ << " layerStack=" << outputFilter.layerStack.id << " geomLayerBounds={"
+ << geomLayerBounds.left << "," << geomLayerBounds.top << "," << geomLayerBounds.bottom
+ << "," << geomLayerBounds.right << "}"
+ << " geomLayerTransform={tx=" << geomLayerTransform.tx()
+ << ",ty=" << geomLayerTransform.ty() << "}"
+ << "}";
return debug.str();
}
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.h b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
index 6fb2f57..5491d9a 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshot.h
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
@@ -89,10 +89,13 @@
gui::GameMode gameMode;
scheduler::LayerInfo::FrameRate frameRate;
ui::Transform::RotationFlags fixedTransformHint;
+ std::optional<ui::Transform::RotationFlags> transformHint;
bool handleSkipScreenshotFlag = false;
int32_t frameRateSelectionPriority;
LayerHierarchy::TraversalPath mirrorRootPath;
bool unreachable = true;
+ uid_t uid;
+ pid_t pid;
ChildState childState;
static bool isOpaqueFormat(PixelFormat format);
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
index a16de1b..babcbe7 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
@@ -21,10 +21,16 @@
#include "LayerSnapshotBuilder.h"
#include <gui/TraceUtils.h>
+#include <ui/FloatRect.h>
+
#include <numeric>
+#include <optional>
+
+#include <gui/TraceUtils.h>
#include "DisplayHardware/HWC2.h"
#include "DisplayHardware/Hal.h"
#include "LayerLog.h"
+#include "LayerSnapshotBuilder.h"
#include "TimeStats/TimeStats.h"
#include "ftl/small_map.h"
@@ -101,43 +107,52 @@
}
/**
+ * Returns the bounds used to fill the input frame and the touchable region.
+ *
* Similar to getInputTransform, we need to update the bounds to include the transform.
* This is because bounds don't include the buffer transform, where the input assumes
* that's already included.
*/
-Rect getInputBounds(const LayerSnapshot& snapshot) {
- if (!snapshot.hasBufferOrSidebandStream()) {
- return snapshot.croppedBufferSize;
+std::pair<FloatRect, bool> getInputBounds(const LayerSnapshot& snapshot, bool fillParentBounds) {
+ FloatRect inputBounds = snapshot.croppedBufferSize.toFloatRect();
+ if (snapshot.hasBufferOrSidebandStream() && snapshot.croppedBufferSize.isValid() &&
+ snapshot.localTransform.getType() != ui::Transform::IDENTITY) {
+ inputBounds = snapshot.localTransform.transform(inputBounds);
}
- if (snapshot.localTransform.getType() == ui::Transform::IDENTITY ||
- !snapshot.croppedBufferSize.isValid()) {
- return snapshot.croppedBufferSize;
+ bool inputBoundsValid = snapshot.croppedBufferSize.isValid();
+ if (!inputBoundsValid) {
+ /**
+ * Input bounds are based on the layer crop or buffer size. But if we are using
+ * the layer bounds as the input bounds (replaceTouchableRegionWithCrop flag) then
+ * we can use the parent bounds as the input bounds if the layer does not have buffer
+ * or a crop. We want to unify this logic but because of compat reasons we cannot always
+ * use the parent bounds. A layer without a buffer can get input. So when a window is
+ * initially added, its touchable region can fill its parent layer bounds and that can
+ * have negative consequences.
+ */
+ inputBounds = fillParentBounds ? snapshot.geomLayerBounds : FloatRect{};
}
- return snapshot.localTransform.transform(snapshot.croppedBufferSize);
+
+ // Clamp surface inset to the input bounds.
+ const float inset = static_cast<float>(snapshot.inputInfo.surfaceInset);
+ const float xSurfaceInset = std::clamp(inset, 0.f, inputBounds.getWidth() / 2.f);
+ const float ySurfaceInset = std::clamp(inset, 0.f, inputBounds.getHeight() / 2.f);
+
+ // Apply the insets to the input bounds.
+ inputBounds.left += xSurfaceInset;
+ inputBounds.top += ySurfaceInset;
+ inputBounds.right -= xSurfaceInset;
+ inputBounds.bottom -= ySurfaceInset;
+ return {inputBounds, inputBoundsValid};
}
-void fillInputFrameInfo(gui::WindowInfo& info, const ui::Transform& screenToDisplay,
- const LayerSnapshot& snapshot) {
- Rect tmpBounds = getInputBounds(snapshot);
- if (!tmpBounds.isValid()) {
- info.touchableRegion.clear();
- // A layer could have invalid input bounds and still expect to receive touch input if it has
- // replaceTouchableRegionWithCrop. For that case, the input transform needs to be calculated
- // correctly to determine the coordinate space for input events. Use an empty rect so that
- // the layer will receive input in its own layer space.
- tmpBounds = Rect::EMPTY_RECT;
- }
-
+Rect getInputBoundsInDisplaySpace(const LayerSnapshot& snapshot, const FloatRect& insetBounds,
+ const ui::Transform& screenToDisplay) {
// InputDispatcher works in the display device's coordinate space. Here, we calculate the
// frame and transform used for the layer, which determines the bounds and the coordinate space
// within which the layer will receive input.
- //
- // The coordinate space within which each of the bounds are specified is explicitly documented
- // in the variable name. For example "inputBoundsInLayer" is specified in layer space. A
- // Transform converts one coordinate space to another, which is apparent in its naming. For
- // example, "layerToDisplay" transforms layer space to display space.
- //
+
// Coordinate space definitions:
// - display: The display device's coordinate space. Correlates to pixels on the display.
// - screen: The post-rotation coordinate space for the display, a.k.a. logical display space.
@@ -145,37 +160,34 @@
// - input: The coordinate space in which this layer will receive input events. This could be
// different than layer space if a surfaceInset is used, which changes the origin
// of the input space.
- const FloatRect inputBoundsInLayer = tmpBounds.toFloatRect();
-
- // Clamp surface inset to the input bounds.
- const auto surfaceInset = static_cast<float>(info.surfaceInset);
- const float xSurfaceInset =
- std::max(0.f, std::min(surfaceInset, inputBoundsInLayer.getWidth() / 2.f));
- const float ySurfaceInset =
- std::max(0.f, std::min(surfaceInset, inputBoundsInLayer.getHeight() / 2.f));
-
- // Apply the insets to the input bounds.
- const FloatRect insetBoundsInLayer(inputBoundsInLayer.left + xSurfaceInset,
- inputBoundsInLayer.top + ySurfaceInset,
- inputBoundsInLayer.right - xSurfaceInset,
- inputBoundsInLayer.bottom - ySurfaceInset);
// Crop the input bounds to ensure it is within the parent's bounds.
- const FloatRect croppedInsetBoundsInLayer =
- snapshot.geomLayerBounds.intersect(insetBoundsInLayer);
+ const FloatRect croppedInsetBoundsInLayer = snapshot.geomLayerBounds.intersect(insetBounds);
const ui::Transform layerToScreen = getInputTransform(snapshot);
const ui::Transform layerToDisplay = screenToDisplay * layerToScreen;
- const Rect roundedFrameInDisplay{layerToDisplay.transform(croppedInsetBoundsInLayer)};
+ return Rect{layerToDisplay.transform(croppedInsetBoundsInLayer)};
+}
+
+void fillInputFrameInfo(gui::WindowInfo& info, const ui::Transform& screenToDisplay,
+ const LayerSnapshot& snapshot) {
+ auto [inputBounds, inputBoundsValid] = getInputBounds(snapshot, /*fillParentBounds=*/false);
+ if (!inputBoundsValid) {
+ info.touchableRegion.clear();
+ }
+
+ const Rect roundedFrameInDisplay =
+ getInputBoundsInDisplaySpace(snapshot, inputBounds, screenToDisplay);
info.frameLeft = roundedFrameInDisplay.left;
info.frameTop = roundedFrameInDisplay.top;
info.frameRight = roundedFrameInDisplay.right;
info.frameBottom = roundedFrameInDisplay.bottom;
ui::Transform inputToLayer;
- inputToLayer.set(insetBoundsInLayer.left, insetBoundsInLayer.top);
- const ui::Transform inputToDisplay = layerToDisplay * inputToLayer;
+ inputToLayer.set(inputBounds.left, inputBounds.top);
+ const ui::Transform layerToScreen = getInputTransform(snapshot);
+ const ui::Transform inputToDisplay = screenToDisplay * layerToScreen * inputToLayer;
// InputDispatcher expects a display-to-input transform.
info.transform = inputToDisplay.inverse();
@@ -642,12 +654,14 @@
snapshot.relativeLayerMetadata.mMap.clear();
}
-uint32_t getDisplayRotationFlags(
- const display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& displays,
- const ui::LayerStack& layerStack) {
- static frontend::DisplayInfo sDefaultDisplayInfo = {.isPrimary = false};
- auto display = displays.get(layerStack).value_or(sDefaultDisplayInfo).get();
- return display.isPrimary ? display.rotationFlags : 0;
+uint32_t getPrimaryDisplayRotationFlags(
+ const display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& displays) {
+ for (auto& [_, display] : displays) {
+ if (display.isPrimary) {
+ return display.rotationFlags;
+ }
+ }
+ return 0;
}
void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& args,
@@ -674,8 +688,7 @@
? requested.layerStack
: parentSnapshot.outputFilter.layerStack;
- uint32_t displayRotationFlags =
- getDisplayRotationFlags(args.displays, snapshot.outputFilter.layerStack);
+ uint32_t primaryDisplayRotationFlags = getPrimaryDisplayRotationFlags(args.displays);
const bool forceUpdate = args.forceUpdate == ForceUpdateFlags::ALL ||
snapshot.changes.any(RequestedLayerState::Changes::Visibility |
RequestedLayerState::Changes::Created);
@@ -689,7 +702,7 @@
: Fence::NO_FENCE;
snapshot.buffer =
requested.externalTexture ? requested.externalTexture->getBuffer() : nullptr;
- snapshot.bufferSize = requested.getBufferSize(displayRotationFlags);
+ snapshot.bufferSize = requested.getBufferSize(primaryDisplayRotationFlags);
snapshot.geomBufferSize = snapshot.bufferSize;
snapshot.croppedBufferSize = requested.getCroppedBufferSize(snapshot.bufferSize);
snapshot.dataspace = requested.dataspace;
@@ -707,8 +720,8 @@
snapshot.sidebandStream = requested.sidebandStream;
snapshot.transparentRegionHint = requested.transparentRegion;
snapshot.color.rgb = requested.getColor().rgb;
- snapshot.currentSdrHdrRatio = requested.currentSdrHdrRatio;
- snapshot.desiredSdrHdrRatio = requested.desiredSdrHdrRatio;
+ snapshot.currentHdrSdrRatio = requested.currentHdrSdrRatio;
+ snapshot.desiredHdrSdrRatio = requested.desiredHdrSdrRatio;
}
if (snapshot.isHiddenByPolicyFromParent &&
@@ -744,15 +757,28 @@
snapshot.gameMode = requested.metadata.has(gui::METADATA_GAME_MODE)
? requested.gameMode
: parentSnapshot.gameMode;
- snapshot.fixedTransformHint = requested.fixedTransformHint != ui::Transform::ROT_INVALID
- ? requested.fixedTransformHint
- : parentSnapshot.fixedTransformHint;
// Display mirrors are always placed in a VirtualDisplay so we never want to capture layers
// marked as skip capture
snapshot.handleSkipScreenshotFlag = parentSnapshot.handleSkipScreenshotFlag ||
(requested.layerStackToMirror != ui::INVALID_LAYER_STACK);
}
+ if (forceUpdate || snapshot.changes.any(RequestedLayerState::Changes::AffectsChildren) ||
+ args.displayChanges) {
+ snapshot.fixedTransformHint = requested.fixedTransformHint != ui::Transform::ROT_INVALID
+ ? requested.fixedTransformHint
+ : parentSnapshot.fixedTransformHint;
+
+ if (snapshot.fixedTransformHint != ui::Transform::ROT_INVALID) {
+ snapshot.transformHint = snapshot.fixedTransformHint;
+ } else {
+ const auto display = args.displays.get(snapshot.outputFilter.layerStack);
+ snapshot.transformHint = display.has_value()
+ ? std::make_optional<>(display->get().transformHint)
+ : std::nullopt;
+ }
+ }
+
if (forceUpdate ||
snapshot.changes.any(RequestedLayerState::Changes::FrameRate |
RequestedLayerState::Changes::Hierarchy)) {
@@ -792,7 +818,7 @@
if (forceUpdate ||
snapshot.changes.any(RequestedLayerState::Changes::Hierarchy |
RequestedLayerState::Changes::Geometry)) {
- updateLayerBounds(snapshot, requested, parentSnapshot, displayRotationFlags);
+ updateLayerBounds(snapshot, requested, parentSnapshot, primaryDisplayRotationFlags);
updateRoundedCorner(snapshot, requested, parentSnapshot);
}
@@ -863,10 +889,10 @@
void LayerSnapshotBuilder::updateLayerBounds(LayerSnapshot& snapshot,
const RequestedLayerState& requested,
const LayerSnapshot& parentSnapshot,
- uint32_t displayRotationFlags) {
+ uint32_t primaryDisplayRotationFlags) {
snapshot.croppedBufferSize = requested.getCroppedBufferSize(snapshot.bufferSize);
snapshot.geomCrop = requested.crop;
- snapshot.localTransform = requested.getTransform(displayRotationFlags);
+ snapshot.localTransform = requested.getTransform(primaryDisplayRotationFlags);
snapshot.localTransformInverse = snapshot.localTransform.inverse();
snapshot.geomLayerTransform = parentSnapshot.geomLayerTransform * snapshot.localTransform;
const bool transformWasInvalid = snapshot.invalidTransform;
@@ -880,14 +906,14 @@
requestedT.dsdy(), requestedT.dtdx(), requestedT.dtdy());
std::string bufferDebug;
if (requested.externalTexture) {
- auto unRotBuffer = requested.getUnrotatedBufferSize(displayRotationFlags);
+ auto unRotBuffer = requested.getUnrotatedBufferSize(primaryDisplayRotationFlags);
auto& destFrame = requested.destinationFrame;
bufferDebug = base::StringPrintf(" buffer={%d,%d} displayRot=%d"
" destFrame={%d,%d,%d,%d} unRotBuffer={%d,%d}",
requested.externalTexture->getWidth(),
requested.externalTexture->getHeight(),
- displayRotationFlags, destFrame.left, destFrame.top,
- destFrame.right, destFrame.bottom,
+ primaryDisplayRotationFlags, destFrame.left,
+ destFrame.top, destFrame.right, destFrame.bottom,
unRotBuffer.getHeight(), unRotBuffer.getWidth());
}
ALOGW("Resetting transform for %s because it is invalid.%s%s",
@@ -1008,12 +1034,26 @@
auto cropLayerSnapshot = getSnapshot(requested.touchCropId);
if (snapshot.inputInfo.replaceTouchableRegionWithCrop) {
- const Rect bounds(cropLayerSnapshot ? cropLayerSnapshot->transformedBounds
- : snapshot.transformedBounds);
- snapshot.inputInfo.touchableRegion = Region(displayInfo.transform.transform(bounds));
+ Rect inputBoundsInDisplaySpace;
+ if (!cropLayerSnapshot) {
+ FloatRect inputBounds = getInputBounds(snapshot, /*fillParentBounds=*/true).first;
+ inputBoundsInDisplaySpace =
+ getInputBoundsInDisplaySpace(snapshot, inputBounds, displayInfo.transform);
+ } else {
+ FloatRect inputBounds =
+ getInputBounds(*cropLayerSnapshot, /*fillParentBounds=*/true).first;
+ inputBoundsInDisplaySpace =
+ getInputBoundsInDisplaySpace(*cropLayerSnapshot, inputBounds,
+ displayInfo.transform);
+ }
+ snapshot.inputInfo.touchableRegion = Region(inputBoundsInDisplaySpace);
} else if (cropLayerSnapshot) {
+ FloatRect inputBounds = getInputBounds(*cropLayerSnapshot, /*fillParentBounds=*/true).first;
+ Rect inputBoundsInDisplaySpace =
+ getInputBoundsInDisplaySpace(*cropLayerSnapshot, inputBounds,
+ displayInfo.transform);
snapshot.inputInfo.touchableRegion = snapshot.inputInfo.touchableRegion.intersect(
- displayInfo.transform.transform(Rect{cropLayerSnapshot->transformedBounds}));
+ displayInfo.transform.transform(inputBoundsInDisplaySpace));
}
// Inherit the trusted state from the parent hierarchy, but don't clobber the trusted state
diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
index a5fdaf4..1f670c8 100644
--- a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
+++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
@@ -100,8 +100,8 @@
layerStack = ui::DEFAULT_LAYER_STACK;
transformToDisplayInverse = false;
dataspace = ui::Dataspace::UNKNOWN;
- desiredSdrHdrRatio = 1.f;
- currentSdrHdrRatio = 1.f;
+ desiredHdrSdrRatio = 1.f;
+ currentHdrSdrRatio = 1.f;
dataspaceRequested = false;
hdrMetadata.validTypes = 0;
surfaceDamageRegion = Region::INVALID_REGION;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 0f2af2f..755e585 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -52,8 +52,11 @@
#include <system/graphics-base-v1.0.h>
#include <ui/DataspaceUtils.h>
#include <ui/DebugUtils.h>
+#include <ui/FloatRect.h>
#include <ui/GraphicBuffer.h>
#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <ui/Transform.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/NativeHandle.h>
@@ -335,6 +338,7 @@
return nullptr;
}
mGetHandleCalled = true;
+ mHandleAlive = true;
return sp<LayerHandle>::make(mFlinger, sp<Layer>::fromExisting(this));
}
@@ -639,8 +643,8 @@
snapshot->surfaceDamage = surfaceDamageRegion;
snapshot->hasProtectedContent = isProtected();
snapshot->dimmingEnabled = isDimmingEnabled();
- snapshot->currentSdrHdrRatio = getCurrentSdrHdrRatio();
- snapshot->desiredSdrHdrRatio = getDesiredSdrHdrRatio();
+ snapshot->currentHdrSdrRatio = getCurrentHdrSdrRatio();
+ snapshot->desiredHdrSdrRatio = getDesiredHdrSdrRatio();
snapshot->cachingHint = getCachingHint();
const bool usesRoundedCorners = hasRoundedCorners();
@@ -1501,7 +1505,7 @@
transformHint = ui::Transform::ROT_0;
}
- setTransformHint(transformHint);
+ setTransformHintLegacy(transformHint);
}
// ----------------------------------------------------------------------------
@@ -1649,9 +1653,9 @@
mFlinger->mFrameTracer->onDestroy(layerId);
}
-size_t Layer::getChildrenCount() const {
+size_t Layer::getDescendantCount() const {
size_t count = 0;
- for (const sp<Layer>& child : mCurrentChildren) {
+ for (const sp<Layer>& child : mDrawingChildren) {
count += 1 + child->getChildrenCount();
}
return count;
@@ -1898,6 +1902,12 @@
}
}
+void Layer::traverseChildren(const LayerVector::Visitor& visitor) {
+ for (const sp<Layer>& child : mDrawingChildren) {
+ visitor(child.get());
+ }
+}
+
LayerVector Layer::makeChildrenTraversalList(LayerVector::StateSet stateSet,
const std::vector<Layer*>& layersInTree) {
LOG_ALWAYS_FATAL_IF(stateSet == LayerVector::StateSet::Invalid,
@@ -2297,62 +2307,21 @@
}
void Layer::fillInputFrameInfo(WindowInfo& info, const ui::Transform& screenToDisplay) {
- Rect tmpBounds = getInputBounds();
- if (!tmpBounds.isValid()) {
+ auto [inputBounds, inputBoundsValid] = getInputBounds(/*fillParentBounds=*/false);
+ if (!inputBoundsValid) {
info.touchableRegion.clear();
- // A layer could have invalid input bounds and still expect to receive touch input if it has
- // replaceTouchableRegionWithCrop. For that case, the input transform needs to be calculated
- // correctly to determine the coordinate space for input events. Use an empty rect so that
- // the layer will receive input in its own layer space.
- tmpBounds = Rect::EMPTY_RECT;
}
- // InputDispatcher works in the display device's coordinate space. Here, we calculate the
- // frame and transform used for the layer, which determines the bounds and the coordinate space
- // within which the layer will receive input.
- //
- // The coordinate space within which each of the bounds are specified is explicitly documented
- // in the variable name. For example "inputBoundsInLayer" is specified in layer space. A
- // Transform converts one coordinate space to another, which is apparent in its naming. For
- // example, "layerToDisplay" transforms layer space to display space.
- //
- // Coordinate space definitions:
- // - display: The display device's coordinate space. Correlates to pixels on the display.
- // - screen: The post-rotation coordinate space for the display, a.k.a. logical display space.
- // - layer: The coordinate space of this layer.
- // - input: The coordinate space in which this layer will receive input events. This could be
- // different than layer space if a surfaceInset is used, which changes the origin
- // of the input space.
- const FloatRect inputBoundsInLayer = tmpBounds.toFloatRect();
-
- // Clamp surface inset to the input bounds.
- const auto surfaceInset = static_cast<float>(info.surfaceInset);
- const float xSurfaceInset =
- std::max(0.f, std::min(surfaceInset, inputBoundsInLayer.getWidth() / 2.f));
- const float ySurfaceInset =
- std::max(0.f, std::min(surfaceInset, inputBoundsInLayer.getHeight() / 2.f));
-
- // Apply the insets to the input bounds.
- const FloatRect insetBoundsInLayer(inputBoundsInLayer.left + xSurfaceInset,
- inputBoundsInLayer.top + ySurfaceInset,
- inputBoundsInLayer.right - xSurfaceInset,
- inputBoundsInLayer.bottom - ySurfaceInset);
-
- // Crop the input bounds to ensure it is within the parent's bounds.
- const FloatRect croppedInsetBoundsInLayer = mBounds.intersect(insetBoundsInLayer);
-
- const ui::Transform layerToScreen = getInputTransform();
- const ui::Transform layerToDisplay = screenToDisplay * layerToScreen;
-
- const Rect roundedFrameInDisplay{layerToDisplay.transform(croppedInsetBoundsInLayer)};
+ const Rect roundedFrameInDisplay = getInputBoundsInDisplaySpace(inputBounds, screenToDisplay);
info.frameLeft = roundedFrameInDisplay.left;
info.frameTop = roundedFrameInDisplay.top;
info.frameRight = roundedFrameInDisplay.right;
info.frameBottom = roundedFrameInDisplay.bottom;
ui::Transform inputToLayer;
- inputToLayer.set(insetBoundsInLayer.left, insetBoundsInLayer.top);
- const ui::Transform inputToDisplay = layerToDisplay * inputToLayer;
+ inputToLayer.set(inputBounds.left, inputBounds.top);
+ const ui::Transform layerToScreen = getInputTransform();
+ const ui::Transform inputToDisplay = screenToDisplay * layerToScreen * inputToLayer;
// InputDispatcher expects a display-to-input transform.
info.transform = inputToDisplay.inverse();
@@ -2485,13 +2454,23 @@
info.inputConfig |= WindowInfo::InputConfig::DROP_INPUT;
}
- auto cropLayer = mDrawingState.touchableRegionCrop.promote();
+ sp<Layer> cropLayer = mDrawingState.touchableRegionCrop.promote();
if (info.replaceTouchableRegionWithCrop) {
- const Rect bounds(cropLayer ? cropLayer->mScreenBounds : mScreenBounds);
- info.touchableRegion = Region(displayTransform.transform(bounds));
+ Rect inputBoundsInDisplaySpace;
+ if (!cropLayer) {
+ FloatRect inputBounds = getInputBounds(/*fillParentBounds=*/true).first;
+ inputBoundsInDisplaySpace = getInputBoundsInDisplaySpace(inputBounds, displayTransform);
+ } else {
+ FloatRect inputBounds = cropLayer->getInputBounds(/*fillParentBounds=*/true).first;
+ inputBoundsInDisplaySpace =
+ cropLayer->getInputBoundsInDisplaySpace(inputBounds, displayTransform);
+ }
+ info.touchableRegion = Region(inputBoundsInDisplaySpace);
} else if (cropLayer != nullptr) {
- info.touchableRegion = info.touchableRegion.intersect(
- displayTransform.transform(Rect{cropLayer->mScreenBounds}));
+ FloatRect inputBounds = cropLayer->getInputBounds(/*fillParentBounds=*/true).first;
+ Rect inputBoundsInDisplaySpace =
+ cropLayer->getInputBoundsInDisplaySpace(inputBounds, displayTransform);
+ info.touchableRegion = info.touchableRegion.intersect(inputBoundsInDisplaySpace);
}
// Inherit the trusted state from the parent hierarchy, but don't clobber the trusted state
@@ -2513,6 +2492,27 @@
return info;
}
+Rect Layer::getInputBoundsInDisplaySpace(const FloatRect& inputBounds,
+ const ui::Transform& screenToDisplay) {
+ // InputDispatcher works in the display device's coordinate space. Here, we calculate the
+ // frame and transform used for the layer, which determines the bounds and the coordinate space
+ // within which the layer will receive input.
+
+ // Coordinate space definitions:
+ // - display: The display device's coordinate space. Correlates to pixels on the display.
+ // - screen: The post-rotation coordinate space for the display, a.k.a. logical display space.
+ // - layer: The coordinate space of this layer.
+ // - input: The coordinate space in which this layer will receive input events. This could be
+ // different than layer space if a surfaceInset is used, which changes the origin
+ // of the input space.
+
+ // Crop the input bounds to ensure it is within the parent's bounds.
+ const FloatRect croppedInputBounds = mBounds.intersect(inputBounds);
+ const ui::Transform layerToScreen = getInputTransform();
+ const ui::Transform layerToDisplay = screenToDisplay * layerToScreen;
+ return Rect{layerToDisplay.transform(croppedInputBounds)};
+}
+
sp<Layer> Layer::getClonedRoot() {
if (mClonedChild != nullptr) {
return sp<Layer>::fromExisting(this);
@@ -2865,9 +2865,13 @@
void Layer::releasePendingBuffer(nsecs_t dequeueReadyTime) {
for (const auto& handle : mDrawingState.callbackHandles) {
- handle->transformHint = mSkipReportingTransformHint
- ? std::nullopt
- : std::make_optional<uint32_t>(mTransformHint);
+ if (mFlinger->mLayerLifecycleManagerEnabled) {
+ handle->transformHint = mTransformHint;
+ } else {
+ handle->transformHint = mSkipReportingTransformHint
+ ? std::nullopt
+ : std::make_optional<uint32_t>(mTransformHintLegacy);
+ }
handle->dequeueReadyTime = dequeueReadyTime;
handle->currentMaxAcquiredBufferCount =
mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(mOwnerUid);
@@ -3141,11 +3145,11 @@
}
bool Layer::setExtendedRangeBrightness(float currentBufferRatio, float desiredRatio) {
- if (mDrawingState.currentSdrHdrRatio == currentBufferRatio &&
- mDrawingState.desiredSdrHdrRatio == desiredRatio)
+ if (mDrawingState.currentHdrSdrRatio == currentBufferRatio &&
+ mDrawingState.desiredHdrSdrRatio == desiredRatio)
return false;
- mDrawingState.currentSdrHdrRatio = currentBufferRatio;
- mDrawingState.desiredSdrHdrRatio = desiredRatio;
+ mDrawingState.currentHdrSdrRatio = currentBufferRatio;
+ mDrawingState.desiredHdrSdrRatio = desiredRatio;
mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
@@ -3168,6 +3172,7 @@
}
bool Layer::setSurfaceDamageRegion(const Region& surfaceDamage) {
+ if (mDrawingState.surfaceDamageRegion.hasSameRects(surfaceDamage)) return false;
mDrawingState.surfaceDamageRegion = surfaceDamage;
mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
@@ -3399,8 +3404,8 @@
if (lastDataspace != mBufferInfo.mDataspace) {
mFlinger->mHdrLayerInfoChanged = true;
}
- if (mBufferInfo.mDesiredSdrHdrRatio != mDrawingState.desiredSdrHdrRatio) {
- mBufferInfo.mDesiredSdrHdrRatio = mDrawingState.desiredSdrHdrRatio;
+ if (mBufferInfo.mDesiredHdrSdrRatio != mDrawingState.desiredHdrSdrRatio) {
+ mBufferInfo.mDesiredHdrSdrRatio = mDrawingState.desiredHdrSdrRatio;
mFlinger->mHdrLayerInfoChanged = true;
}
mBufferInfo.mCrop = computeBufferCrop(mDrawingState);
@@ -3461,20 +3466,46 @@
}
/**
+ * Returns the bounds used to fill the input frame and the touchable region.
+ *
* Similar to getInputTransform, we need to update the bounds to include the transform.
* This is because bounds don't include the buffer transform, where the input assumes
* that's already included.
*/
-Rect Layer::getInputBounds() const {
- if (!hasBufferOrSidebandStream()) {
- return getCroppedBufferSize(getDrawingState());
+std::pair<FloatRect, bool> Layer::getInputBounds(bool fillParentBounds) const {
+ Rect croppedBufferSize = getCroppedBufferSize(getDrawingState());
+ FloatRect inputBounds = croppedBufferSize.toFloatRect();
+ if (hasBufferOrSidebandStream() && croppedBufferSize.isValid() &&
+ mDrawingState.transform.getType() != ui::Transform::IDENTITY) {
+ inputBounds = mDrawingState.transform.transform(inputBounds);
}
- Rect bufferBounds = getCroppedBufferSize(getDrawingState());
- if (mDrawingState.transform.getType() == ui::Transform::IDENTITY || !bufferBounds.isValid()) {
- return bufferBounds;
+ bool inputBoundsValid = croppedBufferSize.isValid();
+ if (!inputBoundsValid) {
+ /**
+ * Input bounds are based on the layer crop or buffer size. But if we are using
+ * the layer bounds as the input bounds (replaceTouchableRegionWithCrop flag) then
+ * we can use the parent bounds as the input bounds if the layer does not have buffer
+ * or a crop. We want to unify this logic but because of compat reasons we cannot always
+ * use the parent bounds. A layer without a buffer can get input. So when a window is
+ * initially added, its touchable region can fill its parent layer bounds and that can
+ * have negative consequences.
+ */
+ inputBounds = fillParentBounds ? mBounds : FloatRect{};
}
- return mDrawingState.transform.transform(bufferBounds);
+
+ // Clamp surface inset to the input bounds.
+ const float inset = static_cast<float>(mDrawingState.inputInfo.surfaceInset);
+ const float xSurfaceInset = std::clamp(inset, 0.f, inputBounds.getWidth() / 2.f);
+ const float ySurfaceInset = std::clamp(inset, 0.f, inputBounds.getHeight() / 2.f);
+
+ // Apply the insets to the input bounds.
+ inputBounds.left += xSurfaceInset;
+ inputBounds.top += ySurfaceInset;
+ inputBounds.right -= xSurfaceInset;
+ inputBounds.bottom -= ySurfaceInset;
+
+ return {inputBounds, inputBoundsValid};
}
bool Layer::simpleBufferUpdate(const layer_state_t& s) const {
@@ -3660,9 +3691,9 @@
}
if (s.what & layer_state_t::eExtendedRangeBrightnessChanged) {
- if (mDrawingState.currentSdrHdrRatio != s.currentSdrHdrRatio ||
- mDrawingState.desiredSdrHdrRatio != s.desiredSdrHdrRatio) {
- ALOGV("%s: false [eDimmingEnabledChanged changed]", __func__);
+ if (mDrawingState.currentHdrSdrRatio != s.currentHdrSdrRatio ||
+ mDrawingState.desiredHdrSdrRatio != s.desiredHdrSdrRatio) {
+ ALOGV("%s: false [eExtendedRangeBrightnessChanged changed]", __func__);
return false;
}
}
@@ -4000,10 +4031,10 @@
return mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getBuffer() : nullptr;
}
-void Layer::setTransformHint(ui::Transform::RotationFlags displayTransformHint) {
- mTransformHint = getFixedTransformHint();
- if (mTransformHint == ui::Transform::ROT_INVALID) {
- mTransformHint = displayTransformHint;
+void Layer::setTransformHintLegacy(ui::Transform::RotationFlags displayTransformHint) {
+ mTransformHintLegacy = getFixedTransformHint();
+ if (mTransformHintLegacy == ui::Transform::ROT_INVALID) {
+ mTransformHintLegacy = displayTransformHint;
}
mSkipReportingTransformHint = false;
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 2fb122c..1af648a 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -225,8 +225,8 @@
gui::DropInputMode dropInputMode;
bool autoRefresh = false;
bool dimmingEnabled = true;
- float currentSdrHdrRatio = 1.f;
- float desiredSdrHdrRatio = 1.f;
+ float currentHdrSdrRatio = 1.f;
+ float desiredHdrSdrRatio = 1.f;
gui::CachingHint cachingHint = gui::CachingHint::Enabled;
int64_t latchedVsyncId = 0;
};
@@ -296,8 +296,8 @@
virtual bool hasColorTransform() const;
virtual bool isColorSpaceAgnostic() const { return mDrawingState.colorSpaceAgnostic; }
virtual bool isDimmingEnabled() const { return getDrawingState().dimmingEnabled; }
- float getDesiredSdrHdrRatio() const { return getDrawingState().desiredSdrHdrRatio; }
- float getCurrentSdrHdrRatio() const { return getDrawingState().currentSdrHdrRatio; }
+ float getDesiredHdrSdrRatio() const { return getDrawingState().desiredHdrSdrRatio; }
+ float getCurrentHdrSdrRatio() const { return getDrawingState().currentHdrSdrRatio; }
gui::CachingHint getCachingHint() const { return getDrawingState().cachingHint; }
bool setTransform(uint32_t /*transform*/);
@@ -455,8 +455,6 @@
sp<GraphicBuffer> getBuffer() const;
const std::shared_ptr<renderengine::ExternalTexture>& getExternalTexture() const;
- ui::Transform::RotationFlags getTransformHint() const { return mTransformHint; }
-
/*
* Returns if a frame is ready
*/
@@ -519,7 +517,7 @@
uint64_t mFrameNumber;
bool mFrameLatencyNeeded{false};
- float mDesiredSdrHdrRatio = 1.f;
+ float mDesiredHdrSdrRatio = 1.f;
};
BufferInfo mBufferInfo;
@@ -570,6 +568,8 @@
FloatRect getBounds(const Region& activeTransparentRegion) const;
FloatRect getBounds() const;
+ Rect getInputBoundsInDisplaySpace(const FloatRect& insetBounds,
+ const ui::Transform& displayTransform);
// Compute bounds for the layer and cache the results.
void computeBounds(FloatRect parentBounds, ui::Transform parentTransform, float shadowRadius);
@@ -700,6 +700,7 @@
void traverse(LayerVector::StateSet, const LayerVector::Visitor&);
void traverseInReverseZOrder(LayerVector::StateSet, const LayerVector::Visitor&);
void traverseInZOrder(LayerVector::StateSet, const LayerVector::Visitor&);
+ void traverseChildren(const LayerVector::Visitor&);
/**
* Traverse only children in z order, ignoring relative layers that are not children of the
@@ -707,7 +708,10 @@
*/
void traverseChildrenInZOrder(LayerVector::StateSet, const LayerVector::Visitor&);
- size_t getChildrenCount() const;
+ size_t getDescendantCount() const;
+ size_t getChildrenCount() const { return mDrawingChildren.size(); }
+ bool isHandleAlive() const { return mHandleAlive; }
+ bool onHandleDestroyed() { return mHandleAlive = false; }
// ONLY CALL THIS FROM THE LAYER DTOR!
// See b/141111965. We need to add current children to offscreen layers in
@@ -848,6 +852,11 @@
void updateMetadataSnapshot(const LayerMetadata& parentMetadata);
void updateRelativeMetadataSnapshot(const LayerMetadata& relativeLayerMetadata,
std::unordered_set<Layer*>& visited);
+ sp<Layer> getClonedFrom() const {
+ return mClonedFrom != nullptr ? mClonedFrom.promote() : nullptr;
+ }
+ bool isClone() { return mClonedFrom != nullptr; }
+
bool willPresentCurrentTransaction() const;
void callReleaseBufferCallback(const sp<ITransactionCompletedListener>& listener,
@@ -867,6 +876,9 @@
};
};
bool hasBuffer() const { return mBufferInfo.mBuffer != nullptr; }
+ void setTransformHint(std::optional<ui::Transform::RotationFlags> transformHint) {
+ mTransformHint = transformHint;
+ }
protected:
// For unit tests
@@ -885,10 +897,6 @@
void gatherBufferInfo();
void onSurfaceFrameCreated(const std::shared_ptr<frametimeline::SurfaceFrame>&);
- sp<Layer> getClonedFrom() const {
- return mClonedFrom != nullptr ? mClonedFrom.promote() : nullptr;
- }
- bool isClone() { return mClonedFrom != nullptr; }
bool isClonedFromAlive() { return getClonedFrom() != nullptr; }
void cloneDrawingState(const Layer* from);
@@ -931,7 +939,7 @@
* "replaceTouchableRegionWithCrop" is specified. In this case, the layer will receive input
* in this layer's space, regardless of the specified crop layer.
*/
- Rect getInputBounds() const;
+ std::pair<FloatRect, bool> getInputBounds(bool fillParentBounds) const;
// constant
sp<SurfaceFlinger> mFlinger;
@@ -1147,14 +1155,15 @@
float mBorderWidth;
half4 mBorderColor;
- void setTransformHint(ui::Transform::RotationFlags);
+ void setTransformHintLegacy(ui::Transform::RotationFlags);
const uint32_t mTextureName;
// Transform hint provided to the producer. This must be accessed holding
// the mStateLock.
- ui::Transform::RotationFlags mTransformHint = ui::Transform::ROT_0;
+ ui::Transform::RotationFlags mTransformHintLegacy = ui::Transform::ROT_0;
bool mSkipReportingTransformHint = true;
+ std::optional<ui::Transform::RotationFlags> mTransformHint = std::nullopt;
ReleaseCallbackId mPreviousReleaseCallbackId = ReleaseCallbackId::INVALID_ID;
uint64_t mPreviousReleasedFrameNumber = 0;
@@ -1191,6 +1200,7 @@
std::vector<std::pair<frontend::LayerHierarchy::TraversalPath, sp<LayerFE>>> mLayerFEs;
std::unique_ptr<frontend::LayerSnapshot> mSnapshot =
std::make_unique<frontend::LayerSnapshot>();
+ bool mHandleAlive = false;
};
std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate);
diff --git a/services/surfaceflinger/LayerRenderArea.cpp b/services/surfaceflinger/LayerRenderArea.cpp
index 03a7f22..1b8ff28 100644
--- a/services/surfaceflinger/LayerRenderArea.cpp
+++ b/services/surfaceflinger/LayerRenderArea.cpp
@@ -39,9 +39,12 @@
LayerRenderArea::LayerRenderArea(SurfaceFlinger& flinger, sp<Layer> layer, const Rect& crop,
ui::Size reqSize, ui::Dataspace reqDataSpace, bool childrenOnly,
- bool allowSecureLayers)
+ bool allowSecureLayers, const ui::Transform& layerTransform,
+ const Rect& layerBufferSize)
: RenderArea(reqSize, CaptureFill::CLEAR, reqDataSpace, allowSecureLayers),
mLayer(std::move(layer)),
+ mLayerTransform(layerTransform),
+ mLayerBufferSize(layerBufferSize),
mCrop(crop),
mFlinger(flinger),
mChildrenOnly(childrenOnly) {}
@@ -60,7 +63,8 @@
Rect LayerRenderArea::getSourceCrop() const {
if (mCrop.isEmpty()) {
- return mLayer->getBufferSize(mLayer->getDrawingState());
+ // TODO this should probably be mBounds instead of just buffer bounds
+ return mLayerBufferSize;
} else {
return mCrop;
}
@@ -70,7 +74,7 @@
using namespace std::string_literals;
if (!mChildrenOnly) {
- mTransform = mLayer->getTransform().inverse();
+ mTransform = mLayerTransform.inverse();
}
if (mFlinger.mLayerLifecycleManagerEnabled) {
diff --git a/services/surfaceflinger/LayerRenderArea.h b/services/surfaceflinger/LayerRenderArea.h
index 322dbd1..9bb13b3 100644
--- a/services/surfaceflinger/LayerRenderArea.h
+++ b/services/surfaceflinger/LayerRenderArea.h
@@ -33,7 +33,8 @@
class LayerRenderArea : public RenderArea {
public:
LayerRenderArea(SurfaceFlinger& flinger, sp<Layer> layer, const Rect& crop, ui::Size reqSize,
- ui::Dataspace reqDataSpace, bool childrenOnly, bool allowSecureLayers);
+ ui::Dataspace reqDataSpace, bool childrenOnly, bool allowSecureLayers,
+ const ui::Transform& layerTransform, const Rect& layerBufferSize);
const ui::Transform& getTransform() const override;
bool isSecure() const override;
@@ -45,6 +46,8 @@
private:
const sp<Layer> mLayer;
+ const ui::Transform mLayerTransform;
+ const Rect mLayerBufferSize;
const Rect mCrop;
ui::Transform mTransform;
diff --git a/services/surfaceflinger/OWNERS b/services/surfaceflinger/OWNERS
index 6011d0d..4e7da82 100644
--- a/services/surfaceflinger/OWNERS
+++ b/services/surfaceflinger/OWNERS
@@ -4,5 +4,7 @@
lpy@google.com
pdwilliams@google.com
racarr@google.com
+ramindani@google.com
+rnlee@google.com
scroggo@google.com
vishnun@google.com
diff --git a/services/surfaceflinger/Scheduler/Android.bp b/services/surfaceflinger/Scheduler/Android.bp
index 5bd8a99..d5d8688 100644
--- a/services/surfaceflinger/Scheduler/Android.bp
+++ b/services/surfaceflinger/Scheduler/Android.bp
@@ -60,7 +60,4 @@
"libgtest",
"libscheduler",
],
- sanitize: {
- address: true,
- },
}
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 3e12db6..7f8d394 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -409,7 +409,6 @@
}
void Scheduler::resyncAllToHardwareVsync(bool allowToEnable) {
- ATRACE_CALL();
std::scoped_lock lock(mDisplayLock);
ftl::FakeGuard guard(kMainThreadContext);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 8ce479a..a008346 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2563,6 +2563,7 @@
if (!dropFrame) {
refreshArgs.outputs.push_back(display->getCompositionDisplay());
}
+ display->tracePowerMode();
displayIds.push_back(display->getId());
}
mPowerAdvisor->setDisplays(displayIds);
@@ -2641,7 +2642,9 @@
CompositionResult compositionResult{layerFE->stealCompositionResult()};
layer->onPreComposition(compositionResult.refreshStartTime);
for (auto releaseFence : compositionResult.releaseFences) {
- layer->onLayerDisplayed(releaseFence);
+ Layer* clonedFrom = layer->getClonedFrom().get();
+ auto owningLayer = clonedFrom ? clonedFrom : layer;
+ owningLayer->onLayerDisplayed(releaseFence);
}
if (compositionResult.lastClientCompositionFence) {
layer->setWasClientComposed(compositionResult.lastClientCompositionFence);
@@ -2760,7 +2763,7 @@
// RANGE_EXTENDED layers may identify themselves as being "HDR" via a desired sdr/hdr ratio
if ((snapshot.dataspace & (int32_t)Dataspace::RANGE_MASK) ==
(int32_t)Dataspace::RANGE_EXTENDED &&
- snapshot.desiredSdrHdrRatio > 1.01f) {
+ snapshot.desiredHdrSdrRatio > 1.01f) {
return true;
}
return false;
@@ -2897,11 +2900,9 @@
const auto* outputLayer =
compositionDisplay->getOutputLayerForLayer(layerFe);
if (outputLayer) {
- // TODO(b/267350616): Rename SdrHdrRatio -> HdrSdrRatio
- // everywhere
- const float desiredHdrSdrRatio = snapshot.desiredSdrHdrRatio <= 1.f
+ const float desiredHdrSdrRatio = snapshot.desiredHdrSdrRatio <= 1.f
? std::numeric_limits<float>::infinity()
- : snapshot.desiredSdrHdrRatio;
+ : snapshot.desiredHdrSdrRatio;
info.mergeDesiredRatio(desiredHdrSdrRatio);
info.numberOfHdrLayers++;
const auto displayFrame = outputLayer->getState().displayFrame;
@@ -3722,8 +3723,11 @@
ATRACE_NAME("BackgroundExecutor::updateInputFlinger");
if (updateWindowInfo) {
mWindowInfosListenerInvoker
- ->windowInfosChanged(windowInfos, displayInfos,
- inputWindowCommands.windowInfosReportedListeners);
+ ->windowInfosChanged(std::move(windowInfos), std::move(displayInfos),
+ std::move(
+ inputWindowCommands.windowInfosReportedListeners),
+ /* forceImmediateCall= */
+ !inputWindowCommands.focusRequests.empty());
} else {
// If there are listeners but no changes to input windows, call the listeners
// immediately.
@@ -4090,8 +4094,34 @@
ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers.load(),
MAX_LAYERS);
static_cast<void>(mScheduler->schedule([=] {
+ ALOGE("Dumping layer keeping > 20 children alive:");
+ bool leakingParentLayerFound = false;
+ mDrawingState.traverse([&](Layer* layer) {
+ if (leakingParentLayerFound) {
+ return;
+ }
+ if (layer->getChildrenCount() > 20) {
+ leakingParentLayerFound = true;
+ sp<Layer> parent = sp<Layer>::fromExisting(layer);
+ while (parent) {
+ ALOGE("Parent Layer: %s handleIsAlive: %s", parent->getName().c_str(),
+ std::to_string(parent->isHandleAlive()).c_str());
+ parent = parent->getParent();
+ }
+ // Sample up to 100 layers
+ ALOGE("Dumping random sampling of child layers total(%zu): ",
+ layer->getChildrenCount());
+ int sampleSize = (layer->getChildrenCount() / 100) + 1;
+ layer->traverseChildren([&](Layer* layer) {
+ if (rand() % sampleSize == 0) {
+ ALOGE("Child Layer: %s", layer->getName().c_str());
+ }
+ });
+ }
+ });
+
ALOGE("Dumping random sampling of on-screen layers: ");
- mDrawingState.traverse([&](Layer *layer) {
+ mDrawingState.traverse([&](Layer* layer) {
// Aim to dump about 200 layers to avoid totally trashing
// logcat. On the other hand, if there really are 4096 layers
// something has gone totally wrong its probably the most
@@ -4100,6 +4130,8 @@
ALOGE("Layer: %s", layer->getName().c_str());
}
});
+ ALOGE("Dumping random sampling of off-screen layers total(%zu): ",
+ mOffscreenLayers.size());
for (Layer* offscreenLayer : mOffscreenLayers) {
if (rand() % 20 == 13) {
ALOGE("Offscreen-layer: %s", offscreenLayer->getName().c_str());
@@ -4145,7 +4177,6 @@
ATRACE_INT("mTransactionFlags", transactionFlags);
if (const bool scheduled = transactionFlags & mask; !scheduled) {
- mScheduler->resync();
scheduleCommit(frameHint);
} else if (frameHint == FrameHint::kActive) {
// Even if the next frame is already scheduled, we should reset the idle timer
@@ -4929,7 +4960,7 @@
if (layer->setDimmingEnabled(s.dimmingEnabled)) flags |= eTraversalNeeded;
}
if (what & layer_state_t::eExtendedRangeBrightnessChanged) {
- if (layer->setExtendedRangeBrightness(s.currentSdrHdrRatio, s.desiredSdrHdrRatio)) {
+ if (layer->setExtendedRangeBrightness(s.currentHdrSdrRatio, s.desiredHdrSdrRatio)) {
flags |= eTraversalNeeded;
}
}
@@ -5104,6 +5135,12 @@
if (layer->setSidebandStream(s.sidebandStream)) flags |= eTraversalNeeded;
}
if (what & layer_state_t::eBufferChanged) {
+ std::optional<ui::Transform::RotationFlags> transformHint = std::nullopt;
+ frontend::LayerSnapshot* snapshot = mLayerSnapshotBuilder.getSnapshot(layer->sequence);
+ if (snapshot) {
+ transformHint = snapshot->transformHint;
+ }
+ layer->setTransformHint(transformHint);
if (layer->setBuffer(composerState.externalTexture, *s.bufferData, postTime,
desiredPresentTime, isAutoTimestamp, dequeueBufferTimestamp,
frameTimelineInfo)) {
@@ -5297,6 +5334,7 @@
Mutex::Autolock lock(mStateLock);
markLayerPendingRemovalLocked(layer);
+ layer->onHandleDestroyed();
mBufferCountTracker.remove(handle);
layer.clear();
@@ -7017,13 +7055,34 @@
bool childrenOnly = args.childrenOnly;
RenderAreaFuture renderAreaFuture = ftl::defer([=]() -> std::unique_ptr<RenderArea> {
+ ui::Transform layerTransform;
+ Rect layerBufferSize;
+ if (mLayerLifecycleManagerEnabled) {
+ frontend::LayerSnapshot* snapshot =
+ mLayerSnapshotBuilder.getSnapshot(parent->getSequence());
+ if (!snapshot) {
+ ALOGW("Couldn't find layer snapshot for %d", parent->getSequence());
+ } else {
+ layerTransform = snapshot->localTransform;
+ layerBufferSize = snapshot->bufferSize;
+ }
+ } else {
+ layerTransform = parent->getTransform();
+ layerBufferSize = parent->getBufferSize(parent->getDrawingState());
+ }
+
return std::make_unique<LayerRenderArea>(*this, parent, crop, reqSize, dataspace,
- childrenOnly, args.captureSecureLayers);
+ childrenOnly, args.captureSecureLayers,
+ layerTransform, layerBufferSize);
});
GetLayerSnapshotsFunction getLayerSnapshots;
if (mLayerLifecycleManagerEnabled) {
- FloatRect parentCrop = crop.isEmpty() ? FloatRect(0, 0, reqSize.width, reqSize.height)
- : crop.toFloatRect();
+ std::optional<FloatRect> parentCrop = std::nullopt;
+ if (args.childrenOnly) {
+ parentCrop = crop.isEmpty() ? FloatRect(0, 0, reqSize.width, reqSize.height)
+ : crop.toFloatRect();
+ }
+
getLayerSnapshots = getLayerSnapshotsForScreenshots(parent->sequence, args.uid,
std::move(excludeLayerIds),
args.childrenOnly, parentCrop);
@@ -7973,7 +8032,7 @@
if (layerStack && snapshot->outputFilter.layerStack != *layerStack) {
return;
}
- if (uid != CaptureArgs::UNSET_UID && snapshot->inputInfo.ownerUid != uid) {
+ if (uid != CaptureArgs::UNSET_UID && snapshot->uid != uid) {
return;
}
if (!snapshot->hasSomethingToDraw()) {
@@ -8000,7 +8059,8 @@
std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()>
SurfaceFlinger::getLayerSnapshotsForScreenshots(uint32_t rootLayerId, uint32_t uid,
std::unordered_set<uint32_t> excludeLayerIds,
- bool childrenOnly, const FloatRect& parentCrop) {
+ bool childrenOnly,
+ const std::optional<FloatRect>& parentCrop) {
return [&, rootLayerId, uid, excludeLayerIds = std::move(excludeLayerIds), childrenOnly,
parentCrop]() {
auto root = mLayerHierarchyBuilder.getPartialHierarchy(rootLayerId, childrenOnly);
@@ -8013,7 +8073,7 @@
.globalShadowSettings = mDrawingState.globalShadowSettings,
.supportsBlur = mSupportsBlur,
.forceFullDamage = mForceFullDamage,
- .parentCrop = {parentCrop},
+ .parentCrop = parentCrop,
.excludeLayerIds = std::move(excludeLayerIds),
.supportedLayerGenericMetadata =
getHwComposer().getSupportedLayerGenericMetadata(),
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 42d5db7..74d00dd 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1382,7 +1382,7 @@
snapshotFilterFn);
std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()> getLayerSnapshotsForScreenshots(
uint32_t rootLayerId, uint32_t uid, std::unordered_set<uint32_t> excludeLayerIds,
- bool childrenOnly, const FloatRect& parentCrop);
+ bool childrenOnly, const std::optional<FloatRect>& optionalParentCrop);
const sp<WindowInfosListenerInvoker> mWindowInfosListenerInvoker;
diff --git a/services/surfaceflinger/TEST_MAPPING b/services/surfaceflinger/TEST_MAPPING
index cab33ae..57752b7 100644
--- a/services/surfaceflinger/TEST_MAPPING
+++ b/services/surfaceflinger/TEST_MAPPING
@@ -5,6 +5,14 @@
},
{
"name": "libcompositionengine_test"
+ },
+ {
+ "name": "libscheduler_test"
+ }
+ ],
+ "hwasan-presubmit": [
+ {
+ "name": "libscheduler_test"
}
]
}
diff --git a/services/surfaceflinger/TracedOrdinal.h b/services/surfaceflinger/TracedOrdinal.h
index 558b3be..1adc3a5 100644
--- a/services/surfaceflinger/TracedOrdinal.h
+++ b/services/surfaceflinger/TracedOrdinal.h
@@ -24,16 +24,24 @@
#include <cutils/compiler.h>
#include <utils/Trace.h>
-namespace std {
-template <class Rep, class Period>
-bool signbit(std::chrono::duration<Rep, Period> v) {
- return signbit(std::chrono::duration_cast<std::chrono::nanoseconds>(v).count());
-}
-} // namespace std
-
namespace android {
namespace {
+template <class Rep, class Period>
+bool signbit(std::chrono::duration<Rep, Period> v) {
+ return std::signbit(std::chrono::duration_cast<std::chrono::nanoseconds>(v).count());
+}
+
+template <typename Enum, typename std::enable_if<std::is_enum<Enum>::value>::type* = nullptr>
+bool signbit(Enum e) {
+ return std::signbit(static_cast<typename std::underlying_type<Enum>::type>(e));
+}
+
+template <typename T, typename std::enable_if<!std::is_enum<T>::value>::type* = nullptr>
+bool signbit(T t) {
+ return std::signbit(t);
+}
+
template <typename T>
int64_t to_int64(T v) {
return int64_t(v);
@@ -49,14 +57,12 @@
class TracedOrdinal {
public:
static_assert(std::is_same<bool, T>() || (std::is_signed<T>() && std::is_integral<T>()) ||
- std::is_same<std::chrono::nanoseconds, T>(),
+ std::is_same<std::chrono::nanoseconds, T>() || std::is_enum<T>(),
"Type is not supported. Please test it with systrace before adding "
"it to the list.");
TracedOrdinal(std::string name, T initialValue)
- : mName(std::move(name)),
- mHasGoneNegative(std::signbit(initialValue)),
- mData(initialValue) {
+ : mName(std::move(name)), mHasGoneNegative(signbit(initialValue)), mData(initialValue) {
trace();
}
@@ -66,7 +72,7 @@
TracedOrdinal& operator=(T other) {
mData = other;
- mHasGoneNegative = mHasGoneNegative || std::signbit(mData);
+ mHasGoneNegative = mHasGoneNegative || signbit(mData);
trace();
return *this;
}
@@ -81,7 +87,7 @@
mNameNegative = mName + "Negative";
}
- if (!std::signbit(mData)) {
+ if (!signbit(mData)) {
ATRACE_INT64(mName.c_str(), to_int64(mData));
if (mHasGoneNegative) {
ATRACE_INT64(mNameNegative.c_str(), 0);
diff --git a/services/surfaceflinger/Tracing/LayerTracing.cpp b/services/surfaceflinger/Tracing/LayerTracing.cpp
index 2918f7c..ecdeabe 100644
--- a/services/surfaceflinger/Tracing/LayerTracing.cpp
+++ b/services/surfaceflinger/Tracing/LayerTracing.cpp
@@ -18,6 +18,8 @@
#define LOG_TAG "LayerTracing"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#include <filesystem>
+
#include <SurfaceFlinger.h>
#include <android-base/stringprintf.h>
#include <log/log.h>
@@ -44,30 +46,39 @@
return true;
}
-bool LayerTracing::disable(std::string filename) {
+bool LayerTracing::disable(std::string filename, bool writeToFile) {
std::scoped_lock lock(mTraceLock);
if (!mEnabled) {
return false;
}
mEnabled = false;
- LayersTraceFileProto fileProto = createTraceFileProto();
- mBuffer->writeToFile(fileProto, filename);
+ if (writeToFile) {
+ LayersTraceFileProto fileProto = createTraceFileProto();
+ mBuffer->writeToFile(fileProto, filename);
+ }
mBuffer->reset();
return true;
}
+void LayerTracing::appendToStream(std::ofstream& out) {
+ std::scoped_lock lock(mTraceLock);
+ LayersTraceFileProto fileProto = createTraceFileProto();
+ mBuffer->appendToStream(fileProto, out);
+ mBuffer->reset();
+}
+
bool LayerTracing::isEnabled() const {
std::scoped_lock lock(mTraceLock);
return mEnabled;
}
-status_t LayerTracing::writeToFile() {
+status_t LayerTracing::writeToFile(std::string filename) {
std::scoped_lock lock(mTraceLock);
if (!mEnabled) {
return STATUS_OK;
}
LayersTraceFileProto fileProto = createTraceFileProto();
- return mBuffer->writeToFile(fileProto, FILE_NAME);
+ return mBuffer->writeToFile(fileProto, filename);
}
void LayerTracing::setTraceFlags(uint32_t flags) {
diff --git a/services/surfaceflinger/Tracing/LayerTracing.h b/services/surfaceflinger/Tracing/LayerTracing.h
index 11bb9f4..40b0fbe 100644
--- a/services/surfaceflinger/Tracing/LayerTracing.h
+++ b/services/surfaceflinger/Tracing/LayerTracing.h
@@ -43,9 +43,10 @@
LayerTracing();
~LayerTracing();
bool enable();
- bool disable(std::string filename = FILE_NAME);
+ bool disable(std::string filename = FILE_NAME, bool writeToFile = true);
+ void appendToStream(std::ofstream& out);
bool isEnabled() const;
- status_t writeToFile();
+ status_t writeToFile(std::string filename = FILE_NAME);
static LayersTraceFileProto createTraceFileProto();
void notify(bool visibleRegionDirty, int64_t time, int64_t vsyncId, LayersProto* layers,
std::string hwcDump, google::protobuf::RepeatedPtrField<DisplayProto>* displays);
diff --git a/services/surfaceflinger/Tracing/RingBuffer.h b/services/surfaceflinger/Tracing/RingBuffer.h
index 7e38c55..b41c65b 100644
--- a/services/surfaceflinger/Tracing/RingBuffer.h
+++ b/services/surfaceflinger/Tracing/RingBuffer.h
@@ -24,6 +24,7 @@
#include <utils/Timers.h>
#include <utils/Trace.h>
#include <chrono>
+#include <fstream>
#include <queue>
namespace android {
@@ -73,6 +74,19 @@
return NO_ERROR;
}
+ status_t appendToStream(FileProto& fileProto, std::ofstream& out) {
+ ATRACE_CALL();
+ writeToProto(fileProto);
+ std::string output;
+ if (!fileProto.SerializeToString(&output)) {
+ ALOGE("Could not serialize proto.");
+ return UNKNOWN_ERROR;
+ }
+
+ out << output;
+ return NO_ERROR;
+ }
+
std::vector<std::string> emplace(std::string&& serializedProto) {
std::vector<std::string> replacedEntries;
size_t protoSize = static_cast<size_t>(serializedProto.size());
diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
index 8fd6538..7642122 100644
--- a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
+++ b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
@@ -27,9 +27,7 @@
namespace android::surfaceflinger {
class FakeExternalTexture : public renderengine::ExternalTexture {
- const sp<GraphicBuffer> mEmptyBuffer =
- sp<GraphicBuffer>::make(1u, 1u, PIXEL_FORMAT_RGBA_8888,
- GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN);
+ const sp<GraphicBuffer> mEmptyBuffer = nullptr;
uint32_t mWidth;
uint32_t mHeight;
uint64_t mId;
diff --git a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
index 2418cf2..0ea421b 100644
--- a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
+++ b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <ios>
#include <memory>
#include <vector>
#include "FrontEnd/LayerCreationArgs.h"
@@ -62,8 +63,11 @@
LayerTracing layerTracing;
layerTracing.setTraceFlags(LayerTracing::TRACE_INPUT | LayerTracing::TRACE_BUFFERS);
- layerTracing.setBufferSize(512 * 1024 * 1024); // 512MB buffer size
+ // 10MB buffer size (large enough to hold a single entry)
+ layerTracing.setBufferSize(10 * 1024 * 1024);
layerTracing.enable();
+ layerTracing.writeToFile(outputLayersTracePath);
+ std::ofstream out(outputLayersTracePath, std::ios::binary | std::ios::app);
ALOGD("Generating %d transactions...", traceFile.entry_size());
for (int i = 0; i < traceFile.entry_size(); i++) {
@@ -141,8 +145,10 @@
auto displayProtos = LayerProtoHelper::writeDisplayInfoToProto(displayInfos);
layerTracing.notify(visibleRegionsDirty, entry.elapsed_realtime_nanos(), entry.vsync_id(),
&layersProto, {}, &displayProtos);
+ layerTracing.appendToStream(out);
}
- layerTracing.disable(outputLayersTracePath);
+ layerTracing.disable("", /*writeToFile=*/false);
+ out.close();
ALOGD("End of generating trace file. File written to %s", outputLayersTracePath);
return true;
}
diff --git a/services/surfaceflinger/WindowInfosListenerInvoker.cpp b/services/surfaceflinger/WindowInfosListenerInvoker.cpp
index 292083b..73a7cae 100644
--- a/services/surfaceflinger/WindowInfosListenerInvoker.cpp
+++ b/services/surfaceflinger/WindowInfosListenerInvoker.cpp
@@ -25,20 +25,14 @@
using gui::IWindowInfosListener;
using gui::WindowInfo;
-struct WindowInfosListenerInvoker::WindowInfosReportedListener : gui::BnWindowInfosReportedListener,
- DeathRecipient {
- explicit WindowInfosReportedListener(
- size_t callbackCount,
- const std::unordered_set<sp<gui::IWindowInfosReportedListener>,
- SpHash<gui::IWindowInfosReportedListener>>&
- windowInfosReportedListeners)
+struct WindowInfosReportedListenerInvoker : gui::BnWindowInfosReportedListener,
+ IBinder::DeathRecipient {
+ WindowInfosReportedListenerInvoker(size_t callbackCount,
+ WindowInfosReportedListenerSet windowInfosReportedListeners)
: mCallbacksPending(callbackCount),
- mWindowInfosReportedListeners(windowInfosReportedListeners) {}
+ mWindowInfosReportedListeners(std::move(windowInfosReportedListeners)) {}
binder::Status onWindowInfosReported() override {
- // TODO(b/222421815) There could potentially be callbacks that we don't need to wait for
- // before calling the WindowInfosReportedListeners coming from InputWindowCommands. Filter
- // the list of callbacks down to those from system server.
if (--mCallbacksPending == 0) {
for (const auto& listener : mWindowInfosReportedListeners) {
sp<IBinder> asBinder = IInterface::asBinder(listener);
@@ -54,9 +48,7 @@
private:
std::atomic<size_t> mCallbacksPending;
- std::unordered_set<sp<gui::IWindowInfosReportedListener>,
- SpHash<gui::IWindowInfosReportedListener>>
- mWindowInfosReportedListeners;
+ WindowInfosReportedListenerSet mWindowInfosReportedListeners;
};
void WindowInfosListenerInvoker::addWindowInfosListener(sp<IWindowInfosListener> listener) {
@@ -82,38 +74,76 @@
}
void WindowInfosListenerInvoker::windowInfosChanged(
- const std::vector<WindowInfo>& windowInfos, const std::vector<DisplayInfo>& displayInfos,
- const std::unordered_set<sp<gui::IWindowInfosReportedListener>,
- SpHash<gui::IWindowInfosReportedListener>>&
- windowInfosReportedListeners) {
- ftl::SmallVector<const sp<IWindowInfosListener>, kStaticCapacity> windowInfosListeners;
+ std::vector<WindowInfo> windowInfos, std::vector<DisplayInfo> displayInfos,
+ WindowInfosReportedListenerSet reportedListeners, bool forceImmediateCall) {
+ reportedListeners.insert(sp<WindowInfosListenerInvoker>::fromExisting(this));
+ auto callListeners = [this, windowInfos = std::move(windowInfos),
+ displayInfos = std::move(displayInfos),
+ reportedListeners = std::move(reportedListeners)]() mutable {
+ ftl::SmallVector<const sp<IWindowInfosListener>, kStaticCapacity> windowInfosListeners;
+ {
+ std::scoped_lock lock(mListenersMutex);
+ for (const auto& [_, listener] : mWindowInfosListeners) {
+ windowInfosListeners.push_back(listener);
+ }
+ }
+
+ auto reportedInvoker =
+ sp<WindowInfosReportedListenerInvoker>::make(windowInfosListeners.size(),
+ std::move(reportedListeners));
+
+ for (const auto& listener : windowInfosListeners) {
+ sp<IBinder> asBinder = IInterface::asBinder(listener);
+
+ // linkToDeath is used here to ensure that the windowInfosReportedListeners
+ // are called even if one of the windowInfosListeners dies before
+ // calling onWindowInfosReported.
+ asBinder->linkToDeath(reportedInvoker);
+
+ auto status =
+ listener->onWindowInfosChanged(windowInfos, displayInfos, reportedInvoker);
+ if (!status.isOk()) {
+ reportedInvoker->onWindowInfosReported();
+ }
+ }
+ };
+
{
- std::scoped_lock lock(mListenersMutex);
- for (const auto& [_, listener] : mWindowInfosListeners) {
- windowInfosListeners.push_back(listener);
+ std::scoped_lock lock(mMessagesMutex);
+ // If there are unacked messages and this isn't a forced call, then return immediately.
+ // If a forced window infos change doesn't happen first, the update will be sent after
+ // the WindowInfosReportedListeners are called. If a forced window infos change happens or
+ // if there are subsequent delayed messages before this update is sent, then this message
+ // will be dropped and the listeners will only be called with the latest info. This is done
+ // to reduce the amount of binder memory used.
+ if (mActiveMessageCount > 0 && !forceImmediateCall) {
+ mWindowInfosChangedDelayed = std::move(callListeners);
+ return;
}
+
+ mWindowInfosChangedDelayed = nullptr;
+ mActiveMessageCount++;
+ }
+ callListeners();
+}
+
+binder::Status WindowInfosListenerInvoker::onWindowInfosReported() {
+ std::function<void()> callListeners;
+
+ {
+ std::scoped_lock lock{mMessagesMutex};
+ mActiveMessageCount--;
+ if (!mWindowInfosChangedDelayed || mActiveMessageCount > 0) {
+ return binder::Status::ok();
+ }
+
+ mActiveMessageCount++;
+ callListeners = std::move(mWindowInfosChangedDelayed);
+ mWindowInfosChangedDelayed = nullptr;
}
- auto windowInfosReportedListener = windowInfosReportedListeners.empty()
- ? nullptr
- : sp<WindowInfosReportedListener>::make(windowInfosListeners.size(),
- windowInfosReportedListeners);
- for (const auto& listener : windowInfosListeners) {
- sp<IBinder> asBinder = IInterface::asBinder(listener);
-
- // linkToDeath is used here to ensure that the windowInfosReportedListeners
- // are called even if one of the windowInfosListeners dies before
- // calling onWindowInfosReported.
- if (windowInfosReportedListener) {
- asBinder->linkToDeath(windowInfosReportedListener);
- }
-
- auto status = listener->onWindowInfosChanged(windowInfos, displayInfos,
- windowInfosReportedListener);
- if (windowInfosReportedListener && !status.isOk()) {
- windowInfosReportedListener->onWindowInfosReported();
- }
- }
+ callListeners();
+ return binder::Status::ok();
}
} // namespace android
diff --git a/services/surfaceflinger/WindowInfosListenerInvoker.h b/services/surfaceflinger/WindowInfosListenerInvoker.h
index d60a9c4..bfe036e 100644
--- a/services/surfaceflinger/WindowInfosListenerInvoker.h
+++ b/services/surfaceflinger/WindowInfosListenerInvoker.h
@@ -23,34 +23,40 @@
#include <android/gui/IWindowInfosReportedListener.h>
#include <binder/IBinder.h>
#include <ftl/small_map.h>
+#include <gui/SpHash.h>
#include <utils/Mutex.h>
namespace android {
-class SurfaceFlinger;
+using WindowInfosReportedListenerSet =
+ std::unordered_set<sp<gui::IWindowInfosReportedListener>,
+ gui::SpHash<gui::IWindowInfosReportedListener>>;
-class WindowInfosListenerInvoker : public IBinder::DeathRecipient {
+class WindowInfosListenerInvoker : public gui::BnWindowInfosReportedListener,
+ public IBinder::DeathRecipient {
public:
void addWindowInfosListener(sp<gui::IWindowInfosListener>);
void removeWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener);
- void windowInfosChanged(const std::vector<gui::WindowInfo>&,
- const std::vector<gui::DisplayInfo>&,
- const std::unordered_set<sp<gui::IWindowInfosReportedListener>,
- SpHash<gui::IWindowInfosReportedListener>>&
- windowInfosReportedListeners);
+ void windowInfosChanged(std::vector<gui::WindowInfo>, std::vector<gui::DisplayInfo>,
+ WindowInfosReportedListenerSet windowInfosReportedListeners,
+ bool forceImmediateCall);
+
+ binder::Status onWindowInfosReported() override;
protected:
void binderDied(const wp<IBinder>& who) override;
private:
- struct WindowInfosReportedListener;
-
std::mutex mListenersMutex;
static constexpr size_t kStaticCapacity = 3;
ftl::SmallMap<wp<IBinder>, const sp<gui::IWindowInfosListener>, kStaticCapacity>
mWindowInfosListeners GUARDED_BY(mListenersMutex);
+
+ std::mutex mMessagesMutex;
+ uint32_t mActiveMessageCount GUARDED_BY(mMessagesMutex) = 0;
+ std::function<void()> mWindowInfosChangedDelayed GUARDED_BY(mMessagesMutex);
};
} // namespace android
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
index c088e7b..4304259 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
@@ -25,6 +25,7 @@
#include <gui/WindowInfo.h>
#include <renderengine/mock/FakeExternalTexture.h>
#include <ui/DisplayStatInfo.h>
+#include <ui/Transform.h>
#include <FuzzableDataspaces.h>
#include <surfaceflinger_fuzzers_utils.h>
@@ -42,6 +43,7 @@
void invokeEffectLayer();
LayerCreationArgs createLayerCreationArgs(TestableSurfaceFlinger* flinger, sp<Client> client);
Rect getFuzzedRect();
+ ui::Transform getFuzzedTransform();
FrameTimelineInfo getFuzzedFrameTimelineInfo();
private:
@@ -54,6 +56,12 @@
mFdp.ConsumeIntegral<int32_t>() /*bottom*/);
}
+ui::Transform LayerFuzzer::getFuzzedTransform() {
+ return ui::Transform(mFdp.ConsumeIntegral<int32_t>() /*orientation*/,
+ mFdp.ConsumeIntegral<int32_t>() /*width*/,
+ mFdp.ConsumeIntegral<int32_t>() /*height*/);
+}
+
FrameTimelineInfo LayerFuzzer::getFuzzedFrameTimelineInfo() {
FrameTimelineInfo ftInfo;
ftInfo.vsyncId = mFdp.ConsumeIntegral<int64_t>();
@@ -166,7 +174,7 @@
{mFdp.ConsumeIntegral<int32_t>(),
mFdp.ConsumeIntegral<int32_t>()} /*reqSize*/,
mFdp.PickValueInArray(kDataspaces), mFdp.ConsumeBool(),
- mFdp.ConsumeBool());
+ mFdp.ConsumeBool(), getFuzzedTransform(), getFuzzedRect());
layerArea.render([]() {} /*drawLayers*/);
if (!ownsHandle) {
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index 6d12aa7..62b539a 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -125,6 +125,9 @@
],
cpp_std: "experimental",
gnu_extensions: false,
+ data: [
+ ":SurfaceFlinger_test",
+ ],
}
subdirs = [
diff --git a/services/surfaceflinger/tests/WindowInfosListener_test.cpp b/services/surfaceflinger/tests/WindowInfosListener_test.cpp
index d71486f..f4a8f03 100644
--- a/services/surfaceflinger/tests/WindowInfosListener_test.cpp
+++ b/services/surfaceflinger/tests/WindowInfosListener_test.cpp
@@ -17,6 +17,7 @@
#include <gtest/gtest.h>
#include <gui/SurfaceComposerClient.h>
#include <private/android_filesystem_config.h>
+#include <cstdint>
#include <future>
namespace android {
@@ -65,14 +66,14 @@
}
};
-std::optional<WindowInfo> findMatchingWindowInfo(WindowInfo targetWindowInfo,
- std::vector<WindowInfo> windowInfos) {
- for (WindowInfo windowInfo : windowInfos) {
+const WindowInfo* findMatchingWindowInfo(const WindowInfo& targetWindowInfo,
+ const std::vector<WindowInfo>& windowInfos) {
+ for (const WindowInfo& windowInfo : windowInfos) {
if (windowInfo.token == targetWindowInfo.token) {
- return windowInfo;
+ return &windowInfo;
}
}
- return std::nullopt;
+ return nullptr;
}
TEST_F(WindowInfosListenerTest, WindowInfoAddedAndRemoved) {
@@ -93,14 +94,14 @@
.apply();
auto windowPresent = [&](const std::vector<WindowInfo>& windowInfos) {
- return findMatchingWindowInfo(windowInfo, windowInfos).has_value();
+ return findMatchingWindowInfo(windowInfo, windowInfos);
};
ASSERT_TRUE(waitForWindowInfosPredicate(windowPresent));
Transaction().reparent(surfaceControl, nullptr).apply();
auto windowNotPresent = [&](const std::vector<WindowInfo>& windowInfos) {
- return !findMatchingWindowInfo(windowInfo, windowInfos).has_value();
+ return !findMatchingWindowInfo(windowInfo, windowInfos);
};
ASSERT_TRUE(waitForWindowInfosPredicate(windowNotPresent));
}
@@ -132,8 +133,7 @@
};
ASSERT_TRUE(waitForWindowInfosPredicate(windowIsPresentAndTouchableRegionEmpty));
- Rect touchableRegions(0, 0, 50, 50);
- windowInfo.addTouchableRegion(Rect(0, 0, 50, 50));
+ windowInfo.addTouchableRegion({0, 0, 50, 50});
Transaction().setInputWindowInfo(surfaceControl, windowInfo).apply();
auto windowIsPresentAndTouchableRegionMatches =
@@ -142,7 +142,10 @@
if (!foundWindowInfo) {
return false;
}
- return foundWindowInfo->touchableRegion.hasSameRects(windowInfo.touchableRegion);
+
+ auto touchableRegion =
+ foundWindowInfo->transform.transform(foundWindowInfo->touchableRegion);
+ return touchableRegion.hasSameRects(windowInfo.touchableRegion);
};
ASSERT_TRUE(waitForWindowInfosPredicate(windowIsPresentAndTouchableRegionMatches));
}
diff --git a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
index abd7789..d26ef3c 100644
--- a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
+++ b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
@@ -489,7 +489,7 @@
auto displayFrame0 = getDisplayFrame(0);
EXPECT_EQ(displayFrame0->getActuals().presentTime, 59);
- EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown);
+ EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown | JankType::DisplayHAL);
EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
}
@@ -2259,6 +2259,7 @@
mFrameTimeline->setSfWakeUp(sfToken3, 72, Fps::fromPeriodNsecs(11));
mFrameTimeline->setSfPresent(80, validPresentFence);
+ erroneousPresentFence2->signalForTest(2);
validPresentFence->signalForTest(80);
addEmptyDisplayFrame();
@@ -2268,14 +2269,14 @@
EXPECT_EQ(displayFrame->getActuals().presentTime, 26);
EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
- EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
+ EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
}
{
auto displayFrame = getDisplayFrame(1);
EXPECT_EQ(displayFrame->getActuals().presentTime, 60);
EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
- EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
+ EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
}
{
auto displayFrame = getDisplayFrame(2);
diff --git a/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp b/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp
index 74541ac..82aac7e 100644
--- a/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp
@@ -21,8 +21,10 @@
#include <cstdint>
#include "Client.h"
+#include <layerproto/LayerProtoHeader.h>
#include "FrontEnd/LayerCreationArgs.h"
#include "FrontEnd/Update.h"
+#include "Tracing/LayerTracing.h"
#include "Tracing/RingBuffer.h"
#include "Tracing/TransactionTracing.h"
@@ -305,4 +307,24 @@
EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 2);
EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(1).z(), 43);
}
+
+// Verify we can write the layers traces by entry to reduce mem pressure
+// on the system when generating large traces.
+TEST(LayerTraceTest, canStreamLayersTrace) {
+ LayersTraceFileProto inProto = LayerTracing::createTraceFileProto();
+ inProto.add_entry();
+ inProto.add_entry();
+
+ std::string output;
+ inProto.SerializeToString(&output);
+ LayersTraceFileProto inProto2 = LayerTracing::createTraceFileProto();
+ inProto2.add_entry();
+ std::string output2;
+ inProto2.SerializeToString(&output2);
+
+ LayersTraceFileProto outProto;
+ outProto.ParseFromString(output + output2);
+ // magic?
+ EXPECT_EQ(outProto.entry().size(), 3);
+}
} // namespace android
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 1bff50d..dec3b20 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -514,7 +514,6 @@
case VK_FORMAT_R8_UNORM:
native_format = android::PIXEL_FORMAT_R_8;
break;
- // TODO: Do we need to query for VK_EXT_rgba10x6_formats here?
case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
native_format = android::PIXEL_FORMAT_RGBA_10101010;
break;
@@ -805,9 +804,23 @@
}
}
- // TODO query VK_EXT_rgba10x6_formats support
+ bool rgba10x6_formats_ext = false;
+ uint32_t exts_count;
+ const auto& driver = GetData(pdev).driver;
+ driver.EnumerateDeviceExtensionProperties(pdev, nullptr, &exts_count,
+ nullptr);
+ std::vector<VkExtensionProperties> props(exts_count);
+ driver.EnumerateDeviceExtensionProperties(pdev, nullptr, &exts_count,
+ props.data());
+ for (uint32_t i = 0; i < exts_count; i++) {
+ VkExtensionProperties prop = props[i];
+ if (strcmp(prop.extensionName,
+ VK_EXT_RGBA10X6_FORMATS_EXTENSION_NAME) == 0) {
+ rgba10x6_formats_ext = true;
+ }
+ }
desc.format = AHARDWAREBUFFER_FORMAT_R10G10B10A10_UNORM;
- if (AHardwareBuffer_isSupported(&desc)) {
+ if (AHardwareBuffer_isSupported(&desc) && rgba10x6_formats_ext) {
all_formats.emplace_back(
VkSurfaceFormatKHR{VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
VK_COLOR_SPACE_SRGB_NONLINEAR_KHR});