diff options
96 files changed, 2310 insertions, 879 deletions
diff --git a/cmds/dumpstate/DumpstateService.cpp b/cmds/dumpstate/DumpstateService.cpp index 77915d5376..e42ee0540b 100644 --- a/cmds/dumpstate/DumpstateService.cpp +++ b/cmds/dumpstate/DumpstateService.cpp @@ -202,7 +202,6 @@ status_t DumpstateService::dump(int fd, const Vector<String16>&) { dprintf(fd, "base_name: %s\n", ds_->base_name_.c_str()); dprintf(fd, "name: %s\n", ds_->name_.c_str()); dprintf(fd, "now: %ld\n", ds_->now_); - dprintf(fd, "is_zipping: %s\n", ds_->IsZipping() ? "true" : "false"); dprintf(fd, "notification title: %s\n", ds_->options_->notification_title.c_str()); dprintf(fd, "notification description: %s\n", ds_->options_->notification_description.c_str()); diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp index e97949eb1d..8ccd940bcf 100644 --- a/cmds/dumpstate/dumpstate.cpp +++ b/cmds/dumpstate/dumpstate.cpp @@ -371,14 +371,10 @@ static const CommandOptions AS_ROOT_20 = CommandOptions::WithTimeout(20).AsRoot( /* * Returns a vector of dump fds under |dir_path| with a given |file_prefix|. * The returned vector is sorted by the mtimes of the dumps with descending - * order. If |limit_by_mtime| is set, the vector only contains files that - * were written in the last 30 minutes. + * order. */ static std::vector<DumpData> GetDumpFds(const std::string& dir_path, - const std::string& file_prefix, - bool limit_by_mtime) { - const time_t thirty_minutes_ago = ds.now_ - 60 * 30; - + const std::string& file_prefix) { std::unique_ptr<DIR, decltype(&closedir)> dump_dir(opendir(dir_path.c_str()), closedir); if (dump_dir == nullptr) { @@ -412,11 +408,6 @@ static std::vector<DumpData> GetDumpFds(const std::string& dir_path, continue; } - if (limit_by_mtime && st.st_mtime < thirty_minutes_ago) { - MYLOGI("Excluding stale dump file: %s\n", abs_path.c_str()); - continue; - } - dump_data.emplace_back(DumpData{abs_path, std::move(fd), st.st_mtime}); } if (!dump_data.empty()) { @@ -447,7 +438,7 @@ static bool AddDumps(const std::vector<DumpData>::const_iterator start, strerror(errno)); } - if (ds.IsZipping() && add_to_zip) { + if (add_to_zip) { if (ds.AddZipEntryFromFd(ZIP_ROOT_DIR + name, fd, /* timeout = */ 0ms) != OK) { MYLOGE("Unable to add %s to zip file, addZipEntryFromFd failed\n", name.c_str()); } @@ -486,7 +477,6 @@ void do_mountinfo(int pid, const char* name __attribute__((unused))) { } void add_mountinfo() { - if (!ds.IsZipping()) return; std::string title = "MOUNT INFO"; mount_points.clear(); DurationReporter duration_reporter(title, true); @@ -823,11 +813,6 @@ static const std::set<std::string> PROBLEMATIC_FILE_EXTENSIONS = { status_t Dumpstate::AddZipEntryFromFd(const std::string& entry_name, int fd, std::chrono::milliseconds timeout = 0ms) { - if (!IsZipping()) { - MYLOGD("Not adding zip entry %s from fd because it's not a zipped bugreport\n", - entry_name.c_str()); - return INVALID_OPERATION; - } std::string valid_name = entry_name; // Rename extension if necessary. @@ -928,21 +913,12 @@ static int _add_file_from_fd(const char* title __attribute__((unused)), const ch } void Dumpstate::AddDir(const std::string& dir, bool recursive) { - if (!IsZipping()) { - MYLOGD("Not adding dir %s because it's not a zipped bugreport\n", dir.c_str()); - return; - } MYLOGD("Adding dir %s (recursive: %d)\n", dir.c_str(), recursive); DurationReporter duration_reporter(dir, true); dump_files("", dir.c_str(), recursive ? skip_none : is_dir, _add_file_from_fd); } bool Dumpstate::AddTextZipEntry(const std::string& entry_name, const std::string& content) { - if (!IsZipping()) { - MYLOGD("Not adding text zip entry %s because it's not a zipped bugreport\n", - entry_name.c_str()); - return false; - } MYLOGD("Adding zip text entry %s\n", entry_name.c_str()); int32_t err = zip_writer_->StartEntryWithTime(entry_name.c_str(), ZipWriter::kCompress, ds.now_); if (err != 0) { @@ -1035,10 +1011,6 @@ static void DoLogcat() { } static void DumpIncidentReport() { - if (!ds.IsZipping()) { - MYLOGD("Not dumping incident report because it's not a zipped bugreport\n"); - return; - } const std::string path = ds.bugreport_internal_dir_ + "/tmp_incident_report"; auto fd = android::base::unique_fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW, @@ -1064,10 +1036,6 @@ static void MaybeAddSystemTraceToZip() { // This function copies into the .zip the system trace that was snapshotted // by the early call to MaybeSnapshotSystemTrace(), if any background // tracing was happening. - if (!ds.IsZipping()) { - MYLOGD("Not dumping system trace because it's not a zipped bugreport\n"); - return; - } if (!ds.has_system_trace_) { // No background trace was happening at the time dumpstate was invoked. return; @@ -1079,10 +1047,6 @@ static void MaybeAddSystemTraceToZip() { } static void DumpVisibleWindowViews() { - if (!ds.IsZipping()) { - MYLOGD("Not dumping visible views because it's not a zipped bugreport\n"); - return; - } DurationReporter duration_reporter("VISIBLE WINDOW VIEWS"); const std::string path = ds.bugreport_internal_dir_ + "/tmp_visible_window_views"; auto fd = android::base::unique_fd(TEMP_FAILURE_RETRY(open(path.c_str(), @@ -1123,7 +1087,7 @@ static void DumpDynamicPartitionInfo() { RunCommand("DEVICE-MAPPER", {"gsid", "dump-device-mapper"}); } -static void AddAnrTraceDir(const bool add_to_zip, const std::string& anr_traces_dir) { +static void AddAnrTraceDir(const std::string& anr_traces_dir) { MYLOGD("AddAnrTraceDir(): dump_traces_file=%s, anr_traces_dir=%s\n", dump_traces_path, anr_traces_dir.c_str()); @@ -1131,13 +1095,9 @@ static void AddAnrTraceDir(const bool add_to_zip, const std::string& anr_traces_ // (created with mkostemp or similar) that contains dumps taken earlier // on in the process. if (dump_traces_path != nullptr) { - if (add_to_zip) { - ds.AddZipEntry(ZIP_ROOT_DIR + anr_traces_dir + "/traces-just-now.txt", dump_traces_path); - } else { - MYLOGD("Dumping current ANR traces (%s) to the main bugreport entry\n", - dump_traces_path); - ds.DumpFile("VM TRACES JUST NOW", dump_traces_path); - } + MYLOGD("Dumping current ANR traces (%s) to the main bugreport entry\n", + dump_traces_path); + ds.DumpFile("VM TRACES JUST NOW", dump_traces_path); const int ret = unlink(dump_traces_path); if (ret == -1) { @@ -1148,14 +1108,12 @@ static void AddAnrTraceDir(const bool add_to_zip, const std::string& anr_traces_ // Add a specific message for the first ANR Dump. if (ds.anr_data_.size() > 0) { + // The "last" ANR will always be present in the body of the main entry. AddDumps(ds.anr_data_.begin(), ds.anr_data_.begin() + 1, - "VM TRACES AT LAST ANR", add_to_zip); + "VM TRACES AT LAST ANR", false /* add_to_zip */); - // The "last" ANR will always be included as separate entry in the zip file. In addition, - // it will be present in the body of the main entry if |add_to_zip| == false. - // // Historical ANRs are always included as separate entries in the bugreport zip file. - AddDumps(ds.anr_data_.begin() + ((add_to_zip) ? 1 : 0), ds.anr_data_.end(), + AddDumps(ds.anr_data_.begin(), ds.anr_data_.end(), "HISTORICAL ANR", true /* add_to_zip */); } else { printf("*** NO ANRs to dump in %s\n\n", ANR_DIR.c_str()); @@ -1163,11 +1121,9 @@ static void AddAnrTraceDir(const bool add_to_zip, const std::string& anr_traces_ } static void AddAnrTraceFiles() { - const bool add_to_zip = ds.IsZipping() && ds.version_ == VERSION_SPLIT_ANR; - std::string anr_traces_dir = "/data/anr"; - AddAnrTraceDir(add_to_zip, anr_traces_dir); + AddAnrTraceDir(anr_traces_dir); RunCommand("ANR FILES", {"ls", "-lt", ANR_DIR}); @@ -1303,10 +1259,6 @@ static Dumpstate::RunStatus RunDumpsysTextNormalPriority(const std::string& titl static Dumpstate::RunStatus RunDumpsysProto(const std::string& title, int priority, std::chrono::milliseconds timeout, std::chrono::milliseconds service_timeout) { - if (!ds.IsZipping()) { - MYLOGD("Not dumping %s because it's not a zipped bugreport\n", title.c_str()); - return Dumpstate::RunStatus::OK; - } sp<android::IServiceManager> sm = defaultServiceManager(); Dumpsys dumpsys(sm.get()); Vector<String16> args; @@ -1386,12 +1338,6 @@ static Dumpstate::RunStatus RunDumpsysNormal() { * if it's not running in the parallel task. */ static void DumpHals(int out_fd = STDOUT_FILENO) { - if (!ds.IsZipping()) { - RunCommand("HARDWARE HALS", {"lshal", "--all", "--types=all", "--debug"}, - CommandOptions::WithTimeout(60).AsRootIfAvailable().Build(), - false, out_fd); - return; - } RunCommand("HARDWARE HALS", {"lshal", "--all", "--types=all"}, CommandOptions::WithTimeout(10).AsRootIfAvailable().Build(), false, out_fd); @@ -1846,8 +1792,8 @@ Dumpstate::RunStatus Dumpstate::DumpstateDefaultAfterCritical() { /* Run some operations that require root. */ if (!PropertiesHelper::IsDryRun()) { - ds.tombstone_data_ = GetDumpFds(TOMBSTONE_DIR, TOMBSTONE_FILE_PREFIX, !ds.IsZipping()); - ds.anr_data_ = GetDumpFds(ANR_DIR, ANR_FILE_PREFIX, !ds.IsZipping()); + ds.tombstone_data_ = GetDumpFds(TOMBSTONE_DIR, TOMBSTONE_FILE_PREFIX); + ds.anr_data_ = GetDumpFds(ANR_DIR, ANR_FILE_PREFIX); } ds.AddDir(RECOVERY_DIR, true); @@ -2394,11 +2340,6 @@ void Dumpstate::DumpstateBoard(int out_fd) { dprintf(out_fd, "== Board\n"); dprintf(out_fd, "========================================================\n"); - if (!IsZipping()) { - MYLOGD("Not dumping board info because it's not a zipped bugreport\n"); - return; - } - /* * mount debugfs for non-user builds with ro.product.debugfs_restrictions.enabled * set to true and unmount it after invoking dumpstateBoard_* methods. @@ -2957,10 +2898,9 @@ Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid, version_ = VERSION_CURRENT; } - if (version_ != VERSION_CURRENT && version_ != VERSION_SPLIT_ANR) { - MYLOGE("invalid version requested ('%s'); suppported values are: ('%s', '%s', '%s')\n", - version_.c_str(), VERSION_DEFAULT.c_str(), VERSION_CURRENT.c_str(), - VERSION_SPLIT_ANR.c_str()); + if (version_ != VERSION_CURRENT) { + MYLOGE("invalid version requested ('%s'); supported values are: ('%s', '%s')\n", + version_.c_str(), VERSION_DEFAULT.c_str(), VERSION_CURRENT.c_str()); return RunStatus::INVALID_INPUT; } @@ -3567,10 +3507,6 @@ void Progress::Dump(int fd, const std::string& prefix) const { dprintf(fd, "%saverage_max: %d\n", pr, average_max_); } -bool Dumpstate::IsZipping() const { - return zip_writer_ != nullptr; -} - std::string Dumpstate::GetPath(const std::string& suffix) const { return GetPath(bugreport_internal_dir_, suffix); } @@ -4216,10 +4152,6 @@ void dump_frozen_cgroupfs(const char *dir, int level, } void dump_frozen_cgroupfs() { - if (!ds.IsZipping()) { - MYLOGD("Not adding cgroupfs because it's not a zipped bugreport\n"); - return; - } MYLOGD("Adding frozen processes from %s\n", CGROUPFS_DIR); DurationReporter duration_reporter("FROZEN CGROUPFS"); if (PropertiesHelper::IsDryRun()) return; diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h index 852b9a8e24..4a99cd8c5a 100644 --- a/cmds/dumpstate/dumpstate.h +++ b/cmds/dumpstate/dumpstate.h @@ -157,12 +157,6 @@ class Progress { static std::string VERSION_CURRENT = "2.0"; /* - * Temporary version that adds a anr-traces.txt entry. Once tools support it, the current version - * will be bumped to 3.0. - */ -static std::string VERSION_SPLIT_ANR = "3.0-dev-split-anr"; - -/* * "Alias" for the current version. */ static std::string VERSION_DEFAULT = "default"; @@ -214,9 +208,6 @@ class Dumpstate { static Dumpstate& GetInstance(); - /* Checkes whether dumpstate is generating a zipped bugreport. */ - bool IsZipping() const; - /* Initialize dumpstate fields before starting bugreport generation */ void Initialize(); diff --git a/data/etc/Android.bp b/data/etc/Android.bp index 31dee235e8..5003151b51 100644 --- a/data/etc/Android.bp +++ b/data/etc/Android.bp @@ -119,6 +119,12 @@ prebuilt_etc { } 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.prebuilt.xml", src: "android.hardware.sensor.gyroscope.xml", defaults: ["frameworks_native_data_etc_defaults"], diff --git a/data/etc/android.hardware.sensor.accelerometer_limited_axes.xml b/data/etc/android.hardware.sensor.accelerometer_limited_axes.xml new file mode 100644 index 0000000000..6a43d5dc5f --- /dev/null +++ b/data/etc/android.hardware.sensor.accelerometer_limited_axes.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 with a limited axes accelerometer sensor. --> +<permissions> + <feature name="android.hardware.sensor.accelerometer_limited_axes" /> +</permissions> diff --git a/data/etc/android.hardware.sensor.accelerometer_limited_axes_uncalibrated.xml b/data/etc/android.hardware.sensor.accelerometer_limited_axes_uncalibrated.xml new file mode 100644 index 0000000000..4c6755c45a --- /dev/null +++ b/data/etc/android.hardware.sensor.accelerometer_limited_axes_uncalibrated.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 with an uncalibrated limited axes accelerometer sensor. --> +<permissions> + <feature name="android.hardware.sensor.accelerometer_limited_axes_uncalibrated" /> +</permissions> diff --git a/data/etc/android.hardware.sensor.dynamic.head_tracker.xml b/data/etc/android.hardware.sensor.dynamic.head_tracker.xml new file mode 100644 index 0000000000..ece58c9a72 --- /dev/null +++ b/data/etc/android.hardware.sensor.dynamic.head_tracker.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 with a head tracker sensor. --> +<permissions> + <feature name="android.hardware.sensor.dynamic.head_tracker" /> +</permissions>
\ No newline at end of file diff --git a/data/etc/android.hardware.sensor.gyroscope_limited_axes.xml b/data/etc/android.hardware.sensor.gyroscope_limited_axes.xml new file mode 100644 index 0000000000..45c6547fe1 --- /dev/null +++ b/data/etc/android.hardware.sensor.gyroscope_limited_axes.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 with a limited axes gyroscope. --> +<permissions> + <feature name="android.hardware.sensor.gyroscope_limited_axes" /> +</permissions> diff --git a/data/etc/android.hardware.sensor.gyroscope_limited_axes_uncalibrated.xml b/data/etc/android.hardware.sensor.gyroscope_limited_axes_uncalibrated.xml new file mode 100644 index 0000000000..2ca8364677 --- /dev/null +++ b/data/etc/android.hardware.sensor.gyroscope_limited_axes_uncalibrated.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 with an uncalibrated limited axes gyroscope. --> +<permissions> + <feature name="android.hardware.sensor.gyroscope_limited_axes_uncalibrated" /> +</permissions> diff --git a/data/etc/android.hardware.sensor.heading.xml b/data/etc/android.hardware.sensor.heading.xml new file mode 100644 index 0000000000..8b81823b45 --- /dev/null +++ b/data/etc/android.hardware.sensor.heading.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 with a heading sensor. --> +<permissions> + <feature name="android.hardware.sensor.heading" /> +</permissions> diff --git a/data/etc/android.hardware.telephony.calling.xml b/data/etc/android.hardware.telephony.calling.xml index 3e92a6601f..ab245fc238 100644 --- a/data/etc/android.hardware.telephony.calling.xml +++ b/data/etc/android.hardware.telephony.calling.xml @@ -18,7 +18,7 @@ <permissions> <feature name="android.hardware.telephony" /> <feature name="android.software.telecom" /> - <feature name="android.hardware.telephony.radio" /> + <feature name="android.hardware.telephony.radio.access" /> <feature name="android.hardware.telephony.subscription" /> <feature name="android.hardware.telephony.calling" /> </permissions> diff --git a/data/etc/android.hardware.telephony.cdma.xml b/data/etc/android.hardware.telephony.cdma.xml index c81cf06079..0a8cfc4901 100644 --- a/data/etc/android.hardware.telephony.cdma.xml +++ b/data/etc/android.hardware.telephony.cdma.xml @@ -18,7 +18,7 @@ <permissions> <feature name="android.hardware.telephony" /> <feature name="android.software.telecom" /> - <feature name="android.hardware.telephony.radio" /> + <feature name="android.hardware.telephony.radio.access" /> <feature name="android.hardware.telephony.subscription" /> <feature name="android.hardware.telephony.cdma" /> <feature name="android.hardware.telephony.calling" /> diff --git a/data/etc/android.hardware.telephony.data.xml b/data/etc/android.hardware.telephony.data.xml index 2716152650..a9bb36e25e 100644 --- a/data/etc/android.hardware.telephony.data.xml +++ b/data/etc/android.hardware.telephony.data.xml @@ -17,7 +17,7 @@ <!-- This is the standard set of features for devices to support Telephony Data API. --> <permissions> <feature name="android.hardware.telephony" /> - <feature name="android.hardware.telephony.radio" /> + <feature name="android.hardware.telephony.radio.access" /> <feature name="android.hardware.telephony.subscription" /> <feature name="android.hardware.telephony.data" /> </permissions> diff --git a/data/etc/android.hardware.telephony.gsm.xml b/data/etc/android.hardware.telephony.gsm.xml index e368a06bfd..e3952bf8c7 100644 --- a/data/etc/android.hardware.telephony.gsm.xml +++ b/data/etc/android.hardware.telephony.gsm.xml @@ -18,7 +18,7 @@ <permissions> <feature name="android.hardware.telephony" /> <feature name="android.software.telecom" /> - <feature name="android.hardware.telephony.radio" /> + <feature name="android.hardware.telephony.radio.access" /> <feature name="android.hardware.telephony.subscription" /> <feature name="android.hardware.telephony.gsm" /> <feature name="android.hardware.telephony.calling" /> diff --git a/data/etc/android.hardware.telephony.radio.xml b/data/etc/android.hardware.telephony.radio.access.xml index 4377705f2f..c98267ce8c 100644 --- a/data/etc/android.hardware.telephony.radio.xml +++ b/data/etc/android.hardware.telephony.radio.access.xml @@ -17,5 +17,5 @@ <!-- This is the standard set of features for devices to support Telephony Radio Access API. --> <permissions> <feature name="android.hardware.telephony" /> - <feature name="android.hardware.telephony.radio" /> + <feature name="android.hardware.telephony.radio.access" /> </permissions> diff --git a/include/android/sensor.h b/include/android/sensor.h index c5d50d25be..c714b05dd7 100644 --- a/include/android/sensor.h +++ b/include/android/sensor.h @@ -263,6 +263,52 @@ enum { * Measures the orientation and rotational velocity of a user's head. */ ASENSOR_TYPE_HEAD_TRACKER = 37, + /** + * {@link ASENSOR_TYPE_ACCELEROMETER_LIMITED_AXES} + * reporting-mode: continuous + * + * The first three values are in SI units (m/s^2) and measure the acceleration of the device + * minus the force of gravity. The last three values indicate which acceleration axes are + * supported. A value of 1.0 means supported and a value of 0 means not supported. + */ + ASENSOR_TYPE_ACCELEROMETER_LIMITED_AXES = 38, + /** + * {@link ASENSOR_TYPE_GYROSCOPE_LIMITED_AXES} + * reporting-mode: continuous + * + * The first three values are in radians/second and measure the rate of rotation around the X, + * Y and Z axis. The last three values indicate which rotation axes are supported. A value of + * 1.0 means supported and a value of 0 means not supported. + */ + ASENSOR_TYPE_GYROSCOPE_LIMITED_AXES = 39, + /** + * {@link ASENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED} + * reporting-mode: continuous + * + * The first three values are in SI units (m/s^2) and measure the acceleration of the device + * minus the force of gravity. The middle three values represent the estimated bias for each + * axis. The last three values indicate which acceleration axes are supported. A value of 1.0 + * means supported and a value of 0 means not supported. + */ + ASENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED = 40, + /** + * {@link ASENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED} + * reporting-mode: continuous + * + * The first three values are in radians/second and measure the rate of rotation around the X, + * Y and Z axis. The middle three values represent the estimated drift around each axis in + * rad/s. The last three values indicate which rotation axes are supported. A value of 1.0 means + * supported and a value of 0 means not supported. + */ + ASENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED = 41, + /** + * {@link ASENSOR_TYPE_HEADING} + * reporting-mode: continuous + * + * A heading sensor measures the direction in which the device is pointing + * relative to true north in degrees. + */ + ASENSOR_TYPE_HEADING = 42, }; /** @@ -479,6 +525,69 @@ typedef struct AHeadTrackerEvent { int32_t discontinuity_count; } AHeadTrackerEvent; +typedef struct ALimitedAxesImuEvent { + union { + float calib[3]; + struct { + float x; + float y; + float z; + }; + }; + union { + float supported[3]; + struct { + float x_supported; + float y_supported; + float z_supported; + }; + }; +} ALimitedAxesImuEvent; + +typedef struct ALimitedAxesImuUncalibratedEvent { + union { + float uncalib[3]; + struct { + float x_uncalib; + float y_uncalib; + float z_uncalib; + }; + }; + union { + float bias[3]; + struct { + float x_bias; + float y_bias; + float z_bias; + }; + }; + union { + float supported[3]; + struct { + float x_supported; + float y_supported; + float z_supported; + }; + }; +} ALimitedAxesImuUncalibratedEvent; + +typedef struct AHeadingEvent { + /** + * The direction in which the device is pointing relative to true north in + * degrees. The value must be between 0.0 (inclusive) and 360.0 (exclusive), + * with 0 indicating north, 90 east, 180 south, and 270 west. + */ + float heading; + /** + * Accuracy is defined at 68% confidence. In the case where the underlying + * distribution is assumed Gaussian normal, this would be considered one + * standard deviation. For example, if the heading returns 60 degrees, and + * accuracy returns 10 degrees, then there is a 68 percent probability of + * the true heading being between 50 degrees and 70 degrees. + */ + float accuracy; +} AHeadingEvent; + /** * Information that describes a sensor event, refer to * <a href="/reference/android/hardware/SensorEvent">SensorEvent</a> for additional @@ -516,6 +625,9 @@ typedef struct ASensorEvent { ADynamicSensorEvent dynamic_sensor_meta; AAdditionalInfoEvent additional_info; AHeadTrackerEvent head_tracker; + ALimitedAxesImuEvent limited_axes_imu; + ALimitedAxesImuUncalibratedEvent limited_axes_imu_uncalibrated; + AHeadingEvent heading; }; union { uint64_t data[8]; diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp index ec9d5544f9..0970ca5aa5 100644 --- a/libs/binder/Binder.cpp +++ b/libs/binder/Binder.cpp @@ -54,6 +54,8 @@ constexpr const bool kEnableRpcDevServers = true; constexpr const bool kEnableRpcDevServers = false; #endif +// Log any reply transactions for which the data exceeds this size +#define LOG_REPLIES_OVER_SIZE (300 * 1024) // --------------------------------------------------------------------------- IBinder::IBinder() @@ -296,6 +298,10 @@ status_t BBinder::transact( // In case this is being transacted on in the same process. if (reply != nullptr) { reply->setDataPosition(0); + if (reply->dataSize() > LOG_REPLIES_OVER_SIZE) { + ALOGW("Large reply transaction of %zu bytes, interface descriptor %s, code %d", + reply->dataSize(), String8(getInterfaceDescriptor()).c_str(), code); + } } return err; diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp index 06542f064d..056ef0ab74 100644 --- a/libs/binder/BpBinder.cpp +++ b/libs/binder/BpBinder.cpp @@ -48,6 +48,9 @@ uint32_t BpBinder::sBinderProxyCountHighWatermark = 2500; // Another arbitrary value a binder count needs to drop below before another callback will be called uint32_t BpBinder::sBinderProxyCountLowWatermark = 2000; +// Log any transactions for which the data exceeds this size +#define LOG_TRANSACTIONS_OVER_SIZE (300 * 1024) + enum { LIMIT_REACHED_MASK = 0x80000000, // A flag denoting that the limit has been reached COUNTING_VALUE_MASK = 0x7FFFFFFF, // A mask of the remaining bits for the count value @@ -302,6 +305,14 @@ status_t BpBinder::transact( } else { status = IPCThreadState::self()->transact(binderHandle(), code, data, reply, flags); } + if (data.dataSize() > LOG_TRANSACTIONS_OVER_SIZE) { + Mutex::Autolock _l(mLock); + ALOGW("Large outgoing transaction of %zu bytes, interface descriptor %s, code %d", + data.dataSize(), + mDescriptorCache.size() ? String8(mDescriptorCache).c_str() + : "<uncached descriptor>", + code); + } if (status == DEAD_OBJECT) mAlive = 0; diff --git a/libs/binder/Status.cpp b/libs/binder/Status.cpp index a44c578230..83b97d04c6 100644 --- a/libs/binder/Status.cpp +++ b/libs/binder/Status.cpp @@ -211,6 +211,12 @@ status_t Status::writeToParcel(Parcel* parcel) const { return status; } +status_t Status::writeOverParcel(Parcel* parcel) const { + parcel->setDataSize(0); + parcel->setDataPosition(0); + return writeToParcel(parcel); +} + void Status::setException(int32_t ex, const String8& message) { mException = ex; mErrorCode = ex == EX_TRANSACTION_FAILED ? FAILED_TRANSACTION : NO_ERROR; diff --git a/libs/binder/include/binder/Status.h b/libs/binder/include/binder/Status.h index aaafa36d40..af34695875 100644 --- a/libs/binder/include/binder/Status.h +++ b/libs/binder/include/binder/Status.h @@ -117,6 +117,10 @@ public: status_t readFromParcel(const Parcel& parcel); status_t writeToParcel(Parcel* parcel) const; + // Convenience API to replace a Parcel with a status value, w/o requiring + // calling multiple APIs (makes generated code smaller). + status_t writeOverParcel(Parcel* parcel) const; + // Set one of the pre-defined exception types defined above. void setException(int32_t ex, const String8& message); // Set a service specific exception with error code. diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp index 77493b3882..79c8c8f88b 100644 --- a/libs/binder/ndk/Android.bp +++ b/libs/binder/ndk/Android.bp @@ -32,16 +32,6 @@ license { ], } -// TODO(b/211908498): remove this -cc_defaults { - name: "libbinder_ndk_host_user", - target: { - darwin: { - enabled: false, - }, - }, -} - cc_library { name: "libbinder_ndk", diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp index 86da5887a8..ff55d6ebdc 100644 --- a/libs/binder/tests/Android.bp +++ b/libs/binder/tests/Android.bp @@ -37,7 +37,11 @@ cc_test { srcs: ["binderDriverInterfaceTest.cpp"], header_libs: ["libbinder_headers"], compile_multilib: "32", - multilib: { lib32: { suffix: "" } }, + multilib: { + lib32: { + suffix: "", + }, + }, cflags: ["-DBINDER_IPC_32BIT=1"], test_suites: ["vts"], } @@ -52,7 +56,10 @@ cc_test { }, header_libs: ["libbinder_headers"], srcs: ["binderDriverInterfaceTest.cpp"], - test_suites: ["device-tests", "vts"], + test_suites: [ + "device-tests", + "vts", + ], } cc_test { @@ -69,7 +76,11 @@ cc_test { "libgmock", ], compile_multilib: "32", - multilib: { lib32: { suffix: "" } }, + multilib: { + lib32: { + suffix: "", + }, + }, cflags: ["-DBINDER_IPC_32BIT=1"], test_suites: ["vts"], require_root: true, @@ -84,7 +95,11 @@ cc_test { enabled: false, }, }, - srcs: ["binderParcelUnitTest.cpp", "binderBinderUnitTest.cpp"], + srcs: [ + "binderParcelUnitTest.cpp", + "binderBinderUnitTest.cpp", + "binderStatusUnitTest.cpp", + ], shared_libs: [ "libbinder", "libcutils", @@ -112,7 +127,10 @@ cc_test { static_libs: [ "libgmock", ], - test_suites: ["device-tests", "vts"], + test_suites: [ + "device-tests", + "vts", + ], require_root: true, } @@ -179,7 +197,6 @@ cc_test { }, defaults: [ "binder_test_defaults", - "libbinder_ndk_host_user", "libbinder_tls_shared_deps", ], @@ -232,7 +249,10 @@ cc_test { "libbinder_tls_test_utils", "libbinder_tls_static", ], - test_suites: ["general-tests", "device-tests"], + test_suites: [ + "general-tests", + "device-tests", + ], } cc_benchmark { @@ -348,7 +368,10 @@ cc_test { "liblog", "libutils", ], - test_suites: ["device-tests", "vts"], + test_suites: [ + "device-tests", + "vts", + ], require_root: true, } @@ -402,7 +425,10 @@ cc_test { "binderStabilityTestIface-ndk", ], - test_suites: ["device-tests", "vts"], + test_suites: [ + "device-tests", + "vts", + ], require_root: true, } diff --git a/libs/binder/tests/binderStatusUnitTest.cpp b/libs/binder/tests/binderStatusUnitTest.cpp new file mode 100644 index 0000000000..a32ec5cc31 --- /dev/null +++ b/libs/binder/tests/binderStatusUnitTest.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <binder/Parcel.h> +#include <binder/Status.h> +#include <gtest/gtest.h> + +using android::Parcel; +using android::binder::Status; + +TEST(Status, WriteOverParcel) { + Status status = Status::fromExceptionCode(Status::EX_NULL_POINTER); + + Parcel indirect; + indirect.writeInt32(64); + status.writeOverParcel(&indirect); + + Parcel direct; + status.writeToParcel(&direct); + + EXPECT_EQ(0, indirect.compareData(direct)); +} diff --git a/libs/cputimeinstate/Android.bp b/libs/cputimeinstate/Android.bp index 4f63194f03..79cc15f571 100644 --- a/libs/cputimeinstate/Android.bp +++ b/libs/cputimeinstate/Android.bp @@ -13,12 +13,13 @@ cc_library { shared_libs: [ "libbase", "libbpf_bcc", - "libbpf_android", "libbpf_minimal", "liblog", - "libnetdutils" ], - header_libs: ["bpf_prog_headers"], + header_libs: [ + "bpf_prog_headers", + "bpf_headers", + ], cflags: [ "-Werror", "-Wall", @@ -33,12 +34,13 @@ cc_test { shared_libs: [ "libbase", "libbpf_bcc", - "libbpf_android", "libbpf_minimal", "libtimeinstate", - "libnetdutils", ], - header_libs: ["bpf_prog_headers"], + header_libs: [ + "bpf_prog_headers", + "bpf_headers", + ], cflags: [ "-Werror", "-Wall", diff --git a/libs/gralloc/types/Android.bp b/libs/gralloc/types/Android.bp index 6afd1729de..bd21fbaf0e 100644 --- a/libs/gralloc/types/Android.bp +++ b/libs/gralloc/types/Android.bp @@ -23,7 +23,6 @@ package { cc_library { name: "libgralloctypes", - defaults: ["libbinder_ndk_host_user"], cflags: [ "-Wall", "-Werror", diff --git a/libs/gralloc/types/fuzzer/Android.bp b/libs/gralloc/types/fuzzer/Android.bp index 6689771a24..3c3b6af670 100644 --- a/libs/gralloc/types/fuzzer/Android.bp +++ b/libs/gralloc/types/fuzzer/Android.bp @@ -9,12 +9,11 @@ package { cc_fuzz { name: "libgralloctypes_fuzzer", - defaults: ["libbinder_ndk_host_user"], host_supported: true, target: { darwin: { enabled: false, - } + }, }, fuzz_config: { diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp index ec3587b79a..e17b2c8af7 100644 --- a/libs/gui/Android.bp +++ b/libs/gui/Android.bp @@ -198,6 +198,7 @@ cc_library_shared { "SurfaceComposerClient.cpp", "SyncFeatures.cpp", "TransactionTracing.cpp", + "VsyncEventData.cpp", "view/Surface.cpp", "WindowInfosListenerReporter.cpp", "bufferqueue/1.0/B2HProducerListener.cpp", diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index dd966837f4..aeb237deb4 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -28,6 +28,7 @@ #include <gui/GLConsumer.h> #include <gui/IProducerListener.h> #include <gui/Surface.h> +#include <gui/TraceUtils.h> #include <utils/Singleton.h> #include <utils/Trace.h> @@ -57,6 +58,10 @@ namespace android { #define BQA_LOGE(x, ...) \ ALOGE("[%s](f:%u,a:%u) " x, mName.c_str(), mNumFrameAvailable, mNumAcquired, ##__VA_ARGS__) +#define BBQ_TRACE(x, ...) \ + ATRACE_FORMAT("%s - %s(f:%u,a:%u)" x, __FUNCTION__, mName.c_str(), mNumFrameAvailable, \ + mNumAcquired, ##__VA_ARGS__) + void BLASTBufferItemConsumer::onDisconnect() { Mutex::Autolock lock(mMutex); mPreviouslyConnected = mCurrentlyConnected; @@ -254,7 +259,7 @@ void BLASTBufferQueue::transactionCommittedCallback(nsecs_t /*latchTime*/, const std::vector<SurfaceControlStats>& stats) { { std::unique_lock _lock{mMutex}; - ATRACE_CALL(); + BBQ_TRACE(); BQA_LOGV("transactionCommittedCallback"); if (!mSurfaceControlsWithPendingCallback.empty()) { sp<SurfaceControl> pendingSC = mSurfaceControlsWithPendingCallback.front(); @@ -304,7 +309,7 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence const std::vector<SurfaceControlStats>& stats) { { std::unique_lock _lock{mMutex}; - ATRACE_CALL(); + BBQ_TRACE(); BQA_LOGV("transactionCallback"); if (!mSurfaceControlsWithPendingCallback.empty()) { @@ -367,7 +372,7 @@ void BLASTBufferQueue::flushShadowQueue() { void BLASTBufferQueue::releaseBufferCallback( const ReleaseCallbackId& id, const sp<Fence>& releaseFence, std::optional<uint32_t> currentMaxAcquiredBufferCount) { - ATRACE_CALL(); + BBQ_TRACE(); std::unique_lock _lock{mMutex}; BQA_LOGV("releaseBufferCallback %s", id.to_string().c_str()); @@ -415,6 +420,7 @@ void BLASTBufferQueue::releaseBuffer(const ReleaseCallbackId& callbackId, return; } mNumAcquired--; + BBQ_TRACE("frame=%" PRIu64, callbackId.framenumber); BQA_LOGV("released %s", callbackId.to_string().c_str()); mBufferItemConsumer->releaseBuffer(it->second, releaseFence); mSubmitted.erase(it); @@ -422,7 +428,6 @@ void BLASTBufferQueue::releaseBuffer(const ReleaseCallbackId& callbackId, void BLASTBufferQueue::acquireNextBufferLocked( const std::optional<SurfaceComposerClient::Transaction*> transaction) { - ATRACE_CALL(); // If the next transaction is set, we want to guarantee the our acquire will not fail, so don't // include the extra buffer when checking if we can acquire the next buffer. const bool includeExtraAcquire = !transaction; @@ -456,8 +461,10 @@ void BLASTBufferQueue::acquireNextBufferLocked( BQA_LOGE("Failed to acquire a buffer, err=%s", statusToString(status).c_str()); return; } + auto buffer = bufferItem.mGraphicBuffer; mNumFrameAvailable--; + BBQ_TRACE("frame=%" PRIu64, bufferItem.mFrameNumber); if (buffer == nullptr) { mBufferItemConsumer->releaseBuffer(bufferItem, Fence::NO_FENCE); @@ -600,7 +607,7 @@ void BLASTBufferQueue::flushAndWaitForFreeBuffer(std::unique_lock<std::mutex>& l } void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) { - ATRACE_CALL(); + BBQ_TRACE(); std::unique_lock _lock{mMutex}; const bool syncTransactionSet = mSyncTransaction != nullptr; @@ -674,6 +681,7 @@ void BLASTBufferQueue::onFrameCancelled(const uint64_t bufferId) { void BLASTBufferQueue::setSyncTransaction(SurfaceComposerClient::Transaction* t, bool acquireSingleBuffer) { + BBQ_TRACE(); std::lock_guard _lock{mMutex}; mSyncTransaction = t; mAcquireSingleBuffer = mSyncTransaction ? acquireSingleBuffer : true; diff --git a/libs/gui/DisplayEventDispatcher.cpp b/libs/gui/DisplayEventDispatcher.cpp index ee8008270e..26db59bcff 100644 --- a/libs/gui/DisplayEventDispatcher.cpp +++ b/libs/gui/DisplayEventDispatcher.cpp @@ -148,14 +148,13 @@ int DisplayEventDispatcher::handleEvent(int, int events, void*) { void DisplayEventDispatcher::populateFrameTimelines(const DisplayEventReceiver::Event& event, VsyncEventData* outVsyncEventData) const { - for (size_t i = 0; i < DisplayEventReceiver::kFrameTimelinesLength; i++) { + for (size_t i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) { DisplayEventReceiver::Event::VSync::FrameTimeline receiverTimeline = event.vsync.frameTimelines[i]; - outVsyncEventData->frameTimelines[i] = {.id = receiverTimeline.vsyncId, - .deadlineTimestamp = - receiverTimeline.deadlineTimestamp, - .expectedPresentTime = - receiverTimeline.expectedVSyncTimestamp}; + outVsyncEventData->frameTimelines[i] = + VsyncEventData::FrameTimeline(receiverTimeline.vsyncId, + receiverTimeline.deadlineTimestamp, + receiverTimeline.expectedVSyncTimestamp); } } diff --git a/libs/gui/LayerDebugInfo.cpp b/libs/gui/LayerDebugInfo.cpp index 0827bbe3ee..ea5fb293a6 100644 --- a/libs/gui/LayerDebugInfo.cpp +++ b/libs/gui/LayerDebugInfo.cpp @@ -58,7 +58,6 @@ status_t LayerDebugInfo::writeToParcel(Parcel* parcel) const { RETURN_ON_ERROR(parcel->writeInt32(mActiveBufferStride)); RETURN_ON_ERROR(parcel->writeInt32(mActiveBufferFormat)); RETURN_ON_ERROR(parcel->writeInt32(mNumQueuedFrames)); - RETURN_ON_ERROR(parcel->writeBool(mRefreshPending)); RETURN_ON_ERROR(parcel->writeBool(mIsOpaque)); RETURN_ON_ERROR(parcel->writeBool(mContentDirty)); RETURN_ON_ERROR(parcel->write(mStretchEffect)); @@ -103,7 +102,6 @@ status_t LayerDebugInfo::readFromParcel(const Parcel* parcel) { RETURN_ON_ERROR(parcel->readInt32(&mActiveBufferStride)); RETURN_ON_ERROR(parcel->readInt32(&mActiveBufferFormat)); RETURN_ON_ERROR(parcel->readInt32(&mNumQueuedFrames)); - RETURN_ON_ERROR(parcel->readBool(&mRefreshPending)); RETURN_ON_ERROR(parcel->readBool(&mIsOpaque)); RETURN_ON_ERROR(parcel->readBool(&mContentDirty)); RETURN_ON_ERROR(parcel->read(mStretchEffect)); @@ -146,8 +144,7 @@ std::string to_string(const LayerDebugInfo& info) { StringAppendF(&result, " activeBuffer=[%4ux%4u:%4u,%s],", info.mActiveBufferWidth, info.mActiveBufferHeight, info.mActiveBufferStride, decodePixelFormat(info.mActiveBufferFormat).c_str()); - StringAppendF(&result, " queued-frames=%d, mRefreshPending=%d", info.mNumQueuedFrames, - info.mRefreshPending); + StringAppendF(&result, " queued-frames=%d", info.mNumQueuedFrames); result.append("\n"); return result; } diff --git a/libs/gui/VsyncEventData.cpp b/libs/gui/VsyncEventData.cpp new file mode 100644 index 0000000000..aad81d0198 --- /dev/null +++ b/libs/gui/VsyncEventData.cpp @@ -0,0 +1,76 @@ +/* + * 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. + */ + +#include "gui/VsyncEventData.h" +#include <gui/DisplayEventReceiver.h> +#include <private/gui/ParcelUtils.h> +#include <utils/Log.h> +#include <utils/Looper.h> +#include <cstdint> + +namespace android::gui { + +status_t VsyncEventData::readFromParcel(const Parcel* parcel) { + if (parcel == nullptr) { + ALOGE("%s: Null parcel", __func__); + return BAD_VALUE; + } + + SAFE_PARCEL(parcel->readInt64, &id) + SAFE_PARCEL(parcel->readInt64, &deadlineTimestamp); + SAFE_PARCEL(parcel->readInt64, &frameInterval); + + uint64_t uintPreferredFrameTimelineIndex; + SAFE_PARCEL(parcel->readUint64, &uintPreferredFrameTimelineIndex); + preferredFrameTimelineIndex = static_cast<size_t>(uintPreferredFrameTimelineIndex); + + std::vector<FrameTimeline> timelines; + SAFE_PARCEL(parcel->readParcelableVector, &timelines); + std::copy_n(timelines.begin(), timelines.size(), frameTimelines.begin()); + + return OK; +} +status_t VsyncEventData::writeToParcel(Parcel* parcel) const { + SAFE_PARCEL(parcel->writeInt64, id) + SAFE_PARCEL(parcel->writeInt64, deadlineTimestamp); + SAFE_PARCEL(parcel->writeInt64, frameInterval); + SAFE_PARCEL(parcel->writeUint64, preferredFrameTimelineIndex); + SAFE_PARCEL(parcel->writeParcelableVector, + std::vector(frameTimelines.begin(), frameTimelines.end())); + + return OK; +} +status_t VsyncEventData::FrameTimeline::readFromParcel(const Parcel* parcel) { + if (parcel == nullptr) { + ALOGE("%s: Null parcel", __func__); + return BAD_VALUE; + } + + SAFE_PARCEL(parcel->readInt64, &id) + SAFE_PARCEL(parcel->readInt64, &deadlineTimestamp); + SAFE_PARCEL(parcel->readInt64, &expectedPresentTime); + + return OK; +} +status_t VsyncEventData::FrameTimeline::writeToParcel(Parcel* parcel) const { + SAFE_PARCEL(parcel->writeInt64, id); + SAFE_PARCEL(parcel->writeInt64, deadlineTimestamp); + SAFE_PARCEL(parcel->writeInt64, expectedPresentTime); + + return OK; +} + +}; // namespace android::gui diff --git a/libs/gui/WindowInfo.cpp b/libs/gui/WindowInfo.cpp index 1c7b270527..a8667867b2 100644 --- a/libs/gui/WindowInfo.cpp +++ b/libs/gui/WindowInfo.cpp @@ -69,7 +69,7 @@ bool WindowInfo::operator==(const WindowInfo& info) const { info.hasWallpaper == hasWallpaper && info.paused == paused && info.ownerPid == ownerPid && info.ownerUid == ownerUid && info.packageName == packageName && info.inputFeatures == inputFeatures && - info.displayId == displayId && info.portalToDisplayId == portalToDisplayId && + info.displayId == displayId && info.replaceTouchableRegionWithCrop == replaceTouchableRegionWithCrop && info.applicationInfo == applicationInfo; } @@ -116,7 +116,6 @@ status_t WindowInfo::writeToParcel(android::Parcel* parcel) const { parcel->writeUtf8AsUtf16(packageName) ?: parcel->writeInt32(inputFeatures.get()) ?: parcel->writeInt32(displayId) ?: - parcel->writeInt32(portalToDisplayId) ?: applicationInfo.writeToParcel(parcel) ?: parcel->write(touchableRegion) ?: parcel->writeBool(replaceTouchableRegionWithCrop) ?: @@ -180,7 +179,6 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) { inputFeatures = Flags<Feature>(parcel->readInt32()); // clang-format off status = parcel->readInt32(&displayId) ?: - parcel->readInt32(&portalToDisplayId) ?: applicationInfo.readFromParcel(parcel) ?: parcel->read(touchableRegion) ?: parcel->readBool(&replaceTouchableRegionWithCrop); diff --git a/libs/gui/WindowInfosListenerReporter.cpp b/libs/gui/WindowInfosListenerReporter.cpp index c32b9ab398..4112f74068 100644 --- a/libs/gui/WindowInfosListenerReporter.cpp +++ b/libs/gui/WindowInfosListenerReporter.cpp @@ -68,8 +68,7 @@ status_t WindowInfosListenerReporter::removeWindowInfosListener( binder::Status WindowInfosListenerReporter::onWindowInfosChanged( const std::vector<WindowInfo>& windowInfos, const std::vector<DisplayInfo>& displayInfos, const sp<IWindowInfosReportedListener>& windowInfosReportedListener) { - std::unordered_set<sp<WindowInfosListener>, ISurfaceComposer::SpHash<WindowInfosListener>> - windowInfosListeners; + std::unordered_set<sp<WindowInfosListener>, SpHash<WindowInfosListener>> windowInfosListeners; { std::scoped_lock lock(mListenersMutex); @@ -96,4 +95,4 @@ void WindowInfosListenerReporter::reconnect(const sp<ISurfaceComposer>& composer } } -} // namespace android
\ No newline at end of file +} // namespace android diff --git a/libs/gui/include/gui/DisplayEventDispatcher.h b/libs/gui/include/gui/DisplayEventDispatcher.h index 40621ddb15..71968fa59f 100644 --- a/libs/gui/include/gui/DisplayEventDispatcher.h +++ b/libs/gui/include/gui/DisplayEventDispatcher.h @@ -17,45 +17,10 @@ #include <gui/DisplayEventReceiver.h> #include <utils/Log.h> #include <utils/Looper.h> -#include <array> namespace android { using FrameRateOverride = DisplayEventReceiver::Event::FrameRateOverride; -struct VsyncEventData { - // The Vsync Id corresponsing to this vsync event. This will be used to - // populate ISurfaceComposer::setFrameTimelineVsync and - // SurfaceComposerClient::setFrameTimelineVsync - int64_t id = FrameTimelineInfo::INVALID_VSYNC_ID; - - // The deadline in CLOCK_MONOTONIC that the app needs to complete its - // frame by (both on the CPU and the GPU) - int64_t deadlineTimestamp = std::numeric_limits<int64_t>::max(); - - // The current frame interval in ns when this frame was scheduled. - int64_t frameInterval = 0; - - struct FrameTimeline { - // The Vsync Id corresponsing to this vsync event. This will be used to - // populate ISurfaceComposer::setFrameTimelineVsync and - // SurfaceComposerClient::setFrameTimelineVsync - int64_t id = FrameTimelineInfo::INVALID_VSYNC_ID; - - // The deadline in CLOCK_MONOTONIC that the app needs to complete its - // frame by (both on the CPU and the GPU) - int64_t deadlineTimestamp = std::numeric_limits<int64_t>::max(); - - // The anticipated Vsync present time. - int64_t expectedPresentTime = 0; - }; - - // Sorted possible frame timelines. - std::array<FrameTimeline, DisplayEventReceiver::kFrameTimelinesLength> frameTimelines; - - // Index into the frameTimelines that represents the platform's preferred frame timeline. - size_t preferredFrameTimelineIndex = std::numeric_limits<size_t>::max(); -}; - class DisplayEventDispatcher : public LooperCallback { public: explicit DisplayEventDispatcher( diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h index 456bbfb611..db41c32549 100644 --- a/libs/gui/include/gui/DisplayEventReceiver.h +++ b/libs/gui/include/gui/DisplayEventReceiver.h @@ -26,6 +26,7 @@ #include <binder/IInterface.h> #include <gui/ISurfaceComposer.h> +#include <gui/VsyncEventData.h> // ---------------------------------------------------------------------------- @@ -34,6 +35,7 @@ namespace android { // ---------------------------------------------------------------------------- using gui::IDisplayEventConnection; +using gui::VsyncEventData; namespace gui { class BitTube; @@ -49,8 +51,6 @@ static inline constexpr uint32_t fourcc(char c1, char c2, char c3, char c4) { // ---------------------------------------------------------------------------- class DisplayEventReceiver { public: - // Max amount of frame timelines is arbitrarily set to be reasonable. - static constexpr int64_t kFrameTimelinesLength = 7; enum { DISPLAY_EVENT_VSYNC = fourcc('v', 's', 'y', 'n'), @@ -85,7 +85,7 @@ public: nsecs_t expectedVSyncTimestamp __attribute__((aligned(8))); nsecs_t deadlineTimestamp __attribute__((aligned(8))); int64_t vsyncId; - } frameTimelines[kFrameTimelinesLength]; + } frameTimelines[VsyncEventData::kFrameTimelinesLength]; }; struct Hotplug { diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 4b5cee256a..90b2a0e05f 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -30,6 +30,7 @@ #include <ftl/Flags.h> #include <gui/FrameTimelineInfo.h> #include <gui/ITransactionCompletedListener.h> +#include <gui/SpHash.h> #include <math/vec4.h> #include <stdint.h> #include <sys/types.h> @@ -70,6 +71,7 @@ enum class FrameEvent; using gui::IDisplayEventConnection; using gui::IRegionSamplingListener; using gui::IScreenCaptureListener; +using gui::SpHash; namespace ui { @@ -118,11 +120,6 @@ public: using EventRegistrationFlags = Flags<EventRegistration>; - template <typename T> - struct SpHash { - size_t operator()(const sp<T>& k) const { return std::hash<T*>()(k.get()); } - }; - /* * Create a connection with SurfaceFlinger. */ diff --git a/libs/gui/include/gui/LayerDebugInfo.h b/libs/gui/include/gui/LayerDebugInfo.h index 8b7d32c0a5..af834d78df 100644 --- a/libs/gui/include/gui/LayerDebugInfo.h +++ b/libs/gui/include/gui/LayerDebugInfo.h @@ -64,7 +64,6 @@ public: int32_t mActiveBufferStride = 0; PixelFormat mActiveBufferFormat = PIXEL_FORMAT_NONE; int32_t mNumQueuedFrames = -1; - bool mRefreshPending = false; bool mIsOpaque = false; bool mContentDirty = false; StretchEffect mStretchEffect = {}; diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index cd6afd29a0..f7206193cd 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -31,6 +31,7 @@ #include <gui/ISurfaceComposer.h> #include <gui/LayerMetadata.h> +#include <gui/SpHash.h> #include <gui/SurfaceControl.h> #include <gui/WindowInfo.h> #include <math/vec3.h> @@ -412,7 +413,7 @@ struct DisplayCaptureArgs : CaptureArgs { struct LayerCaptureArgs : CaptureArgs { sp<IBinder> layerHandle; - std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>> excludeHandles; + std::unordered_set<sp<IBinder>, SpHash<IBinder>> excludeHandles; bool childrenOnly{false}; status_t write(Parcel& output) const override; diff --git a/libs/gui/include/gui/SpHash.h b/libs/gui/include/gui/SpHash.h new file mode 100644 index 0000000000..5162f01041 --- /dev/null +++ b/libs/gui/include/gui/SpHash.h @@ -0,0 +1,31 @@ +/* + * 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. + */ + +#pragma once + +#include <stdint.h> +#include <sys/types.h> + +#include <functional> + +namespace android::gui { + +template <typename T> +struct SpHash { + size_t operator()(const sp<T>& k) const { return std::hash<T*>()(k.get()); } +}; + +}; // namespace android::gui diff --git a/libs/gui/include/gui/VsyncEventData.h b/libs/gui/include/gui/VsyncEventData.h new file mode 100644 index 0000000000..abac61c334 --- /dev/null +++ b/libs/gui/include/gui/VsyncEventData.h @@ -0,0 +1,74 @@ +/* + * 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. + */ + +#pragma once + +#include <gui/FrameTimelineInfo.h> + +#include <array> + +namespace android::gui { +struct VsyncEventData : public Parcelable { + // Max amount of frame timelines is arbitrarily set to be reasonable. + static constexpr int64_t kFrameTimelinesLength = 7; + + // The Vsync Id corresponsing to this vsync event. This will be used to + // populate ISurfaceComposer::setFrameTimelineVsync and + // SurfaceComposerClient::setFrameTimelineVsync + // TODO(b/198191703): Remove when JNI DisplayEventReceiver uses frameTimelines array. + int64_t id = FrameTimelineInfo::INVALID_VSYNC_ID; + + // The deadline in CLOCK_MONOTONIC that the app needs to complete its + // frame by (both on the CPU and the GPU) + // TODO(b/198191703): Remove when JNI DisplayEventReceiver uses frameTimelines array. + int64_t deadlineTimestamp = std::numeric_limits<int64_t>::max(); + + // The current frame interval in ns when this frame was scheduled. + int64_t frameInterval = 0; + + struct FrameTimeline : public Parcelable { + FrameTimeline() = default; + FrameTimeline(int64_t id, int64_t deadlineTimestamp, int64_t expectedPresentTime) + : id(id), + deadlineTimestamp(deadlineTimestamp), + expectedPresentTime(expectedPresentTime) {} + + // The Vsync Id corresponsing to this vsync event. This will be used to + // populate ISurfaceComposer::setFrameTimelineVsync and + // SurfaceComposerClient::setFrameTimelineVsync + int64_t id = FrameTimelineInfo::INVALID_VSYNC_ID; + + // The deadline in CLOCK_MONOTONIC that the app needs to complete its + // frame by (both on the CPU and the GPU) + int64_t deadlineTimestamp = std::numeric_limits<int64_t>::max(); + + // The anticipated Vsync present time. + int64_t expectedPresentTime = 0; + + status_t readFromParcel(const Parcel*) override; + status_t writeToParcel(Parcel*) const override; + }; + + // Sorted possible frame timelines. + std::array<FrameTimeline, kFrameTimelinesLength> frameTimelines; + + // Index into the frameTimelines that represents the platform's preferred frame timeline. + size_t preferredFrameTimelineIndex = std::numeric_limits<size_t>::max(); + + status_t readFromParcel(const Parcel*) override; + status_t writeToParcel(Parcel*) const override; +}; +} // namespace android::gui diff --git a/libs/gui/include/gui/WindowInfo.h b/libs/gui/include/gui/WindowInfo.h index 2bfaec8d03..eb64ac9b25 100644 --- a/libs/gui/include/gui/WindowInfo.h +++ b/libs/gui/include/gui/WindowInfo.h @@ -214,7 +214,6 @@ struct WindowInfo : public Parcelable { std::string packageName; Flags<Feature> inputFeatures; int32_t displayId = ADISPLAY_ID_NONE; - int32_t portalToDisplayId = ADISPLAY_ID_NONE; InputApplicationInfo applicationInfo; bool replaceTouchableRegionWithCrop = false; wp<IBinder> touchableRegionCropHandle; diff --git a/libs/gui/include/gui/WindowInfosListenerReporter.h b/libs/gui/include/gui/WindowInfosListenerReporter.h index 157a804264..96bd0b1db0 100644 --- a/libs/gui/include/gui/WindowInfosListenerReporter.h +++ b/libs/gui/include/gui/WindowInfosListenerReporter.h @@ -20,6 +20,7 @@ #include <android/gui/IWindowInfosReportedListener.h> #include <binder/IBinder.h> #include <gui/ISurfaceComposer.h> +#include <gui/SpHash.h> #include <gui/WindowInfosListener.h> #include <unordered_set> @@ -41,8 +42,7 @@ public: private: std::mutex mListenersMutex; - std::unordered_set<sp<gui::WindowInfosListener>, - ISurfaceComposer::SpHash<gui::WindowInfosListener>> + std::unordered_set<sp<gui::WindowInfosListener>, SpHash<gui::WindowInfosListener>> mWindowInfosListeners GUARDED_BY(mListenersMutex); }; -} // namespace android
\ No newline at end of file +} // namespace android diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp index 6dd1073879..e58543a245 100644 --- a/libs/gui/tests/Android.bp +++ b/libs/gui/tests/Android.bp @@ -44,6 +44,7 @@ cc_test { "SurfaceTextureMultiContextGL_test.cpp", "Surface_test.cpp", "TextureRenderer.cpp", + "VsyncEventData_test.cpp", "WindowInfo_test.cpp", ], diff --git a/libs/gui/tests/VsyncEventData_test.cpp b/libs/gui/tests/VsyncEventData_test.cpp new file mode 100644 index 0000000000..a670d42fe3 --- /dev/null +++ b/libs/gui/tests/VsyncEventData_test.cpp @@ -0,0 +1,75 @@ +/* + * 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. + */ + +#include <gtest/gtest.h> + +#include <binder/Parcel.h> + +#include <gui/VsyncEventData.h> + +namespace android { + +using gui::VsyncEventData; +using FrameTimeline = gui::VsyncEventData::FrameTimeline; + +namespace test { + +TEST(VsyncEventData, Parcelling) { + VsyncEventData data; + data.id = 123; + data.deadlineTimestamp = 456; + data.frameInterval = 789; + data.preferredFrameTimelineIndex = 1; + FrameTimeline timeline0 = FrameTimeline(1, 2, 3); + FrameTimeline timeline1 = FrameTimeline(4, 5, 6); + data.frameTimelines[0] = timeline0; + data.frameTimelines[1] = timeline1; + + Parcel p; + data.writeToParcel(&p); + p.setDataPosition(0); + + VsyncEventData data2; + data2.readFromParcel(&p); + ASSERT_EQ(data.id, data2.id); + ASSERT_EQ(data.deadlineTimestamp, data2.deadlineTimestamp); + ASSERT_EQ(data.frameInterval, data2.frameInterval); + ASSERT_EQ(data.preferredFrameTimelineIndex, data2.preferredFrameTimelineIndex); + for (int i = 0; i < data.frameTimelines.size(); i++) { + ASSERT_EQ(data.frameTimelines[i].id, data2.frameTimelines[i].id); + ASSERT_EQ(data.frameTimelines[i].deadlineTimestamp, + data2.frameTimelines[i].deadlineTimestamp); + ASSERT_EQ(data.frameTimelines[i].expectedPresentTime, + data2.frameTimelines[i].expectedPresentTime); + } +} + +TEST(FrameTimeline, Parcelling) { + FrameTimeline timeline = FrameTimeline(1, 2, 3); + + Parcel p; + timeline.writeToParcel(&p); + p.setDataPosition(0); + + FrameTimeline timeline2; + timeline2.readFromParcel(&p); + ASSERT_EQ(timeline.id, timeline2.id); + ASSERT_EQ(timeline.deadlineTimestamp, timeline2.deadlineTimestamp); + ASSERT_EQ(timeline.expectedPresentTime, timeline2.expectedPresentTime); +} + +} // namespace test +} // namespace android diff --git a/libs/gui/tests/WindowInfo_test.cpp b/libs/gui/tests/WindowInfo_test.cpp index dcdf76fe35..ff3ba2aae0 100644 --- a/libs/gui/tests/WindowInfo_test.cpp +++ b/libs/gui/tests/WindowInfo_test.cpp @@ -70,7 +70,6 @@ TEST(WindowInfo, Parcelling) { i.packageName = "com.example.package"; i.inputFeatures = WindowInfo::Feature::DISABLE_USER_ACTIVITY; i.displayId = 34; - i.portalToDisplayId = 2; i.replaceTouchableRegionWithCrop = true; i.touchableRegionCropHandle = touchableRegionCropHandle; i.applicationInfo.name = "ApplicationFooBar"; @@ -107,7 +106,6 @@ TEST(WindowInfo, Parcelling) { ASSERT_EQ(i.packageName, i2.packageName); ASSERT_EQ(i.inputFeatures, i2.inputFeatures); ASSERT_EQ(i.displayId, i2.displayId); - ASSERT_EQ(i.portalToDisplayId, i2.portalToDisplayId); ASSERT_EQ(i.replaceTouchableRegionWithCrop, i2.replaceTouchableRegionWithCrop); ASSERT_EQ(i.touchableRegionCropHandle, i2.touchableRegionCropHandle); ASSERT_EQ(i.applicationInfo, i2.applicationInfo); diff --git a/libs/nativedisplay/AChoreographer.cpp b/libs/nativedisplay/AChoreographer.cpp index d90ee57322..b182a4a6f1 100644 --- a/libs/nativedisplay/AChoreographer.cpp +++ b/libs/nativedisplay/AChoreographer.cpp @@ -73,6 +73,7 @@ inline const char* toString(bool value) { } // namespace namespace android { +using gui::VsyncEventData; struct FrameCallback { AChoreographer_frameCallback callback; @@ -102,8 +103,7 @@ class Choreographer; struct ChoreographerFrameCallbackDataImpl { int64_t frameTimeNanos{0}; - std::array<VsyncEventData::FrameTimeline, DisplayEventReceiver::kFrameTimelinesLength> - frameTimelines; + std::array<VsyncEventData::FrameTimeline, VsyncEventData::kFrameTimelinesLength> frameTimelines; size_t preferredFrameTimelineIndex; diff --git a/libs/renderengine/skia/filters/BlurFilter.cpp b/libs/renderengine/skia/filters/BlurFilter.cpp index 6746e479d2..63cc02b7ea 100644 --- a/libs/renderengine/skia/filters/BlurFilter.cpp +++ b/libs/renderengine/skia/filters/BlurFilter.cpp @@ -38,7 +38,7 @@ static sk_sp<SkRuntimeEffect> createMixEffect() { uniform float mixFactor; half4 main(float2 xy) { - return half4(mix(originalInput.eval(xy), blurredInput.eval(xy), mixFactor)); + return half4(mix(originalInput.eval(xy), blurredInput.eval(xy), mixFactor)).rgb1; } )"); @@ -103,7 +103,7 @@ void BlurFilter::drawBlurRegion(SkCanvas* canvas, const SkRRect& effectRegion, inputMatrix); blurBuilder.uniform("mixFactor") = blurRadius / mMaxCrossFadeRadius; - paint.setShader(blurBuilder.makeShader(nullptr, true)); + paint.setShader(blurBuilder.makeShader()); } else { paint.setShader(blurShader); } diff --git a/libs/renderengine/skia/filters/LinearEffect.cpp b/libs/renderengine/skia/filters/LinearEffect.cpp index 6077c2e7da..a46329d9fc 100644 --- a/libs/renderengine/skia/filters/LinearEffect.cpp +++ b/libs/renderengine/skia/filters/LinearEffect.cpp @@ -58,7 +58,7 @@ sk_sp<SkShader> createLinearEffectShader(sk_sp<SkShader> shader, effectBuilder.uniform(uniform.name.c_str()).set(uniform.value.data(), uniform.value.size()); } - return effectBuilder.makeShader(nullptr, false); + return effectBuilder.makeShader(); } } // namespace skia diff --git a/libs/renderengine/skia/filters/StretchShaderFactory.cpp b/libs/renderengine/skia/filters/StretchShaderFactory.cpp index c262e3557c..beec3eccf5 100644 --- a/libs/renderengine/skia/filters/StretchShaderFactory.cpp +++ b/libs/renderengine/skia/filters/StretchShaderFactory.cpp @@ -238,7 +238,7 @@ sk_sp<SkShader> StretchShaderFactory::createSkShader(const sk_sp<SkShader>& inpu mBuilder->uniform("viewportWidth").set(&viewportWidth, 1); mBuilder->uniform("viewportHeight").set(&viewportHeight, 1); - return mBuilder->makeShader(nullptr, false); + return mBuilder->makeShader(); } } // namespace skia diff --git a/libs/sensor/Sensor.cpp b/libs/sensor/Sensor.cpp index da88e8541a..ec0ced8663 100644 --- a/libs/sensor/Sensor.cpp +++ b/libs/sensor/Sensor.cpp @@ -280,6 +280,26 @@ Sensor::Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersi mStringType = SENSOR_STRING_TYPE_HEAD_TRACKER; mFlags |= SENSOR_FLAG_CONTINUOUS_MODE; break; + case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES: + mStringType = SENSOR_STRING_TYPE_ACCELEROMETER_LIMITED_AXES; + mFlags |= SENSOR_FLAG_CONTINUOUS_MODE; + break; + case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES: + mStringType = SENSOR_STRING_TYPE_GYROSCOPE_LIMITED_AXES; + mFlags |= SENSOR_FLAG_CONTINUOUS_MODE; + break; + case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED: + mStringType = SENSOR_STRING_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED; + mFlags |= SENSOR_FLAG_CONTINUOUS_MODE; + break; + case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED: + mStringType = SENSOR_STRING_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED; + mFlags |= SENSOR_FLAG_CONTINUOUS_MODE; + break; + case SENSOR_TYPE_HEADING: + mStringType = SENSOR_STRING_TYPE_HEADING; + mFlags |= SENSOR_FLAG_CONTINUOUS_MODE; + break; default: // Only pipe the stringType, requiredPermission and flags for custom sensors. if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor.stringType) { diff --git a/services/gpuservice/bpfprogs/Android.bp b/services/gpuservice/bpfprogs/Android.bp index 9842ed7c3c..076affda5a 100644 --- a/services/gpuservice/bpfprogs/Android.bp +++ b/services/gpuservice/bpfprogs/Android.bp @@ -24,6 +24,7 @@ package { bpf { name: "gpu_mem.o", srcs: ["gpu_mem.c"], + btf: true, cflags: [ "-Wall", "-Werror", diff --git a/services/gpuservice/gpumem/Android.bp b/services/gpuservice/gpumem/Android.bp index 24087ac9e6..d0ea856fb5 100644 --- a/services/gpuservice/gpumem/Android.bp +++ b/services/gpuservice/gpumem/Android.bp @@ -26,19 +26,17 @@ cc_library_shared { srcs: [ "GpuMem.cpp", ], + header_libs: ["bpf_headers"], shared_libs: [ "libbase", "libbpf_bcc", - "libbpf_android", "libcutils", "liblog", "libutils", ], export_include_dirs: ["include"], - export_shared_lib_headers: [ - "libbase", - "libbpf_android", - ], + export_header_lib_headers: ["bpf_headers"], + export_shared_lib_headers: ["libbase"], cppflags: [ "-Wall", "-Werror", diff --git a/services/gpuservice/tests/unittests/Android.bp b/services/gpuservice/tests/unittests/Android.bp index 5b69f960a2..4fb0d2e734 100644 --- a/services/gpuservice/tests/unittests/Android.bp +++ b/services/gpuservice/tests/unittests/Android.bp @@ -32,10 +32,10 @@ cc_test { "GpuMemTracerTest.cpp", "GpuStatsTest.cpp", ], + header_libs: ["bpf_headers"], shared_libs: [ "libbase", "libbpf_bcc", - "libbpf_android", "libcutils", "libgfxstats", "libgpumem", diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index aa3643caef..7062aefc0d 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -137,7 +137,7 @@ constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms; // Number of recent events to keep for debugging purposes. constexpr size_t RECENT_QUEUE_MAX_SIZE = 10; -// Event log tags. See EventLogTags.logtags for reference +// Event log tags. See EventLogTags.logtags for reference. constexpr int LOGTAG_INPUT_INTERACTION = 62000; constexpr int LOGTAG_INPUT_FOCUS = 62001; constexpr int LOGTAG_INPUT_CANCEL = 62003; @@ -417,20 +417,6 @@ KeyEvent createKeyEvent(const KeyEntry& entry) { return event; } -std::optional<int32_t> findMonitorPidByToken( - const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay, - const sp<IBinder>& token) { - for (const auto& it : monitorsByDisplay) { - const std::vector<Monitor>& monitors = it.second; - for (const Monitor& monitor : monitors) { - if (monitor.inputChannel->getConnectionToken() == token) { - return monitor.pid; - } - } - } - return std::nullopt; -} - bool shouldReportMetricsForConnection(const Connection& connection) { // Do not keep track of gesture monitors. They receive every event and would disproportionately // affect the statistics. @@ -948,15 +934,16 @@ bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEnt return true; } - // Alternatively, maybe there's a gesture monitor that could handle this event - for (const auto& monitor : getValueByKey(mGestureMonitorsByDisplay, displayId)) { - sp<Connection> connection = - getConnectionLocked(monitor.inputChannel->getConnectionToken()); + // Alternatively, maybe there's a spy window that could handle this event. + const std::vector<sp<WindowInfoHandle>> touchedSpies = + findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus); + for (const auto& windowHandle : touchedSpies) { + const sp<Connection> connection = getConnectionLocked(windowHandle->getToken()); if (connection != nullptr && connection->responsive) { - // This monitor could take more input. Drop all events preceding this - // event, so that gesture monitor could get a chance to receive the stream + // This spy window could take more input. Drop all events preceding this + // event, so that the spy window can get a chance to receive the stream. ALOGW("Pruning the input queue because %s is unresponsive, but we have a " - "responsive gesture monitor that may handle the event", + "responsive spy window that may handle the event.", mAwaitedFocusedApplication->getName().c_str()); return true; } @@ -2000,7 +1987,7 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( TouchState tempTouchState; if (const auto it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) { oldState = &(it->second); - tempTouchState.copyFrom(*oldState); + tempTouchState = *oldState; } bool isSplit = tempTouchState.split; @@ -2104,6 +2091,13 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle); } + if (newTouchedWindows.empty()) { + ALOGI("Dropping event because there is no touchable window at (%d, %d) on display %d.", + x, y, displayId); + injectionResult = InputEventInjectionResult::FAILED; + goto Failed; + } + for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) { const WindowInfo& info = *windowHandle->getInfo(); @@ -2172,23 +2166,6 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, pointerIds); } - - const std::vector<Monitor> newGestureMonitors = isDown - ? selectResponsiveMonitorsLocked( - getValueByKey(mGestureMonitorsByDisplay, displayId)) - : std::vector<Monitor>{}; - - if (newTouchedWindows.empty() && newGestureMonitors.empty() && - tempTouchState.gestureMonitors.empty()) { - ALOGI("Dropping event because there is no touchable window or gesture monitor at " - "(%d, %d) in display %" PRId32 ".", - x, y, displayId); - injectionResult = InputEventInjectionResult::FAILED; - goto Failed; - } - - tempTouchState.addGestureMonitors(newGestureMonitors); - } else { /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */ @@ -2290,39 +2267,33 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( } } - // Check permission to inject into all touched foreground windows and ensure there - // is at least one touched foreground window. - { - bool haveForegroundOrSpyWindow = false; - for (const TouchedWindow& touchedWindow : tempTouchState.windows) { - const bool isForeground = - (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) != 0; - if (touchedWindow.windowHandle->getInfo()->isSpy()) { - haveForegroundOrSpyWindow = true; - LOG_ALWAYS_FATAL_IF(isForeground, - "Spy window cannot be dispatched as a foreground window."); - } - if (isForeground) { - haveForegroundOrSpyWindow = true; - if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) { - injectionResult = InputEventInjectionResult::PERMISSION_DENIED; - injectionPermission = INJECTION_PERMISSION_DENIED; - goto Failed; - } - } - } - bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty(); - if (!haveForegroundOrSpyWindow && !hasGestureMonitor) { - ALOGI("Dropping event because there is no touched window in display " - "%" PRId32 " or gesture monitor to receive it.", - displayId); - injectionResult = InputEventInjectionResult::FAILED; - goto Failed; - } + // Ensure that we have at least one foreground or spy window. It's possible that we dropped some + // of the touched windows we previously found if they became paused or unresponsive or were + // removed. + if (std::none_of(tempTouchState.windows.begin(), tempTouchState.windows.end(), + [](const TouchedWindow& touchedWindow) { + return (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) != 0 || + touchedWindow.windowHandle->getInfo()->isSpy(); + })) { + ALOGI("Dropping event because there is no touched window on display %d to receive it.", + displayId); + injectionResult = InputEventInjectionResult::FAILED; + goto Failed; + } - // Permission granted to injection into all touched foreground windows. - injectionPermission = INJECTION_PERMISSION_GRANTED; + // Check permission to inject into all touched foreground windows. + if (std::any_of(tempTouchState.windows.begin(), tempTouchState.windows.end(), + [this, &entry](const TouchedWindow& touchedWindow) { + return (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) != 0 && + !checkInjectionPermission(touchedWindow.windowHandle, + entry.injectionState); + })) { + injectionResult = InputEventInjectionResult::PERMISSION_DENIED; + injectionPermission = INJECTION_PERMISSION_DENIED; + goto Failed; } + // Permission granted to inject into all touched foreground windows. + injectionPermission = INJECTION_PERMISSION_GRANTED; // Check whether windows listening for outside touches are owned by the same UID. If it is // set the policy flag that we will not reveal coordinate information to this window. @@ -2380,10 +2351,6 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( touchedWindow.pointerIds, inputTargets); } - for (const auto& monitor : tempTouchState.gestureMonitors) { - addMonitoringTargetLocked(monitor, displayId, inputTargets); - } - // Drop the outside or hover touch windows since we will not care about them // in the next iteration. tempTouchState.filterNonAsIsTouchWindows(); @@ -2584,32 +2551,21 @@ void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHa void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets, int32_t displayId) { - std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it = - mGlobalMonitorsByDisplay.find(displayId); + auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId); + if (monitorsIt == mGlobalMonitorsByDisplay.end()) return; - if (it != mGlobalMonitorsByDisplay.end()) { - const std::vector<Monitor>& monitors = it->second; - for (const Monitor& monitor : monitors) { - addMonitoringTargetLocked(monitor, displayId, inputTargets); + for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) { + InputTarget target; + target.inputChannel = monitor.inputChannel; + target.flags = InputTarget::FLAG_DISPATCH_AS_IS; + if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) { + target.displayTransform = it->second.transform; } + target.setDefaultPointerTransform(target.displayTransform); + inputTargets.push_back(target); } } -void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, int32_t displayId, - std::vector<InputTarget>& inputTargets) { - InputTarget target; - target.inputChannel = monitor.inputChannel; - target.flags = InputTarget::FLAG_DISPATCH_AS_IS; - ui::Transform t; - if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) { - const auto& displayTransform = it->second.transform; - target.displayTransform = displayTransform; - t = displayTransform; - } - target.setDefaultPointerTransform(t); - inputTargets.push_back(target); -} - bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle, const InjectionState* injectionState) { if (injectionState && @@ -3573,15 +3529,7 @@ void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked( void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked( const CancelationOptions& options) { - synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay); - synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay); -} - -void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked( - const CancelationOptions& options, - std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) { - for (const auto& it : monitorsByDisplay) { - const std::vector<Monitor>& monitors = it.second; + for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) { for (const Monitor& monitor : monitors) { synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options); } @@ -4955,23 +4903,42 @@ void InputDispatcher::setInputFilterEnabled(bool enabled) { mLooper->wake(); } -void InputDispatcher::setInTouchMode(bool inTouchMode) { +bool InputDispatcher::setInTouchMode(bool inTouchMode, int32_t pid, int32_t uid, + bool hasPermission) { bool needWake = false; { std::scoped_lock lock(mLock); if (mInTouchMode == inTouchMode) { - return; + return false; } if (DEBUG_TOUCH_MODE) { - ALOGD("Request to change touch mode from %s to %s", toString(mInTouchMode), - toString(inTouchMode)); - // TODO(b/198487159): Also print the current last interacted apps. + ALOGD("Request to change touch mode from %s to %s (calling pid=%d, uid=%d, " + "hasPermission=%s)", + toString(mInTouchMode), toString(inTouchMode), pid, uid, toString(hasPermission)); + } + if (!hasPermission) { + const sp<IBinder> focusedToken = + mFocusResolver.getFocusedWindowToken(mFocusedDisplayId); + + // TODO(b/218541064): if no window is currently focused, then we need to check the last + // interacted window (within 1 second timeout). We should allow touch mode change + // if the last interacted window owner's pid/uid match the calling ones. + if (focusedToken == nullptr) { + return false; + } + const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(focusedToken); + if (windowHandle == nullptr) { + return false; + } + const WindowInfo* windowInfo = windowHandle->getInfo(); + if (pid != windowInfo->ownerPid || uid != windowInfo->ownerUid) { + return false; + } } // TODO(b/198499018): Store touch mode per display. mInTouchMode = inTouchMode; - // TODO(b/198487159): Enforce that only last interacted apps can change touch mode. auto entry = std::make_unique<TouchModeEntry>(mIdGenerator.nextId(), now(), inTouchMode); needWake = enqueueInboundEventLocked(std::move(entry)); } // release lock @@ -4979,6 +4946,7 @@ void InputDispatcher::setInTouchMode(bool inTouchMode) { if (needWake) { mLooper->wake(); } + return true; } void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) { @@ -5266,22 +5234,16 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) { dump += INDENT "Displays: <none>\n"; } - if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) { - for (auto& it : mGlobalMonitorsByDisplay) { - const std::vector<Monitor>& monitors = it.second; - dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first); - dumpMonitors(dump, monitors); - } - for (auto& it : mGestureMonitorsByDisplay) { - const std::vector<Monitor>& monitors = it.second; - dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first); + if (!mGlobalMonitorsByDisplay.empty()) { + for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) { + dump += StringPrintf(INDENT "Global monitors on display %d:\n", displayId); dumpMonitors(dump, monitors); } } else { - dump += INDENT "Monitors: <none>\n"; + dump += INDENT "Global Monitors: <none>\n"; } - nsecs_t currentTime = now(); + const nsecs_t currentTime = now(); // Dump recently dispatched or dropped events from oldest to newest. if (!mRecentQueue.empty()) { @@ -5439,7 +5401,6 @@ Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const } Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId, - bool isGestureMonitor, const std::string& name, int32_t pid) { std::shared_ptr<InputChannel> serverChannel; @@ -5468,13 +5429,9 @@ Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_ std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback, this, std::placeholders::_1, token); - auto& monitorsByDisplay = - isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay; - monitorsByDisplay[displayId].emplace_back(serverChannel, pid); + mGlobalMonitorsByDisplay[displayId].emplace_back(serverChannel, pid); mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr); - ALOGI("Created monitor %s for display %" PRId32 ", gesture=%s, pid=%" PRId32, name.c_str(), - displayId, toString(isGestureMonitor), pid); } // Wake the looper because some connections have changed. @@ -5522,26 +5479,14 @@ status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connection } void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) { - removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay); - removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay); -} - -void InputDispatcher::removeMonitorChannelLocked( - const sp<IBinder>& connectionToken, - std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) { - for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) { - std::vector<Monitor>& monitors = it->second; - const size_t numMonitors = monitors.size(); - for (size_t i = 0; i < numMonitors; i++) { - if (monitors[i].inputChannel->getConnectionToken() == connectionToken) { - ALOGI("Erasing monitor %s on display %" PRId32 ", pid=%" PRId32, - monitors[i].inputChannel->getName().c_str(), it->first, monitors[i].pid); - monitors.erase(monitors.begin() + i); - break; - } - } + for (auto it = mGlobalMonitorsByDisplay.begin(); it != mGlobalMonitorsByDisplay.end();) { + auto& [displayId, monitors] = *it; + std::erase_if(monitors, [connectionToken](const Monitor& monitor) { + return monitor.inputChannel->getConnectionToken() == connectionToken; + }); + if (monitors.empty()) { - it = monitorsByDisplay.erase(it); + it = mGlobalMonitorsByDisplay.erase(it); } else { ++it; } @@ -5549,81 +5494,45 @@ void InputDispatcher::removeMonitorChannelLocked( } status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) { - { // acquire lock - std::scoped_lock _l(mLock); + std::scoped_lock _l(mLock); - TouchState* statePtr = nullptr; - std::shared_ptr<InputChannel> requestingChannel; - int32_t displayId; - int32_t deviceId; - const std::optional<int32_t> foundGestureMonitorDisplayId = - findGestureMonitorDisplayByTokenLocked(token); - - // TODO: Optimize this function for pilfering from windows when removing gesture monitors. - if (foundGestureMonitorDisplayId) { - // A gesture monitor has requested to pilfer pointers. - displayId = *foundGestureMonitorDisplayId; - auto stateIt = mTouchStatesByDisplay.find(displayId); - if (stateIt == mTouchStatesByDisplay.end()) { - ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId); - return BAD_VALUE; - } - statePtr = &stateIt->second; + const std::shared_ptr<InputChannel> requestingChannel = getInputChannelLocked(token); + if (!requestingChannel) { + ALOGW("Attempted to pilfer pointers from an un-registered channel or invalid token"); + return BAD_VALUE; + } - for (const auto& monitor : statePtr->gestureMonitors) { - if (monitor.inputChannel->getConnectionToken() == token) { - requestingChannel = monitor.inputChannel; - deviceId = statePtr->deviceId; - } - } - } else { - // Check if a window has requested to pilfer pointers. - for (auto& [curDisplayId, state] : mTouchStatesByDisplay) { - const sp<WindowInfoHandle>& windowHandle = state.getWindow(token); - if (windowHandle != nullptr) { - displayId = curDisplayId; - requestingChannel = getInputChannelLocked(token); - deviceId = state.deviceId; - statePtr = &state; - break; - } - } - } + auto [statePtr, windowPtr] = findTouchStateAndWindowLocked(token); + if (statePtr == nullptr || windowPtr == nullptr || !statePtr->down) { + ALOGW("Attempted to pilfer points from a channel without any on-going pointer streams." + " Ignoring."); + return BAD_VALUE; + } - if (requestingChannel == nullptr) { - ALOGW("Attempted to pilfer pointers from an un-registered channel or invalid token"); - return BAD_VALUE; - } - TouchState& state = *statePtr; - if (!state.down) { - ALOGW("Attempted to pilfer points from a channel without any on-going pointer streams." - " Ignoring."); - return BAD_VALUE; - } + TouchState& state = *statePtr; - // Send cancel events to all the input channels we're stealing from. - CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, - "input channel stole pointer stream"); - options.deviceId = deviceId; - options.displayId = displayId; - std::string canceledWindows; - for (const TouchedWindow& window : state.windows) { - std::shared_ptr<InputChannel> channel = - getInputChannelLocked(window.windowHandle->getToken()); - if (channel != nullptr && channel->getConnectionToken() != token) { - synthesizeCancelationEventsForInputChannelLocked(channel, options); - canceledWindows += canceledWindows.empty() ? "[" : ", "; - canceledWindows += channel->getName(); - } + // Send cancel events to all the input channels we're stealing from. + CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, + "input channel stole pointer stream"); + options.deviceId = state.deviceId; + options.displayId = state.displayId; + std::string canceledWindows; + for (const TouchedWindow& window : state.windows) { + const std::shared_ptr<InputChannel> channel = + getInputChannelLocked(window.windowHandle->getToken()); + if (channel != nullptr && channel->getConnectionToken() != token) { + synthesizeCancelationEventsForInputChannelLocked(channel, options); + canceledWindows += canceledWindows.empty() ? "[" : ", "; + canceledWindows += channel->getName(); } - canceledWindows += canceledWindows.empty() ? "[]" : "]"; - ALOGI("Channel %s is stealing touch from %s", requestingChannel->getName().c_str(), - canceledWindows.c_str()); - - // Then clear the current touch state so we stop dispatching to them as well. - state.split = false; - state.filterWindowsExcept(token); } + canceledWindows += canceledWindows.empty() ? "[]" : "]"; + ALOGI("Channel %s is stealing touch from %s", requestingChannel->getName().c_str(), + canceledWindows.c_str()); + + // Prevent the gesture from being sent to any other windows. + state.filterWindowsExcept(token); + state.preventNewTargets = true; return OK; } @@ -5677,27 +5586,17 @@ void InputDispatcher::setDisplayEligibilityForPointerCapture(int32_t displayId, } // release lock } -std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked( - const sp<IBinder>& token) { - for (const auto& it : mGestureMonitorsByDisplay) { - const std::vector<Monitor>& monitors = it.second; +std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) { + for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) { for (const Monitor& monitor : monitors) { if (monitor.inputChannel->getConnectionToken() == token) { - return it.first; + return monitor.pid; } } } return std::nullopt; } -std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) { - std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token); - if (gesturePid.has_value()) { - return gesturePid; - } - return findMonitorPidByToken(mGlobalMonitorsByDisplay, token); -} - sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const { if (inputConnectionToken == nullptr) { return nullptr; diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h index bff6cac149..e162c78b81 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.h +++ b/services/inputflinger/dispatcher/InputDispatcher.h @@ -117,7 +117,7 @@ public: void setFocusedDisplay(int32_t displayId) override; void setInputDispatchMode(bool enabled, bool frozen) override; void setInputFilterEnabled(bool enabled) override; - void setInTouchMode(bool inTouchMode) override; + bool setInTouchMode(bool inTouchMode, int32_t pid, int32_t uid, bool hasPermission) override; void setMaximumObscuringOpacityForTouch(float opacity) override; void setBlockUntrustedTouchesMode(android::os::BlockUntrustedTouchesMode mode) override; @@ -129,7 +129,6 @@ public: const std::string& name) override; void setFocusedWindow(const android::gui::FocusRequest&) override; base::Result<std::unique_ptr<InputChannel>> createInputMonitor(int32_t displayId, - bool isGestureMonitor, const std::string& name, int32_t pid) override; status_t removeInputChannel(const sp<IBinder>& connectionToken) override; @@ -260,21 +259,12 @@ private: std::unordered_map<sp<IBinder>, sp<Connection>, StrongPointerHash<IBinder>> mConnectionsByToken GUARDED_BY(mLock); - // Finds the display ID of the gesture monitor identified by the provided token. - std::optional<int32_t> findGestureMonitorDisplayByTokenLocked(const sp<IBinder>& token) - REQUIRES(mLock); // Find a monitor pid by the provided token. std::optional<int32_t> findMonitorPidByTokenLocked(const sp<IBinder>& token) REQUIRES(mLock); // Input channels that will receive a copy of all input events sent to the provided display. std::unordered_map<int32_t, std::vector<Monitor>> mGlobalMonitorsByDisplay GUARDED_BY(mLock); - // Input channels that will receive pointer events that start within the corresponding display. - // These are a bit special when compared to global monitors since they'll cause gesture streams - // to continue even when there isn't a touched window,and have the ability to steal the rest of - // the pointer stream in order to claim it for a system gesture. - std::unordered_map<int32_t, std::vector<Monitor>> mGestureMonitorsByDisplay GUARDED_BY(mLock); - const HmacKeyManager mHmacKeyManager; const std::array<uint8_t, 32> getSignature(const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const; @@ -530,7 +520,6 @@ private: sp<android::gui::WindowInfoHandle> mLastHoverWindowHandle GUARDED_BY(mLock); void cancelEventsForAnrLocked(const sp<Connection>& connection) REQUIRES(mLock); - nsecs_t getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime) REQUIRES(mLock); // If a focused application changes, we should stop counting down the "no focused window" time, // because we will have no way of knowing when the previous application actually added a window. // This also means that we will miss cases like pulling down notification shade when the @@ -551,8 +540,6 @@ private: void addWindowTargetLocked(const sp<android::gui::WindowInfoHandle>& windowHandle, int32_t targetFlags, BitSet32 pointerIds, std::vector<InputTarget>& inputTargets) REQUIRES(mLock); - void addMonitoringTargetLocked(const Monitor& monitor, int32_t displayId, - std::vector<InputTarget>& inputTargets) REQUIRES(mLock); void addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets, int32_t displayId) REQUIRES(mLock); void pokeUserActivityLocked(const EventEntry& eventEntry) REQUIRES(mLock); @@ -618,9 +605,6 @@ private: REQUIRES(mLock); void synthesizeCancelationEventsForMonitorsLocked(const CancelationOptions& options) REQUIRES(mLock); - void synthesizeCancelationEventsForMonitorsLocked( - const CancelationOptions& options, - std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) REQUIRES(mLock); void synthesizeCancelationEventsForInputChannelLocked( const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) REQUIRES(mLock); @@ -646,9 +630,6 @@ private: // Registration. void removeMonitorChannelLocked(const sp<IBinder>& connectionToken) REQUIRES(mLock); - void removeMonitorChannelLocked( - const sp<IBinder>& connectionToken, - std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) REQUIRES(mLock); status_t removeInputChannelLocked(const sp<IBinder>& connectionToken, bool notify) REQUIRES(mLock); diff --git a/services/inputflinger/dispatcher/TouchState.cpp b/services/inputflinger/dispatcher/TouchState.cpp index 08c7826045..b63fe104fa 100644 --- a/services/inputflinger/dispatcher/TouchState.cpp +++ b/services/inputflinger/dispatcher/TouchState.cpp @@ -25,29 +25,8 @@ using android::gui::WindowInfoHandle; namespace android::inputdispatcher { -TouchState::TouchState() - : down(false), split(false), deviceId(-1), source(0), displayId(ADISPLAY_ID_NONE) {} - -TouchState::~TouchState() {} - void TouchState::reset() { - down = false; - split = false; - deviceId = -1; - source = 0; - displayId = ADISPLAY_ID_NONE; - windows.clear(); - gestureMonitors.clear(); -} - -void TouchState::copyFrom(const TouchState& other) { - down = other.down; - split = other.split; - deviceId = other.deviceId; - source = other.source; - displayId = other.displayId; - windows = other.windows; - gestureMonitors = other.gestureMonitors; + *this = TouchState(); } void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, int32_t targetFlags, @@ -68,6 +47,8 @@ void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, int } } + if (preventNewTargets) return; // Don't add new TouchedWindows. + TouchedWindow touchedWindow; touchedWindow.windowHandle = windowHandle; touchedWindow.targetFlags = targetFlags; @@ -75,13 +56,6 @@ void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, int windows.push_back(touchedWindow); } -void TouchState::addGestureMonitors(const std::vector<Monitor>& newMonitors) { - const size_t newSize = gestureMonitors.size() + newMonitors.size(); - gestureMonitors.reserve(newSize); - gestureMonitors.insert(std::end(gestureMonitors), std::begin(newMonitors), - std::end(newMonitors)); -} - void TouchState::removeWindowByToken(const sp<IBinder>& token) { for (size_t i = 0; i < windows.size(); i++) { if (windows[i].windowHandle->getToken() == token) { diff --git a/services/inputflinger/dispatcher/TouchState.h b/services/inputflinger/dispatcher/TouchState.h index 83ca90197b..9efb2808c5 100644 --- a/services/inputflinger/dispatcher/TouchState.h +++ b/services/inputflinger/dispatcher/TouchState.h @@ -29,22 +29,26 @@ class WindowInfoHandle; namespace inputdispatcher { struct TouchState { - bool down; - bool split; - int32_t deviceId; // id of the device that is currently down, others are rejected - uint32_t source; // source of the device that is current down, others are rejected - int32_t displayId; // id to the display that currently has a touch, others are rejected + bool down = false; + bool split = false; + bool preventNewTargets = false; + + // id of the device that is currently down, others are rejected + int32_t deviceId = -1; + // source of the device that is current down, others are rejected + uint32_t source = 0; + // id to the display that currently has a touch, others are rejected + int32_t displayId = ADISPLAY_ID_NONE; + std::vector<TouchedWindow> windows; - std::vector<Monitor> gestureMonitors; + TouchState() = default; + ~TouchState() = default; + TouchState& operator=(const TouchState&) = default; - TouchState(); - ~TouchState(); void reset(); - void copyFrom(const TouchState& other); void addOrUpdateWindow(const sp<android::gui::WindowInfoHandle>& windowHandle, int32_t targetFlags, BitSet32 pointerIds); - void addGestureMonitors(const std::vector<Monitor>& monitors); void removeWindowByToken(const sp<IBinder>& token); void filterNonAsIsTouchWindows(); void filterWindowsExcept(const sp<IBinder>& token); diff --git a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h index 16a6f16555..67e1b6f93b 100644 --- a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h +++ b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h @@ -123,8 +123,10 @@ public: * Touch mode is a global state that apps may enter / exit based on specific * user interactions with input devices. * If true, the device is in touch mode. + * + * Returns true when changing touch mode state. */ - virtual void setInTouchMode(bool inTouchMode) = 0; + virtual bool setInTouchMode(bool inTouchMode, int32_t pid, int32_t uid, bool hasPermission) = 0; /** * Sets the maximum allowed obscuring opacity by UID to propagate touches. @@ -169,16 +171,14 @@ public: const std::string& name) = 0; /** - * Creates an input channel to be used to monitor input events. + * Creates an input channel to be used to monitor all input events on a display. * * Each monitor must target a specific display and will only receive input events sent to that - * display. If the monitor is a gesture monitor, it will only receive pointer events on the - * targeted display. + * display. * * This method may be called on any thread (usually by the input manager). */ virtual base::Result<std::unique_ptr<InputChannel>> createInputMonitor(int32_t displayId, - bool gestureMonitor, const std::string& name, int32_t pid) = 0; diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index f97a9ec8bc..872882e5d8 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -1127,6 +1127,16 @@ public: expectedFlags); } + void consumeMotionOutsideWithZeroedCoords(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT, + int32_t expectedFlags = 0) { + InputEvent* event = consume(); + ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType()); + const MotionEvent& motionEvent = static_cast<MotionEvent&>(*event); + EXPECT_EQ(AMOTION_EVENT_ACTION_OUTSIDE, motionEvent.getActionMasked()); + EXPECT_EQ(0.f, motionEvent.getRawPointerCoords(0)->getX()); + EXPECT_EQ(0.f, motionEvent.getRawPointerCoords(0)->getY()); + } + void consumeFocusEvent(bool hasFocus, bool inTouchMode = true) { ASSERT_NE(mInputReceiver, nullptr) << "Cannot consume events from a window with no receiver"; @@ -2769,8 +2779,7 @@ public: FakeMonitorReceiver(const std::unique_ptr<InputDispatcher>& dispatcher, const std::string name, int32_t displayId) { base::Result<std::unique_ptr<InputChannel>> channel = - dispatcher->createInputMonitor(displayId, false /*isGestureMonitor*/, name, - MONITOR_PID); + dispatcher->createInputMonitor(displayId, name, MONITOR_PID); mInputReceiver = std::make_unique<FakeInputReceiver>(std::move(*channel), name); } @@ -2988,6 +2997,7 @@ TEST_F(InputDispatcherTest, TouchModeState_IsSentToApps) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT); + const WindowInfo& windowInfo = *window->getInfo(); // Set focused application. mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); @@ -3004,7 +3014,8 @@ TEST_F(InputDispatcherTest, TouchModeState_IsSentToApps) { window->consumeFocusEvent(false /*hasFocus*/, true /*inTouchMode*/); SCOPED_TRACE("Disable touch mode"); - mDispatcher->setInTouchMode(false); + mDispatcher->setInTouchMode(false, windowInfo.ownerPid, windowInfo.ownerUid, + /* hasPermission */ true); window->consumeTouchModeEvent(false); window->setFocusable(true); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}}); @@ -3017,7 +3028,8 @@ TEST_F(InputDispatcherTest, TouchModeState_IsSentToApps) { window->consumeFocusEvent(false /*hasFocus*/, false /*inTouchMode*/); SCOPED_TRACE("Enable touch mode again"); - mDispatcher->setInTouchMode(true); + mDispatcher->setInTouchMode(true, windowInfo.ownerPid, windowInfo.ownerUid, + /* hasPermission */ true); window->consumeTouchModeEvent(true); window->setFocusable(true); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}}); @@ -5613,11 +5625,7 @@ TEST_F(InputDispatcherUntrustedTouchesTest, OutsideEvent_HasZeroCoordinates) { touch(); - InputEvent* event = w->consume(); - ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType()); - MotionEvent& motionEvent = static_cast<MotionEvent&>(*event); - EXPECT_EQ(0.0f, motionEvent.getRawPointerCoords(0)->getX()); - EXPECT_EQ(0.0f, motionEvent.getRawPointerCoords(0)->getY()); + w->consumeMotionOutsideWithZeroedCoords(); } TEST_F(InputDispatcherUntrustedTouchesTest, WindowWithOpacityBelowThreshold_AllowsTouch) { @@ -6226,19 +6234,23 @@ protected: mWindow->consumeFocusEvent(true); } - void changeAndVerifyTouchMode(bool inTouchMode) { - mDispatcher->setInTouchMode(inTouchMode); + void changeAndVerifyTouchMode(bool inTouchMode, int32_t pid, int32_t uid, bool hasPermission) { + mDispatcher->setInTouchMode(inTouchMode, pid, uid, hasPermission); mWindow->consumeTouchModeEvent(inTouchMode); mSecondWindow->consumeTouchModeEvent(inTouchMode); } }; TEST_F(InputDispatcherTouchModeChangedTests, ChangeTouchModeOnFocusedWindow) { - changeAndVerifyTouchMode(!InputDispatcher::kDefaultInTouchMode); + const WindowInfo& windowInfo = *mWindow->getInfo(); + changeAndVerifyTouchMode(!InputDispatcher::kDefaultInTouchMode, windowInfo.ownerPid, + windowInfo.ownerUid, /* hasPermission */ false); } TEST_F(InputDispatcherTouchModeChangedTests, EventIsNotGeneratedIfNotChangingTouchMode) { - mDispatcher->setInTouchMode(InputDispatcher::kDefaultInTouchMode); + const WindowInfo& windowInfo = *mWindow->getInfo(); + mDispatcher->setInTouchMode(InputDispatcher::kDefaultInTouchMode, windowInfo.ownerPid, + windowInfo.ownerUid, /* hasPermission */ true); mWindow->assertNoEvents(); mSecondWindow->assertNoEvents(); } @@ -6428,20 +6440,23 @@ TEST_F(InputDispatcherSpyWindowTest, ModalWindow) { /** * A spy window can listen for touches outside its touchable region using the WATCH_OUTSIDE_TOUCHES - * flag. + * flag, but it will get zero-ed out coordinates if the foreground has a different owner. */ TEST_F(InputDispatcherSpyWindowTest, WatchOutsideTouches) { auto window = createForeground(); + window->setOwnerInfo(12, 34); auto spy = createSpy(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::WATCH_OUTSIDE_TOUCH); + spy->setOwnerInfo(56, 78); spy->setFrame(Rect{0, 0, 20, 20}); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy, window}}}); // Inject an event outside the spy window's frame and touchable region. ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, - injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT)) + injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, + {100, 200})) << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; window->consumeMotionDown(); - spy->consumeMotionOutside(); + spy->consumeMotionOutsideWithZeroedCoords(); } /** @@ -6503,32 +6518,29 @@ TEST_F(InputDispatcherSpyWindowTest, CanPilferAfterWindowIsRemovedMidStream) { } /** - * After a spy window pilfers pointers, new pointers that go down should not go to any foreground - * windows. + * After a spy window pilfers pointers, new pointers that go down in its bounds should be sent to + * the spy, but not to any other windows. */ -TEST_F(InputDispatcherSpyWindowTest, NoSplitAfterPilfer) { - // Create a touch modal spy that spies on the entire display. - auto spy = createSpy(static_cast<WindowInfo::Flag>(0)); - - // Create a non touch modal window that supports split touch. +TEST_F(InputDispatcherSpyWindowTest, ContinuesToReceiveGestureAfterPilfer) { + auto spy = createSpy(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH); auto window = createForeground(); - window->setFrame(Rect(0, 0, 100, 100)); window->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy, window}}}); - // First finger down, no window touched. + // First finger down on the window and the spy. ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {100, 200})) << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; - spy->consumeMotionDown(ADISPLAY_ID_DEFAULT); - window->assertNoEvents(); + spy->consumeMotionDown(); + window->consumeMotionDown(); - // Spy window pilfer the pointers. + // Spy window pilfers the pointers. EXPECT_EQ(OK, mDispatcher->pilferPointers(spy->getToken())); + window->consumeMotionCancel(); - // Second finger down on window, the window should not receive touch down. + // Second finger down on the window and spy, but the window should not receive the pointer down. const MotionEvent secondFingerDownEvent = MotionEventBuilder(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), @@ -6545,10 +6557,28 @@ TEST_F(InputDispatcherSpyWindowTest, NoSplitAfterPilfer) { InputEventInjectionSync::WAIT_FOR_RESULT)) << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; + spy->consumeMotionPointerDown(1 /*pointerIndex*/); + + // Third finger goes down outside all windows, so injection should fail. + const MotionEvent thirdFingerDownEvent = + MotionEventBuilder(AMOTION_EVENT_ACTION_POINTER_DOWN | + (2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), + AINPUT_SOURCE_TOUCHSCREEN) + .displayId(ADISPLAY_ID_DEFAULT) + .eventTime(systemTime(SYSTEM_TIME_MONOTONIC)) + .pointer(PointerBuilder(/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER) + .x(100) + .y(200)) + .pointer(PointerBuilder(/* id */ 1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50)) + .pointer(PointerBuilder(/* id */ 2, AMOTION_EVENT_TOOL_TYPE_FINGER).x(-5).y(-5)) + .build(); + ASSERT_EQ(InputEventInjectionResult::FAILED, + injectMotionEvent(mDispatcher, thirdFingerDownEvent, INJECT_EVENT_TIMEOUT, + InputEventInjectionSync::WAIT_FOR_RESULT)) + << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; + + spy->assertNoEvents(); window->assertNoEvents(); - // Since we no longer allow splitting, the spy will not receive new pointers. - // TODO(b/217376964): Add a way for the pilfering window to receive the rest of the gesture. - spy->consumeMotionMove(); } /** @@ -6790,4 +6820,7 @@ TEST_F(InputDispatcherStylusInterceptorTest, SpyWindowStylusInterceptor) { window->assertNoEvents(); } +// TODO(b/198487159): Add permission tests for touch mode switch once the validation is put in +// place. + } // namespace android::inputdispatcher diff --git a/services/sensorservice/AidlSensorHalWrapper.cpp b/services/sensorservice/AidlSensorHalWrapper.cpp index cdd95ca18f..86c8b0dbea 100644 --- a/services/sensorservice/AidlSensorHalWrapper.cpp +++ b/services/sensorservice/AidlSensorHalWrapper.cpp @@ -250,6 +250,46 @@ void convertToSensorEvent(const Event &src, sensors_event_t *dst) { break; } + case SensorType::ACCELEROMETER_LIMITED_AXES: + case SensorType::GYROSCOPE_LIMITED_AXES: + dst->limited_axes_imu.x = src.payload.get<Event::EventPayload::limitedAxesImu>().x; + dst->limited_axes_imu.y = src.payload.get<Event::EventPayload::limitedAxesImu>().y; + dst->limited_axes_imu.z = src.payload.get<Event::EventPayload::limitedAxesImu>().z; + dst->limited_axes_imu.x_supported = + src.payload.get<Event::EventPayload::limitedAxesImu>().xSupported; + dst->limited_axes_imu.y_supported = + src.payload.get<Event::EventPayload::limitedAxesImu>().ySupported; + dst->limited_axes_imu.z_supported = + src.payload.get<Event::EventPayload::limitedAxesImu>().zSupported; + break; + + case SensorType::ACCELEROMETER_LIMITED_AXES_UNCALIBRATED: + case SensorType::GYROSCOPE_LIMITED_AXES_UNCALIBRATED: + dst->limited_axes_imu_uncalibrated.x_uncalib = + src.payload.get<Event::EventPayload::limitedAxesImuUncal>().x; + dst->limited_axes_imu_uncalibrated.y_uncalib = + src.payload.get<Event::EventPayload::limitedAxesImuUncal>().y; + dst->limited_axes_imu_uncalibrated.z_uncalib = + src.payload.get<Event::EventPayload::limitedAxesImuUncal>().z; + dst->limited_axes_imu_uncalibrated.x_bias = + src.payload.get<Event::EventPayload::limitedAxesImuUncal>().xBias; + dst->limited_axes_imu_uncalibrated.y_bias = + src.payload.get<Event::EventPayload::limitedAxesImuUncal>().yBias; + dst->limited_axes_imu_uncalibrated.z_bias = + src.payload.get<Event::EventPayload::limitedAxesImuUncal>().zBias; + dst->limited_axes_imu_uncalibrated.x_supported = + src.payload.get<Event::EventPayload::limitedAxesImuUncal>().xSupported; + dst->limited_axes_imu_uncalibrated.y_supported = + src.payload.get<Event::EventPayload::limitedAxesImuUncal>().ySupported; + dst->limited_axes_imu_uncalibrated.z_supported = + src.payload.get<Event::EventPayload::limitedAxesImuUncal>().zSupported; + break; + + case SensorType::HEADING: + dst->heading.heading = src.payload.get<Event::EventPayload::heading>().heading; + dst->heading.accuracy = src.payload.get<Event::EventPayload::heading>().accuracy; + break; + default: { CHECK_GE((int32_t)src.sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE); @@ -264,7 +304,7 @@ void convertFromSensorEvent(const sensors_event_t &src, Event *dst) { *dst = { .timestamp = src.timestamp, .sensorHandle = src.sensor, - .sensorType = (SensorType) src.type, + .sensorType = (SensorType)src.type, }; switch (dst->sensorType) { @@ -409,6 +449,43 @@ void convertFromSensorEvent(const sensors_event_t &src, Event *dst) { break; } + case SensorType::ACCELEROMETER_LIMITED_AXES: + case SensorType::GYROSCOPE_LIMITED_AXES: { + Event::EventPayload::LimitedAxesImu limitedAxesImu; + limitedAxesImu.x = src.limited_axes_imu.x; + limitedAxesImu.y = src.limited_axes_imu.y; + limitedAxesImu.z = src.limited_axes_imu.z; + limitedAxesImu.xSupported = src.limited_axes_imu.x_supported; + limitedAxesImu.ySupported = src.limited_axes_imu.y_supported; + limitedAxesImu.zSupported = src.limited_axes_imu.z_supported; + dst->payload.set<Event::EventPayload::Tag::limitedAxesImu>(limitedAxesImu); + break; + } + + case SensorType::ACCELEROMETER_LIMITED_AXES_UNCALIBRATED: + case SensorType::GYROSCOPE_LIMITED_AXES_UNCALIBRATED: { + Event::EventPayload::LimitedAxesImuUncal limitedAxesImuUncal; + limitedAxesImuUncal.x = src.limited_axes_imu_uncalibrated.x_uncalib; + limitedAxesImuUncal.y = src.limited_axes_imu_uncalibrated.y_uncalib; + limitedAxesImuUncal.z = src.limited_axes_imu_uncalibrated.z_uncalib; + limitedAxesImuUncal.xBias = src.limited_axes_imu_uncalibrated.x_bias; + limitedAxesImuUncal.yBias = src.limited_axes_imu_uncalibrated.y_bias; + limitedAxesImuUncal.zBias = src.limited_axes_imu_uncalibrated.z_bias; + limitedAxesImuUncal.xSupported = src.limited_axes_imu_uncalibrated.x_supported; + limitedAxesImuUncal.ySupported = src.limited_axes_imu_uncalibrated.y_supported; + limitedAxesImuUncal.zSupported = src.limited_axes_imu_uncalibrated.z_supported; + dst->payload.set<Event::EventPayload::Tag::limitedAxesImuUncal>(limitedAxesImuUncal); + break; + } + + case SensorType::HEADING: { + Event::EventPayload::Heading heading; + heading.heading = src.heading.heading; + heading.accuracy = src.heading.accuracy; + dst->payload.set<Event::EventPayload::heading>(heading); + break; + } + default: { CHECK_GE((int32_t)dst->sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE); diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp index d5b629d564..3c4f8d9bae 100644 --- a/services/sensorservice/Android.bp +++ b/services/sensorservice/Android.bp @@ -17,6 +17,7 @@ cc_library_shared { "Fusion.cpp", "GravitySensor.cpp", "HidlSensorHalWrapper.cpp", + "LimitedAxesImuSensor.cpp", "LinearAccelerationSensor.cpp", "OrientationSensor.cpp", "RecentEventLogger.cpp", diff --git a/services/sensorservice/LimitedAxesImuSensor.cpp b/services/sensorservice/LimitedAxesImuSensor.cpp new file mode 100644 index 0000000000..2f91479b38 --- /dev/null +++ b/services/sensorservice/LimitedAxesImuSensor.cpp @@ -0,0 +1,134 @@ +/* + * 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. + */ + +#include <math.h> +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Errors.h> + +#include <hardware/sensors.h> + +#include "LimitedAxesImuSensor.h" +#include "SensorDevice.h" +#include "SensorFusion.h" +#include "SensorServiceUtils.h" + +namespace android { + +namespace { +const sensor_t DUMMY_SENSOR = {.name = "", + .vendor = "", + .stringType = "", + .requiredPermission = ""}; +} // unnamed namespace + +LimitedAxesImuSensor::LimitedAxesImuSensor(sensor_t const* list, size_t count, + int32_t imu3dSensorType) + : BaseSensor(DUMMY_SENSOR) { + for (size_t i = 0; i < count; i++) { + if (list[i].type == imu3dSensorType) { + mImu3dSensor = Sensor(list + i); + break; + } + } + + const int32_t imuLimitedAxesSensorType = convertImu3dToLimitedAxesSensorType(imu3dSensorType); + + const sensor_t sensor = { + .name = convertLimitedAxesSensorTypeToName(imuLimitedAxesSensorType), + .vendor = "AOSP", + .version = 1, + .handle = convertLimitedAxesSensorTypeToHandle(imuLimitedAxesSensorType), + .type = imuLimitedAxesSensorType, + .maxRange = mImu3dSensor.getMaxValue(), + .resolution = mImu3dSensor.getResolution(), + .power = mImu3dSensor.getPowerUsage(), + .minDelay = mImu3dSensor.getMinDelay(), + }; + mSensor = Sensor(&sensor); +} + +bool LimitedAxesImuSensor::process(sensors_event_t* outEvent, const sensors_event_t& event) { + if (event.type == mImu3dSensor.getType()) { + *outEvent = event; + size_t imu3dDataSize = SensorServiceUtil::eventSizeBySensorType(mImu3dSensor.getType()); + outEvent->data[0 + imu3dDataSize] = 1; + outEvent->data[1 + imu3dDataSize] = 1; + outEvent->data[2 + imu3dDataSize] = 1; + outEvent->sensor = mSensor.getHandle(); + outEvent->type = mSensor.getType(); + return true; + } + return false; +} + +status_t LimitedAxesImuSensor::activate(void* ident, bool enabled) { + return mSensorDevice.activate(ident, mImu3dSensor.getHandle(), enabled); +} + +status_t LimitedAxesImuSensor::setDelay(void* ident, int /*handle*/, int64_t ns) { + return mSensorDevice.setDelay(ident, mImu3dSensor.getHandle(), ns); +} + +int32_t LimitedAxesImuSensor::convertImu3dToLimitedAxesSensorType(int32_t imu3dSensorType) { + switch (imu3dSensorType) { + case SENSOR_TYPE_ACCELEROMETER: + return SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES; + case SENSOR_TYPE_GYROSCOPE: + return SENSOR_TYPE_GYROSCOPE_LIMITED_AXES; + case SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED: + return SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED; + case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: + return SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED; + default: + return 0; + } +} + +int32_t LimitedAxesImuSensor::convertLimitedAxesSensorTypeToHandle( + int32_t imuLimitedAxesSensorType) { + switch (imuLimitedAxesSensorType) { + case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES: + return '_ala'; + case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES: + return '_gla'; + case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED: + return '_alc'; + case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED: + return '_glc'; + default: + return 0; + } +} + +const char* LimitedAxesImuSensor::convertLimitedAxesSensorTypeToName( + int32_t imuLimitedAxesSensorType) { + switch (imuLimitedAxesSensorType) { + case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES: + return "Accelerometer Limited Axes Sensor"; + case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES: + return "Gyroscope Limited Axes Sensor"; + case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED: + return "Accelerometer Limited Axes Uncalibrated Sensor"; + case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED: + return "Gyroscope Limited Axes Uncalibrated Sensor"; + default: + return ""; + } +} + +}; // namespace android diff --git a/services/sensorservice/LimitedAxesImuSensor.h b/services/sensorservice/LimitedAxesImuSensor.h new file mode 100644 index 0000000000..fd46a9860a --- /dev/null +++ b/services/sensorservice/LimitedAxesImuSensor.h @@ -0,0 +1,46 @@ +/* + * 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. + */ + +#pragma once + +#include <stdint.h> +#include <sys/types.h> + +#include <sensor/Sensor.h> + +#include "SensorInterface.h" + +namespace android { + +class SensorDevice; + +class LimitedAxesImuSensor : public BaseSensor { + Sensor mImu3dSensor; + +public: + LimitedAxesImuSensor(sensor_t const* list, size_t count, int32_t imuSensorType); + virtual bool process(sensors_event_t* outEvent, const sensors_event_t& event) override; + virtual status_t activate(void* ident, bool enabled) override; + virtual status_t setDelay(void* ident, int handle, int64_t ns) override; + virtual bool isVirtual() const override { return true; } + +private: + int32_t convertImu3dToLimitedAxesSensorType(int32_t imu3dSensorType); + int32_t convertLimitedAxesSensorTypeToHandle(int32_t imuLimitedAxesSensorType); + const char* convertLimitedAxesSensorTypeToName(int32_t imuLimitedAxesSensorType); +}; + +}; // namespace android
\ No newline at end of file diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp index 517d383b5a..971491dbef 100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp @@ -38,6 +38,7 @@ #include "BatteryService.h" #include "CorrectedGyroSensor.h" #include "GravitySensor.h" +#include "LimitedAxesImuSensor.h" #include "LinearAccelerationSensor.h" #include "OrientationSensor.h" #include "RotationVectorSensor.h" @@ -101,6 +102,33 @@ static const String16 sDumpPermission("android.permission.DUMP"); static const String16 sLocationHardwarePermission("android.permission.LOCATION_HARDWARE"); static const String16 sManageSensorsPermission("android.permission.MANAGE_SENSORS"); +static bool isAutomotive() { + sp<IServiceManager> serviceManager = defaultServiceManager(); + if (serviceManager.get() == nullptr) { + ALOGE("%s: unable to access native ServiceManager", __func__); + return false; + } + + sp<content::pm::IPackageManagerNative> packageManager; + sp<IBinder> binder = serviceManager->waitForService(String16("package_native")); + packageManager = interface_cast<content::pm::IPackageManagerNative>(binder); + if (packageManager == nullptr) { + ALOGE("%s: unable to access native PackageManager", __func__); + return false; + } + + bool isAutomotive = false; + binder::Status status = + packageManager->hasSystemFeature(String16("android.hardware.type.automotive"), 0, + &isAutomotive); + if (!status.isOk()) { + ALOGE("%s: hasSystemFeature failed: %s", __func__, status.exceptionMessage().c_str()); + return false; + } + + return isAutomotive; +} + SensorService::SensorService() : mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED), mWakeLockAcquired(false), mLastReportedProxIsActive(false) { @@ -165,6 +193,8 @@ void SensorService::onFirstRef() { ssize_t count = dev.getSensorList(&list); if (count > 0) { bool hasGyro = false, hasAccel = false, hasMag = false; + bool hasGyroUncalibrated = false; + bool hasAccelUncalibrated = false; uint32_t virtualSensorsNeeds = (1<<SENSOR_TYPE_GRAVITY) | (1<<SENSOR_TYPE_LINEAR_ACCELERATION) | @@ -179,13 +209,18 @@ void SensorService::onFirstRef() { case SENSOR_TYPE_ACCELEROMETER: hasAccel = true; break; + case SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED: + hasAccelUncalibrated = true; + break; case SENSOR_TYPE_MAGNETIC_FIELD: hasMag = true; break; case SENSOR_TYPE_GYROSCOPE: - case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: hasGyro = true; break; + case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: + hasGyroUncalibrated = true; + break; case SENSOR_TYPE_GRAVITY: case SENSOR_TYPE_LINEAR_ACCELERATION: case SENSOR_TYPE_ROTATION_VECTOR: @@ -216,7 +251,7 @@ void SensorService::onFirstRef() { // registered) SensorFusion::getInstance(); - if (hasGyro && hasAccel && hasMag) { + if ((hasGyro || hasGyroUncalibrated) && hasAccel && hasMag) { // Add Android virtual sensors if they're not already // available in the HAL bool needRotationVector = @@ -230,7 +265,7 @@ void SensorService::onFirstRef() { registerSensor( new GyroDriftSensor(), true, true); } - if (hasAccel && hasGyro) { + if (hasAccel && (hasGyro || hasGyroUncalibrated)) { bool needGravitySensor = (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) != 0; registerSensor(new GravitySensor(list, count), !needGravitySensor, true); @@ -250,6 +285,30 @@ void SensorService::onFirstRef() { registerSensor(new GeoMagRotationVectorSensor(), !needGeoMagRotationVector, true); } + if (isAutomotive()) { + if (hasAccel) { + registerSensor(new LimitedAxesImuSensor(list, count, SENSOR_TYPE_ACCELEROMETER), + /*isDebug=*/false, /*isVirtual=*/true); + } + + if (hasGyro) { + registerSensor(new LimitedAxesImuSensor(list, count, SENSOR_TYPE_GYROSCOPE), + /*isDebug=*/false, /*isVirtual=*/true); + } + + if (hasAccelUncalibrated) { + registerSensor(new LimitedAxesImuSensor(list, count, + SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED), + /*isDebug=*/false, /*isVirtual=*/true); + } + + if (hasGyroUncalibrated) { + registerSensor(new LimitedAxesImuSensor(list, count, + SENSOR_TYPE_GYROSCOPE_UNCALIBRATED), + /*isDebug=*/false, /*isVirtual=*/true); + } + } + // Check if the device really supports batching by looking at the FIFO event // counts for each sensor. bool batchingSupported = false; diff --git a/services/sensorservice/SensorServiceUtils.cpp b/services/sensorservice/SensorServiceUtils.cpp index baa01c9ce3..7dd23316b1 100644 --- a/services/sensorservice/SensorServiceUtils.cpp +++ b/services/sensorservice/SensorServiceUtils.cpp @@ -30,12 +30,18 @@ size_t eventSizeBySensorType(int type) { case SENSOR_TYPE_POSE_6DOF: return 16; + case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED: + case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED: + return 9; + case SENSOR_TYPE_ROTATION_VECTOR: case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR: return 5; case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED: case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: + case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES: + case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES: return 6; case SENSOR_TYPE_GAME_ROTATION_VECTOR: @@ -61,6 +67,9 @@ size_t eventSizeBySensorType(int type) { case SENSOR_TYPE_HEAD_TRACKER: return 7; + case SENSOR_TYPE_HEADING: + return 2; + default: return 3; } diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index b7e2ff3b34..18a6baeffe 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -319,7 +319,6 @@ bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) { Mutex::Autolock lock(mFrameEventHistoryMutex); mFrameEventHistory.addPreComposition(mCurrentFrameNumber, refreshStartTime); } - mRefreshPending = false; return hasReadyFrame(); } namespace { @@ -474,19 +473,6 @@ bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime, return refreshRequired; } - if (!hasReadyFrame()) { - return false; - } - - // if we've already called updateTexImage() without going through - // a composition step, we have to skip this layer at this point - // because we cannot call updateTeximage() without a corresponding - // compositionComplete() call. - // we'll trigger an update in onPreComposition(). - if (mRefreshPending) { - return false; - } - // If the head buffer's acquire fence hasn't signaled yet, return and // try again later if (!fenceHasSignaled()) { @@ -518,7 +504,6 @@ bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime, gatherBufferInfo(); - mRefreshPending = true; if (oldBufferInfo.mBuffer == nullptr) { // the first time we receive a buffer, we need to trigger a // geometry invalidation. @@ -689,7 +674,6 @@ FloatRect BufferLayer::computeSourceBounds(const FloatRect& parentBounds) const } void BufferLayer::latchAndReleaseBuffer() { - mRefreshPending = false; if (hasReadyFrame()) { bool ignored = false; latchBuffer(ignored, systemTime(), 0 /* expectedPresentTime */); diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index 99267be673..3e70493101 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -88,9 +88,6 @@ public: // to figure out if the content or size of a surface has changed. bool latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime, nsecs_t expectedPresentTime) override; - - bool isBufferLatched() const override { return mRefreshPending; } - bool hasReadyFrame() const override; // Returns the current scaling mode @@ -158,9 +155,6 @@ protected: // from graphics API const uint32_t mTextureName; - - bool mRefreshPending{false}; - ui::Dataspace translateDataspace(ui::Dataspace dataspace); void setInitialValuesForClone(const sp<Layer>& clonedFrom); void updateCloneBufferInfo() override; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h index 16aebef9f3..ee0c53ded7 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h @@ -26,8 +26,18 @@ namespace android::compositionengine::mock { // Defines the interface used by the CompositionEngine to make requests // of the front-end layer. class LayerFE : public compositionengine::LayerFE { -public: +private: + // Making the constructor private as this class implements RefBase, + // and constructing it with a different way than sp<LayerFE>::make() causes + // a memory leak of the shared state. LayerFE(); + + // friends class to allow instantiation via sp<LayerFE>::make() and + // sp<StrictMock<LayerFE>>::make() + friend class sp<LayerFE>; + friend class testing::StrictMock<LayerFE>; + +public: virtual ~LayerFE(); MOCK_CONST_METHOD0(getCompositionState, const LayerFECompositionState*()); diff --git a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp index 325361b45a..de9de0150d 100644 --- a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp @@ -203,9 +203,9 @@ TEST_F(CompositionEngineUpdateCursorAsyncTest, handlesMultipleLayersBeingCursorL */ struct CompositionTestPreComposition : public CompositionEngineTest { - sp<StrictMock<mock::LayerFE>> mLayer1FE{new StrictMock<mock::LayerFE>()}; - sp<StrictMock<mock::LayerFE>> mLayer2FE{new StrictMock<mock::LayerFE>()}; - sp<StrictMock<mock::LayerFE>> mLayer3FE{new StrictMock<mock::LayerFE>()}; + sp<StrictMock<mock::LayerFE>> mLayer1FE = sp<StrictMock<mock::LayerFE>>::make(); + sp<StrictMock<mock::LayerFE>> mLayer2FE = sp<StrictMock<mock::LayerFE>>::make(); + sp<StrictMock<mock::LayerFE>> mLayer3FE = sp<StrictMock<mock::LayerFE>>::make(); }; TEST_F(CompositionTestPreComposition, preCompositionSetsFrameTimestamp) { diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp index 03c6f8dd81..125ce7468e 100644 --- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp @@ -74,7 +74,7 @@ struct Layer { EXPECT_CALL(*outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer)); } - sp<mock::LayerFE> layerFE = new StrictMock<mock::LayerFE>(); + sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make(); StrictMock<mock::OutputLayer>* outputLayer = new StrictMock<mock::OutputLayer>(); StrictMock<HWC2::mock::Layer> hwc2Layer; }; @@ -85,7 +85,7 @@ struct LayerNoHWC2Layer { EXPECT_CALL(*outputLayer, getHwcLayer()).WillRepeatedly(Return(nullptr)); } - sp<mock::LayerFE> layerFE = new StrictMock<mock::LayerFE>(); + sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make(); StrictMock<mock::OutputLayer>* outputLayer = new StrictMock<mock::OutputLayer>(); }; @@ -469,7 +469,7 @@ TEST_F(DisplayCreateRenderSurfaceTest, setsRenderSurface) { using DisplayCreateOutputLayerTest = FullDisplayImplTestCommon; TEST_F(DisplayCreateOutputLayerTest, setsHwcLayer) { - sp<mock::LayerFE> layerFE = new StrictMock<mock::LayerFE>(); + sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make(); auto hwcLayer = std::make_shared<StrictMock<HWC2::mock::Layer>>(); EXPECT_CALL(mHwComposer, createLayer(HalDisplayId(DEFAULT_DISPLAY_ID))) diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp index 0b123b12d1..82dcc66833 100644 --- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp @@ -109,8 +109,8 @@ struct OutputLayerTest : public testing::Test { } compositionengine::mock::Output mOutput; - sp<compositionengine::mock::LayerFE> mLayerFE{ - new StrictMock<compositionengine::mock::LayerFE>()}; + sp<StrictMock<compositionengine::mock::LayerFE>> mLayerFE = + sp<StrictMock<compositionengine::mock::LayerFE>>::make(); OutputLayer mOutputLayer{mOutput, mLayerFE}; LayerFECompositionState mLayerFEState; diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp index f7d5991fef..e72bc9f66d 100644 --- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp @@ -106,7 +106,7 @@ struct InjectedLayer { } mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>}; - sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>(); + sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make(); LayerFECompositionState layerFEState; impl::OutputLayerCompositionState outputLayerState; }; @@ -123,7 +123,7 @@ struct NonInjectedLayer { } mock::OutputLayer outputLayer; - sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>(); + sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make(); LayerFECompositionState layerFEState; impl::OutputLayerCompositionState outputLayerState; }; @@ -722,9 +722,9 @@ TEST_F(OutputTest, getOutputLayerForLayerWorks) { using OutputSetReleasedLayersTest = OutputTest; TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) { - sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()}; - sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()}; - sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()}; + sp<StrictMock<mock::LayerFE>> layer1FE = sp<StrictMock<mock::LayerFE>>::make(); + sp<StrictMock<mock::LayerFE>> layer2FE = sp<StrictMock<mock::LayerFE>>::make(); + sp<StrictMock<mock::LayerFE>> layer3FE = sp<StrictMock<mock::LayerFE>>::make(); Output::ReleasedLayers layers; layers.push_back(layer1FE); @@ -1209,7 +1209,7 @@ struct OutputCollectVisibleLayersTest : public testing::Test { StrictMock<mock::OutputLayer> outputLayer; impl::OutputLayerCompositionState outputLayerState; - sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()}; + sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make(); }; OutputCollectVisibleLayersTest() { @@ -2987,9 +2987,9 @@ TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) { EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u)); // Load up the released layers with some mock instances - sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()}; - sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()}; - sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()}; + sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make(); + sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make(); + sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make(); Output::ReleasedLayers layers; layers.push_back(releasedLayer1); layers.push_back(releasedLayer2); diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp index 84b3fc5698..0b1c2626a1 100644 --- a/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp @@ -107,7 +107,7 @@ struct LayerStateTest : public testing::Test { EXPECT_EQ(fields, rhs.getDifferingFields(lhs)); } - mock::LayerFE mLayerFE; + sp<mock::LayerFE> mLayerFE = sp<mock::LayerFE>::make(); mock::OutputLayer mOutputLayer; std::unique_ptr<LayerState> mLayerState; }; @@ -115,7 +115,7 @@ struct LayerStateTest : public testing::Test { TEST_F(LayerStateTest, getOutputLayer) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); EXPECT_EQ(&mOutputLayer, mLayerState->getOutputLayer()); @@ -124,14 +124,14 @@ TEST_F(LayerStateTest, getOutputLayer) { TEST_F(LayerStateTest, updateOutputLayer) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); EXPECT_EQ(&mOutputLayer, mLayerState->getOutputLayer()); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState->update(&newOutputLayer); EXPECT_EQ(&newOutputLayer, mLayerState->getOutputLayer()); @@ -140,7 +140,7 @@ TEST_F(LayerStateTest, updateOutputLayer) { TEST_F(LayerStateTest, getId) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); EXPECT_EQ(sSequenceId, mLayerState->getId()); @@ -149,13 +149,13 @@ TEST_F(LayerStateTest, getId) { TEST_F(LayerStateTest, updateId) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionState, sSequenceIdTwo); Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer); EXPECT_EQ(sSequenceIdTwo, mLayerState->getId()); @@ -165,12 +165,12 @@ TEST_F(LayerStateTest, updateId) { TEST_F(LayerStateTest, compareId) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionState, sSequenceIdTwo); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -185,7 +185,7 @@ TEST_F(LayerStateTest, compareId) { TEST_F(LayerStateTest, getName) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); EXPECT_EQ(sDebugName, mLayerState->getName()); @@ -194,13 +194,13 @@ TEST_F(LayerStateTest, getName) { TEST_F(LayerStateTest, updateName) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionState, sSequenceId, sDebugNameTwo); Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer); EXPECT_EQ(sDebugNameTwo, mLayerState->getName()); @@ -210,12 +210,12 @@ TEST_F(LayerStateTest, updateName) { TEST_F(LayerStateTest, compareName) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionState, sSequenceId, sDebugNameTwo); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -231,7 +231,7 @@ TEST_F(LayerStateTest, getDisplayFrame) { OutputLayerCompositionState outputLayerCompositionState; outputLayerCompositionState.displayFrame = sRectOne; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); EXPECT_EQ(sRectOne, mLayerState->getDisplayFrame()); @@ -241,15 +241,15 @@ TEST_F(LayerStateTest, updateDisplayFrame) { OutputLayerCompositionState outputLayerCompositionState; outputLayerCompositionState.displayFrame = sRectOne; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo; outputLayerCompositionStateTwo.displayFrame = sRectTwo; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo, layerFECompositionState); Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer); EXPECT_EQ(sRectTwo, mLayerState->getDisplayFrame()); @@ -260,14 +260,14 @@ TEST_F(LayerStateTest, compareDisplayFrame) { OutputLayerCompositionState outputLayerCompositionState; outputLayerCompositionState.displayFrame = sRectOne; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo; outputLayerCompositionStateTwo.displayFrame = sRectTwo; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo, layerFECompositionState); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -282,7 +282,7 @@ TEST_F(LayerStateTest, getCompositionType) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.compositionType = Composition::DEVICE; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); EXPECT_EQ(Composition::DEVICE, mLayerState->getCompositionType()); @@ -293,7 +293,7 @@ TEST_F(LayerStateTest, getCompositionType_forcedClient) { outputLayerCompositionState.forceClientComposition = true; LayerFECompositionState layerFECompositionState; layerFECompositionState.compositionType = Composition::DEVICE; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); EXPECT_EQ(Composition::CLIENT, mLayerState->getCompositionType()); @@ -303,15 +303,15 @@ TEST_F(LayerStateTest, updateCompositionType) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.compositionType = Composition::DEVICE; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.compositionType = Composition::SOLID_COLOR; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer); EXPECT_EQ(Composition::SOLID_COLOR, mLayerState->getCompositionType()); @@ -322,14 +322,14 @@ TEST_F(LayerStateTest, compareCompositionType) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.compositionType = Composition::DEVICE; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.compositionType = Composition::SOLID_COLOR; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -345,15 +345,15 @@ TEST_F(LayerStateTest, updateBuffer) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.buffer = new GraphicBuffer(); - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.buffer = new GraphicBuffer(); - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer); EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Buffer), updates); @@ -363,14 +363,14 @@ TEST_F(LayerStateTest, compareBuffer) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.buffer = new GraphicBuffer(); - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.buffer = new GraphicBuffer(); - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -386,15 +386,15 @@ TEST_F(LayerStateTest, updateSourceCrop) { OutputLayerCompositionState outputLayerCompositionState; outputLayerCompositionState.sourceCrop = sFloatRectOne; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo; outputLayerCompositionStateTwo.sourceCrop = sFloatRectTwo; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo, layerFECompositionState); Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer); EXPECT_EQ(Flags<LayerStateField>(LayerStateField::SourceCrop), updates); @@ -404,14 +404,14 @@ TEST_F(LayerStateTest, compareSourceCrop) { OutputLayerCompositionState outputLayerCompositionState; outputLayerCompositionState.sourceCrop = sFloatRectOne; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo; outputLayerCompositionStateTwo.sourceCrop = sFloatRectTwo; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo, layerFECompositionState); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -425,15 +425,15 @@ TEST_F(LayerStateTest, updateBufferTransform) { OutputLayerCompositionState outputLayerCompositionState; outputLayerCompositionState.bufferTransform = Hwc2::Transform::FLIP_H; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo; outputLayerCompositionStateTwo.bufferTransform = Hwc2::Transform::FLIP_V; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo, layerFECompositionState); Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer); EXPECT_EQ(Flags<LayerStateField>(LayerStateField::BufferTransform), updates); @@ -443,14 +443,14 @@ TEST_F(LayerStateTest, compareBufferTransform) { OutputLayerCompositionState outputLayerCompositionState; outputLayerCompositionState.bufferTransform = Hwc2::Transform::FLIP_H; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo; outputLayerCompositionStateTwo.bufferTransform = Hwc2::Transform::FLIP_V; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo, layerFECompositionState); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -465,15 +465,15 @@ TEST_F(LayerStateTest, updateBlendMode) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.blendMode = hal::BlendMode::COVERAGE; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.blendMode = hal::BlendMode::PREMULTIPLIED; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer); EXPECT_EQ(Flags<LayerStateField>(LayerStateField::BlendMode), updates); @@ -483,14 +483,14 @@ TEST_F(LayerStateTest, compareBlendMode) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.blendMode = hal::BlendMode::COVERAGE; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.blendMode = hal::BlendMode::PREMULTIPLIED; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -504,15 +504,15 @@ TEST_F(LayerStateTest, updateAlpha) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.alpha = sAlphaOne; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.alpha = sAlphaTwo; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer); EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Alpha), updates); @@ -522,14 +522,14 @@ TEST_F(LayerStateTest, compareAlpha) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.alpha = sAlphaOne; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.alpha = sAlphaTwo; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -543,15 +543,15 @@ TEST_F(LayerStateTest, updateLayerMetadata) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.metadata[sMetadataKeyOne] = sMetadataValueOne; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.metadata[sMetadataKeyTwo] = sMetadataValueTwo; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer); EXPECT_EQ(Flags<LayerStateField>(LayerStateField::LayerMetadata), updates); @@ -561,14 +561,14 @@ TEST_F(LayerStateTest, compareLayerMetadata) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.metadata[sMetadataKeyOne] = sMetadataValueOne; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.metadata[sMetadataKeyTwo] = sMetadataValueTwo; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -582,7 +582,7 @@ TEST_F(LayerStateTest, getVisibleRegion) { OutputLayerCompositionState outputLayerCompositionState; outputLayerCompositionState.visibleRegion = sRegionOne; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); EXPECT_TRUE(mLayerState->getVisibleRegion().hasSameRects(sRegionOne)); @@ -592,15 +592,15 @@ TEST_F(LayerStateTest, updateVisibleRegion) { OutputLayerCompositionState outputLayerCompositionState; outputLayerCompositionState.visibleRegion = sRegionOne; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo; outputLayerCompositionStateTwo.visibleRegion = sRegionTwo; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo, layerFECompositionState); Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer); EXPECT_EQ(Flags<LayerStateField>(LayerStateField::VisibleRegion), updates); @@ -610,14 +610,14 @@ TEST_F(LayerStateTest, compareVisibleRegion) { OutputLayerCompositionState outputLayerCompositionState; outputLayerCompositionState.visibleRegion = sRegionOne; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo; outputLayerCompositionStateTwo.visibleRegion = sRegionTwo; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo, layerFECompositionState); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -631,15 +631,15 @@ TEST_F(LayerStateTest, updateDataspace) { OutputLayerCompositionState outputLayerCompositionState; outputLayerCompositionState.dataspace = ui::Dataspace::SRGB; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo; outputLayerCompositionStateTwo.dataspace = ui::Dataspace::DISPLAY_P3; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo, layerFECompositionState); Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer); EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Dataspace), updates); @@ -649,14 +649,14 @@ TEST_F(LayerStateTest, compareDataspace) { OutputLayerCompositionState outputLayerCompositionState; outputLayerCompositionState.dataspace = ui::Dataspace::SRGB; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo; outputLayerCompositionStateTwo.dataspace = ui::Dataspace::DISPLAY_P3; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo, layerFECompositionState); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -674,19 +674,19 @@ TEST_F(LayerStateTest, updatePixelFormat) { AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, "buffer1"); - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.buffer = new GraphicBuffer(1, 1, PIXEL_FORMAT_RGBX_8888, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, "buffer2"); - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer); EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Buffer) | @@ -702,18 +702,18 @@ TEST_F(LayerStateTest, comparePixelFormat) { AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, "buffer1"); - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.buffer = new GraphicBuffer(1, 1, PIXEL_FORMAT_RGBX_8888, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, "buffer2"); - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -729,16 +729,16 @@ TEST_F(LayerStateTest, updateColorTransform) { LayerFECompositionState layerFECompositionState; layerFECompositionState.colorTransformIsIdentity = true; layerFECompositionState.colorTransform = mat4(); - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.colorTransformIsIdentity = false; layerFECompositionStateTwo.colorTransform = sMat4One; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer); EXPECT_EQ(Flags<LayerStateField>(LayerStateField::ColorTransform), updates); @@ -749,15 +749,15 @@ TEST_F(LayerStateTest, compareColorTransform) { LayerFECompositionState layerFECompositionState; layerFECompositionState.colorTransformIsIdentity = true; layerFECompositionState.colorTransform = mat4(); - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.colorTransformIsIdentity = false; layerFECompositionStateTwo.colorTransform = sMat4One; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -771,15 +771,15 @@ TEST_F(LayerStateTest, updateSidebandStream) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.sidebandStream = NativeHandle::create(sFakeSidebandStreamOne, false); - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.sidebandStream = NativeHandle::create(sFakeSidebandStreamTwo, false); - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer); EXPECT_EQ(Flags<LayerStateField>(LayerStateField::SidebandStream), updates); @@ -789,14 +789,14 @@ TEST_F(LayerStateTest, compareSidebandStream) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.sidebandStream = NativeHandle::create(sFakeSidebandStreamOne, false); - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.sidebandStream = NativeHandle::create(sFakeSidebandStreamTwo, false); - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -810,15 +810,15 @@ TEST_F(LayerStateTest, updateSolidColor) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.color = sHalf4One; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.color = sHalf4Two; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer); EXPECT_EQ(Flags<LayerStateField>(LayerStateField::SolidColor), updates); @@ -828,14 +828,14 @@ TEST_F(LayerStateTest, compareSolidColor) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.color = sHalf4One; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.color = sHalf4Two; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -849,15 +849,15 @@ TEST_F(LayerStateTest, updateBackgroundBlur) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.backgroundBlurRadius = sBgBlurRadiusOne; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.backgroundBlurRadius = sBgBlurRadiusTwo; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer); EXPECT_EQ(Flags<LayerStateField>(LayerStateField::BackgroundBlurRadius), updates); @@ -867,14 +867,14 @@ TEST_F(LayerStateTest, compareBackgroundBlur) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.backgroundBlurRadius = sBgBlurRadiusOne; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.backgroundBlurRadius = sBgBlurRadiusTwo; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -889,15 +889,15 @@ TEST_F(LayerStateTest, updateBlurRegions) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.blurRegions.push_back(sBlurRegionOne); - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.blurRegions.push_back(sBlurRegionTwo); - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer); EXPECT_EQ(Flags<LayerStateField>(LayerStateField::BlurRegions), updates); @@ -907,14 +907,14 @@ TEST_F(LayerStateTest, compareBlurRegions) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.blurRegions.push_back(sBlurRegionOne); - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.blurRegions.push_back(sBlurRegionTwo); - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -927,7 +927,7 @@ TEST_F(LayerStateTest, compareBlurRegions) { TEST_F(LayerStateTest, hasBlurBehind_noBlur_returnsFalse) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); EXPECT_FALSE(mLayerState->hasBlurBehind()); @@ -937,7 +937,7 @@ TEST_F(LayerStateTest, hasBlurBehind_withBackgroundBlur_returnsTrue) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.backgroundBlurRadius = sBgBlurRadiusOne; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); EXPECT_TRUE(mLayerState->hasBlurBehind()); @@ -947,7 +947,7 @@ TEST_F(LayerStateTest, hasBlurBehind_withBlurRegion_returnsTrue) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.blurRegions.push_back(sBlurRegionOne); - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); EXPECT_TRUE(mLayerState->hasBlurBehind()); @@ -956,7 +956,7 @@ TEST_F(LayerStateTest, hasBlurBehind_withBlurRegion_returnsTrue) { TEST_F(LayerStateTest, dumpDoesNotCrash) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); std::string dump; @@ -967,7 +967,7 @@ TEST_F(LayerStateTest, dumpDoesNotCrash) { TEST_F(LayerStateTest, framesSinceBufferUpdate) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); @@ -982,14 +982,14 @@ TEST_F(LayerStateTest, getNonBufferHash_doesNotCommute) { OutputLayerCompositionState outputLayerCompositionState; outputLayerCompositionState.displayFrame = sRectOne; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo; outputLayerCompositionStateTwo.displayFrame = sRectTwo; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo, layerFECompositionState); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -1001,14 +1001,14 @@ TEST_F(LayerStateTest, getNonBufferHash_isIdempotent) { OutputLayerCompositionState outputLayerCompositionState; outputLayerCompositionState.displayFrame = sRectOne; LayerFECompositionState layerFECompositionState; - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo; outputLayerCompositionStateTwo.displayFrame = sRectTwo; - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo, layerFECompositionState); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); @@ -1020,15 +1020,15 @@ TEST_F(LayerStateTest, getNonBufferHash_filtersOutBuffers) { OutputLayerCompositionState outputLayerCompositionState; LayerFECompositionState layerFECompositionState; layerFECompositionState.buffer = new GraphicBuffer(); - setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState, layerFECompositionState); mLayerState = std::make_unique<LayerState>(&mOutputLayer); mock::OutputLayer newOutputLayer; - mock::LayerFE newLayerFE; + sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make(); LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.buffer = new GraphicBuffer(); - setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState, + setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState, layerFECompositionStateTwo); auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer); diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/PredictorTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/PredictorTest.cpp index 6038268a8c..68c72e0945 100644 --- a/services/surfaceflinger/CompositionEngine/tests/planner/PredictorTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/planner/PredictorTest.cpp @@ -73,26 +73,26 @@ struct LayerStackTest : public testing::Test { TEST_F(LayerStackTest, getApproximateMatch_doesNotMatchSizeDifferences) { mock::OutputLayer outputLayerOne; - mock::LayerFE layerFEOne; + sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateOne; LayerFECompositionState layerFECompositionStateOne; - setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne, + setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne, layerFECompositionStateOne); LayerState layerStateOne(&outputLayerOne); mock::OutputLayer outputLayerTwo; - mock::LayerFE layerFETwo; + sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo; LayerFECompositionState layerFECompositionStateTwo; - setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo, + setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo, layerFECompositionStateTwo); LayerState layerStateTwo(&outputLayerTwo); mock::OutputLayer outputLayerThree; - mock::LayerFE layerFEThree; + sp<mock::LayerFE> layerFEThree = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateThree; LayerFECompositionState layerFECompositionStateThree; - setupMocksForLayer(outputLayerThree, layerFEThree, outputLayerCompositionStateThree, + setupMocksForLayer(outputLayerThree, *layerFEThree, outputLayerCompositionStateThree, layerFECompositionStateThree); LayerState layerStateThree(&outputLayerThree); @@ -104,20 +104,20 @@ TEST_F(LayerStackTest, getApproximateMatch_doesNotMatchSizeDifferences) { TEST_F(LayerStackTest, getApproximateMatch_doesNotMatchDifferentCompositionTypes) { mock::OutputLayer outputLayerOne; - mock::LayerFE layerFEOne; + sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateOne; LayerFECompositionState layerFECompositionStateOne; layerFECompositionStateOne.compositionType = Composition::DEVICE; - setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne, + setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne, layerFECompositionStateOne); LayerState layerStateOne(&outputLayerOne); mock::OutputLayer outputLayerTwo; - mock::LayerFE layerFETwo; + sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo; LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.compositionType = Composition::SOLID_COLOR; - setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo, + setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo, layerFECompositionStateTwo); LayerState layerStateTwo(&outputLayerTwo); @@ -128,22 +128,22 @@ TEST_F(LayerStackTest, getApproximateMatch_doesNotMatchDifferentCompositionTypes TEST_F(LayerStackTest, getApproximateMatch_matchesSingleDifferenceInSingleLayer) { mock::OutputLayer outputLayerOne; - mock::LayerFE layerFEOne; + sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateOne{ .sourceCrop = sFloatRectOne, }; LayerFECompositionState layerFECompositionStateOne; - setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne, + setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne, layerFECompositionStateOne); LayerState layerStateOne(&outputLayerOne); mock::OutputLayer outputLayerTwo; - mock::LayerFE layerFETwo; + sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo{ .sourceCrop = sFloatRectTwo, }; LayerFECompositionState layerFECompositionStateTwo; - setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo, + setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo, layerFECompositionStateTwo); LayerState layerStateTwo(&outputLayerTwo); @@ -159,22 +159,22 @@ TEST_F(LayerStackTest, getApproximateMatch_matchesSingleDifferenceInSingleLayer) TEST_F(LayerStackTest, getApproximateMatch_matchesSingleDifferenceInMultiLayerStack) { mock::OutputLayer outputLayerOne; - mock::LayerFE layerFEOne; + sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateOne{ .sourceCrop = sFloatRectOne, }; LayerFECompositionState layerFECompositionStateOne; - setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne, + setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne, layerFECompositionStateOne); LayerState layerStateOne(&outputLayerOne); mock::OutputLayer outputLayerTwo; - mock::LayerFE layerFETwo; + sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo{ .sourceCrop = sFloatRectTwo, }; LayerFECompositionState layerFECompositionStateTwo; - setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo, + setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo, layerFECompositionStateTwo); LayerState layerStateTwo(&outputLayerTwo); @@ -190,7 +190,7 @@ TEST_F(LayerStackTest, getApproximateMatch_matchesSingleDifferenceInMultiLayerSt TEST_F(LayerStackTest, getApproximateMatch_doesNotMatchManyDifferences) { mock::OutputLayer outputLayerOne; - mock::LayerFE layerFEOne; + sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateOne{ .visibleRegion = sRegionOne, .displayFrame = sRectOne, @@ -201,12 +201,12 @@ TEST_F(LayerStackTest, getApproximateMatch_doesNotMatchManyDifferences) { layerFECompositionStateOne.alpha = sAlphaOne; layerFECompositionStateOne.colorTransformIsIdentity = true; layerFECompositionStateOne.blendMode = hal::BlendMode::NONE; - setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne, + setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne, layerFECompositionStateOne); LayerState layerStateOne(&outputLayerOne); mock::OutputLayer outputLayerTwo; - mock::LayerFE layerFETwo; + sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo{ .visibleRegion = sRegionTwo, .displayFrame = sRectTwo, @@ -218,7 +218,7 @@ TEST_F(LayerStackTest, getApproximateMatch_doesNotMatchManyDifferences) { layerFECompositionStateTwo.colorTransformIsIdentity = false; layerFECompositionStateTwo.colorTransform = sMat4One; layerFECompositionStateTwo.blendMode = hal::BlendMode::PREMULTIPLIED; - setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo, + setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo, layerFECompositionStateTwo); LayerState layerStateTwo(&outputLayerTwo); @@ -230,20 +230,20 @@ TEST_F(LayerStackTest, getApproximateMatch_doesNotMatchManyDifferences) { TEST_F(LayerStackTest, getApproximateMatch_exactMatchesSameBuffer) { sp<GraphicBuffer> buffer = new GraphicBuffer(); mock::OutputLayer outputLayerOne; - mock::LayerFE layerFEOne; + sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateOne; LayerFECompositionState layerFECompositionStateOne; layerFECompositionStateOne.buffer = buffer; - setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne, + setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne, layerFECompositionStateOne); LayerState layerStateOne(&outputLayerOne); mock::OutputLayer outputLayerTwo; - mock::LayerFE layerFETwo; + sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo; LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.buffer = buffer; - setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo, + setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo, layerFECompositionStateTwo); LayerState layerStateTwo(&outputLayerTwo); @@ -259,7 +259,7 @@ TEST_F(LayerStackTest, getApproximateMatch_exactMatchesSameBuffer) { TEST_F(LayerStackTest, getApproximateMatch_alwaysMatchesClientComposition) { mock::OutputLayer outputLayerOne; - mock::LayerFE layerFEOne; + sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateOne{ .visibleRegion = sRegionOne, .forceClientComposition = true, @@ -271,12 +271,12 @@ TEST_F(LayerStackTest, getApproximateMatch_alwaysMatchesClientComposition) { layerFECompositionStateOne.buffer = new GraphicBuffer(); layerFECompositionStateOne.alpha = sAlphaOne; layerFECompositionStateOne.colorTransformIsIdentity = true; - setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne, + setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne, layerFECompositionStateOne); LayerState layerStateOne(&outputLayerOne); mock::OutputLayer outputLayerTwo; - mock::LayerFE layerFETwo; + sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo{ .visibleRegion = sRegionTwo, .forceClientComposition = true, @@ -289,7 +289,7 @@ TEST_F(LayerStackTest, getApproximateMatch_alwaysMatchesClientComposition) { layerFECompositionStateTwo.alpha = sAlphaTwo; layerFECompositionStateTwo.colorTransformIsIdentity = false; layerFECompositionStateTwo.colorTransform = sMat4One; - setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo, + setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo, layerFECompositionStateTwo); LayerState layerStateTwo(&outputLayerTwo); @@ -305,24 +305,24 @@ TEST_F(LayerStackTest, getApproximateMatch_alwaysMatchesClientComposition) { TEST_F(LayerStackTest, getApproximateMatch_doesNotMatchMultipleApproximations) { mock::OutputLayer outputLayerOne; - mock::LayerFE layerFEOne; + sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateOne{ .sourceCrop = sFloatRectOne, }; LayerFECompositionState layerFECompositionStateOne; layerFECompositionStateOne.buffer = new GraphicBuffer(); - setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne, + setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne, layerFECompositionStateOne); LayerState layerStateOne(&outputLayerOne); mock::OutputLayer outputLayerTwo; - mock::LayerFE layerFETwo; + sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo{ .sourceCrop = sFloatRectTwo, }; LayerFECompositionState layerFECompositionStateTwo; layerFECompositionStateTwo.buffer = new GraphicBuffer(); - setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo, + setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo, layerFECompositionStateTwo); LayerState layerStateTwo(&outputLayerTwo); @@ -348,22 +348,22 @@ struct PredictionTest : public testing::Test { TEST_F(LayerStackTest, reorderingChangesNonBufferHash) { mock::OutputLayer outputLayerOne; - mock::LayerFE layerFEOne; + sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateOne{ .sourceCrop = sFloatRectOne, }; LayerFECompositionState layerFECompositionStateOne; - setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne, + setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne, layerFECompositionStateOne); LayerState layerStateOne(&outputLayerOne); mock::OutputLayer outputLayerTwo; - mock::LayerFE layerFETwo; + sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo{ .sourceCrop = sFloatRectTwo, }; LayerFECompositionState layerFECompositionStateTwo; - setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo, + setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo, layerFECompositionStateTwo); LayerState layerStateTwo(&outputLayerTwo); @@ -443,11 +443,11 @@ TEST_F(PredictorTest, getPredictedPlan_emptyLayersWithoutExactMatch_returnsNullo TEST_F(PredictorTest, getPredictedPlan_recordCandidateAndRetrieveExactMatch) { mock::OutputLayer outputLayerOne; - mock::LayerFE layerFEOne; + sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateOne; LayerFECompositionState layerFECompositionStateOne; layerFECompositionStateOne.compositionType = Composition::DEVICE; - setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne, + setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne, layerFECompositionStateOne); LayerState layerStateOne(&outputLayerOne); @@ -468,22 +468,22 @@ TEST_F(PredictorTest, getPredictedPlan_recordCandidateAndRetrieveExactMatch) { TEST_F(PredictorTest, getPredictedPlan_recordCandidateAndRetrieveApproximateMatch) { mock::OutputLayer outputLayerOne; - mock::LayerFE layerFEOne; + sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateOne{ .sourceCrop = sFloatRectOne, }; LayerFECompositionState layerFECompositionStateOne; - setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne, + setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne, layerFECompositionStateOne); LayerState layerStateOne(&outputLayerOne); mock::OutputLayer outputLayerTwo; - mock::LayerFE layerFETwo; + sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo{ .sourceCrop = sFloatRectTwo, }; LayerFECompositionState layerFECompositionStateTwo; - setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo, + setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo, layerFECompositionStateTwo); LayerState layerStateTwo(&outputLayerTwo); @@ -505,22 +505,22 @@ TEST_F(PredictorTest, getPredictedPlan_recordCandidateAndRetrieveApproximateMatc TEST_F(PredictorTest, recordMissedPlan_skipsApproximateMatch) { mock::OutputLayer outputLayerOne; - mock::LayerFE layerFEOne; + sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateOne{ .sourceCrop = sFloatRectOne, }; LayerFECompositionState layerFECompositionStateOne; - setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne, + setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne, layerFECompositionStateOne); LayerState layerStateOne(&outputLayerOne); mock::OutputLayer outputLayerTwo; - mock::LayerFE layerFETwo; + sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make(); OutputLayerCompositionState outputLayerCompositionStateTwo{ .sourceCrop = sFloatRectTwo, }; LayerFECompositionState layerFECompositionStateTwo; - setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo, + setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo, layerFECompositionStateTwo); LayerState layerStateTwo(&outputLayerTwo); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 645d4d1b44..a039250327 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1398,7 +1398,6 @@ LayerDebugInfo Layer::getLayerDebugInfo(const DisplayDevice* display) const { } } info.mNumQueuedFrames = getQueuedFrameCount(); - info.mRefreshPending = isBufferLatched(); info.mIsOpaque = isOpaque(ds); info.mContentDirty = contentDirty; info.mStretchEffect = getStretchEffect(); @@ -2029,7 +2028,6 @@ void Layer::writeToProtoDrawingState(LayerProto* layerInfo, uint32_t traceFlags, layerInfo->set_is_protected(isProtected()); layerInfo->set_dataspace(dataspaceDetails(static_cast<android_dataspace>(getDataSpace()))); layerInfo->set_queued_frames(getQueuedFrameCount()); - layerInfo->set_refresh_pending(isBufferLatched()); layerInfo->set_curr_frame(mCurrentFrameNumber); layerInfo->set_effective_scaling_mode(getEffectiveScalingMode()); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 605a27efa7..ddcd641461 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -549,8 +549,6 @@ public: return false; } - virtual bool isBufferLatched() const { return false; } - virtual void latchAndReleaseBuffer() {} /* diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp index ff30348151..e29e6ab05f 100644 --- a/services/surfaceflinger/RegionSamplingThread.cpp +++ b/services/surfaceflinger/RegionSamplingThread.cpp @@ -30,6 +30,7 @@ #include <compositionengine/impl/OutputCompositionState.h> #include <cutils/properties.h> #include <ftl/future.h> +#include <gui/SpHash.h> #include <gui/SyncScreenCaptureListener.h> #include <renderengine/impl/ExternalTexture.h> #include <ui/DisplayStatInfo.h> @@ -46,10 +47,7 @@ namespace android { using namespace std::chrono_literals; -template <typename T> -struct SpHash { - size_t operator()(const sp<T>& p) const { return std::hash<T*>()(p.get()); } -}; +using gui::SpHash; constexpr auto lumaSamplingStepTag = "LumaSamplingStep"; enum class samplingStep { diff --git a/services/surfaceflinger/Scheduler/DispSyncSource.cpp b/services/surfaceflinger/Scheduler/DispSyncSource.cpp index 50b38c9cf6..c593340625 100644 --- a/services/surfaceflinger/Scheduler/DispSyncSource.cpp +++ b/services/surfaceflinger/Scheduler/DispSyncSource.cpp @@ -180,7 +180,7 @@ void DispSyncSource::onVsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime } if (callback != nullptr) { - callback->onVSyncEvent(targetWakeupTime, vsyncTime, readyTime); + callback->onVSyncEvent(targetWakeupTime, {vsyncTime, readyTime}); } } diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp index 627c49a853..adc1009731 100644 --- a/services/surfaceflinger/Scheduler/EventThread.cpp +++ b/services/surfaceflinger/Scheduler/EventThread.cpp @@ -108,13 +108,12 @@ DisplayEventReceiver::Event makeHotplug(PhysicalDisplayId displayId, nsecs_t tim DisplayEventReceiver::Event makeVSync(PhysicalDisplayId displayId, nsecs_t timestamp, uint32_t count, nsecs_t expectedVSyncTimestamp, - nsecs_t deadlineTimestamp, int64_t vsyncId) { + nsecs_t deadlineTimestamp) { DisplayEventReceiver::Event event; event.header = {DisplayEventReceiver::DISPLAY_EVENT_VSYNC, displayId, timestamp}; event.vsync.count = count; event.vsync.expectedVSyncTimestamp = expectedVSyncTimestamp; event.vsync.deadlineTimestamp = deadlineTimestamp; - event.vsync.vsyncId = vsyncId; return event; } @@ -351,14 +350,13 @@ void EventThread::onScreenAcquired() { mCondition.notify_all(); } -void EventThread::onVSyncEvent(nsecs_t timestamp, nsecs_t expectedVSyncTimestamp, - nsecs_t deadlineTimestamp) { +void EventThread::onVSyncEvent(nsecs_t timestamp, VSyncSource::VSyncData vsyncData) { std::lock_guard<std::mutex> lock(mMutex); LOG_FATAL_IF(!mVSyncState); - const int64_t vsyncId = generateToken(timestamp, deadlineTimestamp, expectedVSyncTimestamp); mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count, - expectedVSyncTimestamp, deadlineTimestamp, vsyncId)); + vsyncData.expectedVSyncTimestamp, + vsyncData.deadlineTimestamp)); mCondition.notify_all(); } @@ -493,16 +491,9 @@ void EventThread::threadMain(std::unique_lock<std::mutex>& lock) { const auto now = systemTime(SYSTEM_TIME_MONOTONIC); const auto deadlineTimestamp = now + timeout.count(); const auto expectedVSyncTime = deadlineTimestamp + timeout.count(); - const int64_t vsyncId = [&] { - if (mTokenManager != nullptr) { - return mTokenManager->generateTokenForPredictions( - {now, deadlineTimestamp, expectedVSyncTime}); - } - return FrameTimelineInfo::INVALID_VSYNC_ID; - }(); mPendingEvents.push_back(makeVSync(mVSyncState->displayId, now, ++mVSyncState->count, expectedVSyncTime, - deadlineTimestamp, vsyncId)); + deadlineTimestamp)); } } } @@ -572,25 +563,20 @@ int64_t EventThread::generateToken(nsecs_t timestamp, nsecs_t deadlineTimestamp, void EventThread::generateFrameTimeline(DisplayEventReceiver::Event& event) const { // Add 1 to ensure the preferredFrameTimelineIndex entry (when multiplier == 0) is included. - for (int multiplier = -DisplayEventReceiver::kFrameTimelinesLength + 1, currentIndex = 0; - currentIndex < DisplayEventReceiver::kFrameTimelinesLength; multiplier++) { + for (int multiplier = -VsyncEventData::kFrameTimelinesLength + 1, currentIndex = 0; + currentIndex < VsyncEventData::kFrameTimelinesLength; multiplier++) { nsecs_t deadline = event.vsync.deadlineTimestamp + multiplier * event.vsync.frameInterval; // Valid possible frame timelines must have future values. if (deadline > event.header.timestamp) { if (multiplier == 0) { event.vsync.preferredFrameTimelineIndex = currentIndex; - event.vsync.frameTimelines[currentIndex] = - {.vsyncId = event.vsync.vsyncId, - .deadlineTimestamp = event.vsync.deadlineTimestamp, - .expectedVSyncTimestamp = event.vsync.expectedVSyncTimestamp}; - } else { - nsecs_t expectedVSync = - event.vsync.expectedVSyncTimestamp + multiplier * event.vsync.frameInterval; - event.vsync.frameTimelines[currentIndex] = - {.vsyncId = generateToken(event.header.timestamp, deadline, expectedVSync), - .deadlineTimestamp = deadline, - .expectedVSyncTimestamp = expectedVSync}; } + nsecs_t expectedVSync = + event.vsync.expectedVSyncTimestamp + multiplier * event.vsync.frameInterval; + event.vsync.frameTimelines[currentIndex] = + {.vsyncId = generateToken(event.header.timestamp, deadline, expectedVSync), + .deadlineTimestamp = deadline, + .expectedVSyncTimestamp = expectedVSync}; currentIndex++; } } diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h index fa9af098f6..c3b9129744 100644 --- a/services/surfaceflinger/Scheduler/EventThread.h +++ b/services/surfaceflinger/Scheduler/EventThread.h @@ -62,11 +62,16 @@ enum class VSyncRequest { class VSyncSource { public: + class VSyncData { + public: + nsecs_t expectedVSyncTimestamp; + nsecs_t deadlineTimestamp; + }; + class Callback { public: virtual ~Callback() {} - virtual void onVSyncEvent(nsecs_t when, nsecs_t expectedVSyncTimestamp, - nsecs_t deadlineTimestamp) = 0; + virtual void onVSyncEvent(nsecs_t when, VSyncData vsyncData) = 0; }; virtual ~VSyncSource() {} @@ -201,8 +206,7 @@ private: REQUIRES(mMutex); // Implements VSyncSource::Callback - void onVSyncEvent(nsecs_t timestamp, nsecs_t expectedVSyncTimestamp, - nsecs_t deadlineTimestamp) override; + void onVSyncEvent(nsecs_t timestamp, VSyncSource::VSyncData vsyncData) override; int64_t generateToken(nsecs_t timestamp, nsecs_t deadlineTimestamp, nsecs_t expectedVSyncTimestamp) const; diff --git a/services/surfaceflinger/Scheduler/InjectVSyncSource.h b/services/surfaceflinger/Scheduler/InjectVSyncSource.h index 016b076444..7b93f1eb13 100644 --- a/services/surfaceflinger/Scheduler/InjectVSyncSource.h +++ b/services/surfaceflinger/Scheduler/InjectVSyncSource.h @@ -39,7 +39,7 @@ public: nsecs_t deadlineTimestamp) { std::lock_guard<std::mutex> lock(mCallbackMutex); if (mCallback) { - mCallback->onVSyncEvent(when, expectedVSyncTimestamp, deadlineTimestamp); + mCallback->onVSyncEvent(when, {expectedVSyncTimestamp, deadlineTimestamp}); } } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 3459a8ff5b..5ccb5ebb8f 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3563,11 +3563,9 @@ bool SurfaceFlinger::latchBuffers() { for (const auto& layer : mLayersWithQueuedFrames) { if (layer->latchBuffer(visibleRegions, latchTime, expectedPresentTime)) { mLayersPendingRefresh.push_back(layer); - } - layer->useSurfaceDamage(); - if (layer->isBufferLatched()) { newDataLatched = true; } + layer->useSurfaceDamage(); } } @@ -3647,7 +3645,7 @@ bool SurfaceFlinger::flushTransactionQueues(int64_t vsyncId) { // states) around outside the scope of the lock std::vector<TransactionState> transactions; // Layer handles that have transactions with buffers that are ready to be applied. - std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>> bufferLayersReadyToPresent; + std::unordered_set<sp<IBinder>, SpHash<IBinder>> bufferLayersReadyToPresent; { Mutex::Autolock _l(mStateLock); { @@ -3736,7 +3734,7 @@ bool SurfaceFlinger::applyTransactions(std::vector<TransactionState>& transactio int64_t vsyncId) { bool needsTraversal = false; // Now apply all transactions. - for (const auto& transaction : transactions) { + for (auto& transaction : transactions) { needsTraversal |= applyTransactionState(transaction.frameTimelineInfo, transaction.states, transaction.displays, transaction.flags, @@ -3844,8 +3842,7 @@ bool SurfaceFlinger::frameIsEarly(nsecs_t expectedPresentTime, int64_t vsyncId) bool SurfaceFlinger::transactionIsReadyToBeApplied( const FrameTimelineInfo& info, bool isAutoTimestamp, int64_t desiredPresentTime, uid_t originUid, const Vector<ComposerState>& states, - const std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>>& - bufferLayersReadyToPresent, + const std::unordered_set<sp<IBinder>, SpHash<IBinder>>& bufferLayersReadyToPresent, bool allowLatchUnsignaled) const { ATRACE_FORMAT("transactionIsReadyToBeApplied vsyncId: %" PRId64, info.vsyncId); const nsecs_t expectedPresentTime = mExpectedPresentTime.load(); @@ -3915,7 +3912,8 @@ void SurfaceFlinger::queueTransaction(TransactionState& state) { // been applied by SF if (state.flags & eAnimation) { while (itr != mPendingTransactionQueues.end()) { - status_t err = mTransactionQueueCV.waitRelative(mQueueLock, s2ns(5)); + status_t err = + mTransactionQueueCV.waitRelative(mQueueLock, mAnimationTransactionTimeout); if (CC_UNLIKELY(err != NO_ERROR)) { ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out " @@ -3951,7 +3949,8 @@ void SurfaceFlinger::waitForSynchronousTransaction( // applyTransactionState is called on the main SF thread. While a given process may wish // to wait on synchronous transactions, the main SF thread should apply the transaction and // set the value to notify this after committed. - if (!transactionCommittedSignal.wait_until(std::chrono::seconds(5))) { + if (!transactionCommittedSignal.wait_until( + std::chrono::nanoseconds(mAnimationTransactionTimeout))) { ALOGE("setTransactionState timed out!"); } } @@ -4028,7 +4027,7 @@ status_t SurfaceFlinger::setTransactionState( } bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelineInfo, - const Vector<ComposerState>& states, + Vector<ComposerState>& states, const Vector<DisplayState>& displays, uint32_t flags, const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime, bool isAutoTimestamp, @@ -4050,9 +4049,9 @@ bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelin } uint32_t clientStateFlags = 0; - for (const ComposerState& state : states) { - ComposerState stateCopy = state; - clientStateFlags |= setClientStateLocked(frameTimelineInfo, stateCopy, desiredPresentTime, + for (int i = 0; i < states.size(); i++) { + ComposerState& state = states.editItemAt(i); + clientStateFlags |= setClientStateLocked(frameTimelineInfo, state, desiredPresentTime, isAutoTimestamp, postTime, permissions); if ((flags & eAnimation) && state.state.surface) { if (const auto layer = fromHandle(state.state.surface).promote()) { @@ -5508,7 +5507,13 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { } return PERMISSION_DENIED; } - case SET_OVERRIDE_FRAME_RATE: + case SET_OVERRIDE_FRAME_RATE: { + const int uid = IPCThreadState::self()->getCallingUid(); + if (uid == AID_ROOT || uid == AID_SYSTEM) { + return OK; + } + return PERMISSION_DENIED; + } case ON_PULL_ATOM: { const int uid = IPCThreadState::self()->getCallingUid(); if (uid == AID_SYSTEM) { @@ -6291,7 +6296,7 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, ui::Size reqSize; sp<Layer> parent; Rect crop(args.sourceCrop); - std::unordered_set<sp<Layer>, ISurfaceComposer::SpHash<Layer>> excludeLayers; + std::unordered_set<sp<Layer>, SpHash<Layer>> excludeLayers; ui::Dataspace dataspace; // Call this before holding mStateLock to avoid any deadlocking. diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index c6a4d8501d..b95cd9118a 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -714,7 +714,7 @@ private: /* * Transactions */ - bool applyTransactionState(const FrameTimelineInfo& info, const Vector<ComposerState>& state, + bool applyTransactionState(const FrameTimelineInfo& info, Vector<ComposerState>& state, const Vector<DisplayState>& displays, uint32_t flags, const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime, bool isAutoTimestamp, @@ -752,8 +752,7 @@ private: bool transactionIsReadyToBeApplied( const FrameTimelineInfo& info, bool isAutoTimestamp, int64_t desiredPresentTime, uid_t originUid, const Vector<ComposerState>& states, - const std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>>& - bufferLayersReadyToPresent, + const std::unordered_set<sp<IBinder>, SpHash<IBinder>>& bufferLayersReadyToPresent, bool allowLatchUnsignaled) const REQUIRES(mStateLock); static LatchUnsignaledConfig getLatchUnsignaledConfig(); bool latchUnsignaledIsAllowed(std::vector<TransactionState>& transactions) REQUIRES(mStateLock); @@ -1155,7 +1154,7 @@ private: // Tracks layers that have pending frames which are candidates for being // latched. - std::unordered_set<sp<Layer>, ISurfaceComposer::SpHash<Layer>> mLayersWithQueuedFrames; + std::unordered_set<sp<Layer>, SpHash<Layer>> mLayersWithQueuedFrames; // Tracks layers that need to update a display's dirty region. std::vector<sp<Layer>> mLayersPendingRefresh; std::array<FenceWithFenceTime, 2> mPreviousPresentFences; @@ -1372,6 +1371,8 @@ private: nsecs_t compositeStart; nsecs_t presentEnd; } mPowerHintSessionData GUARDED_BY(SF_MAIN_THREAD); + + nsecs_t mAnimationTransactionTimeout = s2ns(5); }; } // namespace android diff --git a/services/surfaceflinger/TransactionState.h b/services/surfaceflinger/TransactionState.h index fe3f3fcfd6..04ca347b2f 100644 --- a/services/surfaceflinger/TransactionState.h +++ b/services/surfaceflinger/TransactionState.h @@ -93,7 +93,7 @@ public: } // Return true if triggered. - bool wait_until(const std::chrono::seconds& timeout) const { + bool wait_until(const std::chrono::nanoseconds& timeout) const { std::unique_lock<std::mutex> lock(mMutex); const auto untilTime = std::chrono::system_clock::now() + timeout; while (mFlags != 0) { diff --git a/services/surfaceflinger/WindowInfosListenerInvoker.cpp b/services/surfaceflinger/WindowInfosListenerInvoker.cpp index 72434e943a..23cd99336a 100644 --- a/services/surfaceflinger/WindowInfosListenerInvoker.cpp +++ b/services/surfaceflinger/WindowInfosListenerInvoker.cpp @@ -67,8 +67,7 @@ void WindowInfosListenerInvoker::binderDied(const wp<IBinder>& who) { void WindowInfosListenerInvoker::windowInfosChanged(const std::vector<WindowInfo>& windowInfos, const std::vector<DisplayInfo>& displayInfos, bool shouldSync) { - std::unordered_set<sp<IWindowInfosListener>, ISurfaceComposer::SpHash<IWindowInfosListener>> - windowInfosListeners; + std::unordered_set<sp<IWindowInfosListener>, SpHash<IWindowInfosListener>> windowInfosListeners; { std::scoped_lock lock(mListenersMutex); diff --git a/services/surfaceflinger/fuzzer/Android.bp b/services/surfaceflinger/fuzzer/Android.bp index 0ead1631e7..b0d216e5cd 100644 --- a/services/surfaceflinger/fuzzer/Android.bp +++ b/services/surfaceflinger/fuzzer/Android.bp @@ -92,3 +92,13 @@ cc_fuzz { "android.hardware.graphics.composer@2.4-hal", ], } + +cc_fuzz { + name: "surfaceflinger_scheduler_fuzzer", + defaults: [ + "surfaceflinger_fuzz_defaults", + ], + srcs: [ + "surfaceflinger_scheduler_fuzzer.cpp", + ], +} diff --git a/services/surfaceflinger/fuzzer/README.md b/services/surfaceflinger/fuzzer/README.md index 4ecf770ca9..6231ca5536 100644 --- a/services/surfaceflinger/fuzzer/README.md +++ b/services/surfaceflinger/fuzzer/README.md @@ -2,6 +2,7 @@ ## Table of contents + [SurfaceFlinger](#SurfaceFlinger) + [DisplayHardware](#DisplayHardware) ++ [Scheduler](#Scheduler) # <a name="SurfaceFlinger"></a> Fuzzer for SurfaceFlinger @@ -51,3 +52,21 @@ You can find the possible values in the fuzzer's source code. $ adb sync data $ adb shell /data/fuzz/arm64/surfaceflinger_displayhardware_fuzzer/surfaceflinger_displayhardware_fuzzer ``` + +# <a name="Scheduler"></a> Fuzzer for Scheduler + +Scheduler supports the following parameters: +1. VSync Periods (parameter name: `lowFpsPeriod`) + +You can find the possible values in the fuzzer's source code. + +#### Steps to run +1. Build the fuzzer +``` + $ mm -j$(nproc) surfaceflinger_scheduler_fuzzer +``` +2. To run on device +``` + $ adb sync data + $ adb shell /data/fuzz/arm64/surfaceflinger_scheduler_fuzzer/surfaceflinger_scheduler_fuzzer +``` diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp new file mode 100644 index 0000000000..06bbfd26c2 --- /dev/null +++ b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp @@ -0,0 +1,391 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "surfaceflinger_scheduler_fuzzer.h" +#include <fuzzer/FuzzedDataProvider.h> +#include <processgroup/sched_policy.h> +#include "Scheduler/DispSyncSource.h" +#include "Scheduler/OneShotTimer.h" +#include "Scheduler/VSyncDispatchTimerQueue.h" +#include "Scheduler/VSyncPredictor.h" +#include "Scheduler/VSyncReactor.h" +#include "surfaceflinger_fuzzers_utils.h" + +namespace android::fuzz { + +using hardware::graphics::composer::hal::PowerMode; + +static constexpr PowerMode kPowerModes[] = {PowerMode::ON, PowerMode::DOZE, PowerMode::OFF, + PowerMode::DOZE_SUSPEND, PowerMode::ON_SUSPEND}; + +constexpr uint16_t kRandomStringLength = 256; +constexpr std::chrono::duration kSyncPeriod(16ms); + +template <typename T> +void dump(T* component, FuzzedDataProvider* fdp) { + std::string res = fdp->ConsumeRandomLengthString(kRandomStringLength); + component->dump(res); +} + +class SchedulerFuzzer : private VSyncSource::Callback { +public: + SchedulerFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){}; + void process(); + +private: + void fuzzRefreshRateSelection(); + void fuzzRefreshRateConfigs(); + void fuzzVSyncModulator(); + void fuzzVSyncPredictor(); + void fuzzVSyncReactor(); + void fuzzLayerHistory(); + void fuzzDispSyncSource(); + void fuzzCallbackToken(scheduler::VSyncDispatchTimerQueue* dispatch); + void fuzzVSyncDispatchTimerQueue(); + void fuzzOneShotTimer(); + void fuzzEventThread(); + PhysicalDisplayId getPhysicalDisplayId(); + + FuzzedDataProvider mFdp; + +protected: + void onVSyncEvent(nsecs_t /* when */, VSyncSource::VSyncData) {} +}; + +PhysicalDisplayId SchedulerFuzzer::getPhysicalDisplayId() { + PhysicalDisplayId internalDispId = PhysicalDisplayId::fromPort(111u); + PhysicalDisplayId externalDispId = PhysicalDisplayId::fromPort(222u); + PhysicalDisplayId randomDispId = PhysicalDisplayId::fromPort(mFdp.ConsumeIntegral<uint16_t>()); + PhysicalDisplayId dispId64Bit = PhysicalDisplayId::fromEdid(0xffu, 0xffffu, 0xffff'ffffu); + PhysicalDisplayId displayId = mFdp.PickValueInArray<PhysicalDisplayId>( + {internalDispId, externalDispId, dispId64Bit, randomDispId}); + return displayId; +} + +void SchedulerFuzzer::fuzzEventThread() { + const auto getVsyncPeriod = [](uid_t /* uid */) { return kSyncPeriod.count(); }; + std::unique_ptr<android::impl::EventThread> thread = std::make_unique< + android::impl::EventThread>(std::move(std::make_unique<FuzzImplVSyncSource>()), nullptr, + nullptr, nullptr, getVsyncPeriod); + + thread->onHotplugReceived(getPhysicalDisplayId(), mFdp.ConsumeBool()); + sp<EventThreadConnection> connection = + new EventThreadConnection(thread.get(), mFdp.ConsumeIntegral<uint16_t>(), nullptr, + {} /*eventRegistration*/); + thread->requestNextVsync(connection); + thread->setVsyncRate(mFdp.ConsumeIntegral<uint32_t>() /*rate*/, connection); + + thread->setDuration((std::chrono::nanoseconds)mFdp.ConsumeIntegral<uint64_t>(), + (std::chrono::nanoseconds)mFdp.ConsumeIntegral<uint64_t>()); + thread->registerDisplayEventConnection(connection); + thread->onScreenAcquired(); + thread->onScreenReleased(); + dump<android::impl::EventThread>(thread.get(), &mFdp); +} + +void SchedulerFuzzer::fuzzDispSyncSource() { + std::unique_ptr<FuzzImplVSyncDispatch> vSyncDispatch = + std::make_unique<FuzzImplVSyncDispatch>(); + std::unique_ptr<scheduler::DispSyncSource> dispSyncSource = std::make_unique< + scheduler::DispSyncSource>(*vSyncDispatch, + (std::chrono::nanoseconds) + mFdp.ConsumeIntegral<uint64_t>() /*workDuration*/, + (std::chrono::nanoseconds)mFdp.ConsumeIntegral<uint64_t>() + /*readyDuration*/, + mFdp.ConsumeBool(), + mFdp.ConsumeRandomLengthString(kRandomStringLength).c_str()); + dispSyncSource->setVSyncEnabled(true); + dispSyncSource->setCallback(this); + dispSyncSource->setDuration((std::chrono::nanoseconds)mFdp.ConsumeIntegral<uint64_t>(), 0ns); + dump<scheduler::DispSyncSource>(dispSyncSource.get(), &mFdp); +} + +void SchedulerFuzzer::fuzzCallbackToken(scheduler::VSyncDispatchTimerQueue* dispatch) { + scheduler::VSyncDispatch::CallbackToken tmp = dispatch->registerCallback( + [&](auto, auto, auto) { + dispatch->schedule(tmp, + {.workDuration = mFdp.ConsumeIntegral<nsecs_t>(), + .readyDuration = mFdp.ConsumeIntegral<nsecs_t>(), + .earliestVsync = mFdp.ConsumeIntegral<nsecs_t>()}); + }, + "o.o"); + dispatch->schedule(tmp, + {.workDuration = mFdp.ConsumeIntegral<nsecs_t>(), + .readyDuration = mFdp.ConsumeIntegral<nsecs_t>(), + .earliestVsync = mFdp.ConsumeIntegral<nsecs_t>()}); + dispatch->unregisterCallback(tmp); + dispatch->cancel(tmp); +} + +void SchedulerFuzzer::fuzzVSyncDispatchTimerQueue() { + FuzzImplVSyncTracker stubTracker{mFdp.ConsumeIntegral<nsecs_t>()}; + scheduler::VSyncDispatchTimerQueue + mDispatch{std::make_unique<scheduler::ControllableClock>(), stubTracker, + mFdp.ConsumeIntegral<nsecs_t>() /*dispatchGroupThreshold*/, + mFdp.ConsumeIntegral<nsecs_t>() /*vSyncMoveThreshold*/}; + + fuzzCallbackToken(&mDispatch); + + dump<scheduler::VSyncDispatchTimerQueue>(&mDispatch, &mFdp); + + scheduler::VSyncDispatchTimerQueueEntry entry( + "fuzz", [](auto, auto, auto) {}, + mFdp.ConsumeIntegral<nsecs_t>() /*vSyncMoveThreshold*/); + entry.update(stubTracker, 0); + entry.schedule({.workDuration = mFdp.ConsumeIntegral<nsecs_t>(), + .readyDuration = mFdp.ConsumeIntegral<nsecs_t>(), + .earliestVsync = mFdp.ConsumeIntegral<nsecs_t>()}, + stubTracker, 0); + entry.disarm(); + entry.ensureNotRunning(); + entry.schedule({.workDuration = mFdp.ConsumeIntegral<nsecs_t>(), + .readyDuration = mFdp.ConsumeIntegral<nsecs_t>(), + .earliestVsync = mFdp.ConsumeIntegral<nsecs_t>()}, + stubTracker, 0); + auto const wakeup = entry.wakeupTime(); + auto const ready = entry.readyTime(); + entry.callback(entry.executing(), *wakeup, *ready); + entry.addPendingWorkloadUpdate({.workDuration = mFdp.ConsumeIntegral<nsecs_t>(), + .readyDuration = mFdp.ConsumeIntegral<nsecs_t>(), + .earliestVsync = mFdp.ConsumeIntegral<nsecs_t>()}); + dump<scheduler::VSyncDispatchTimerQueueEntry>(&entry, &mFdp); +} + +void SchedulerFuzzer::fuzzVSyncPredictor() { + uint16_t now = mFdp.ConsumeIntegral<uint16_t>(); + uint16_t historySize = mFdp.ConsumeIntegralInRange<uint16_t>(1, UINT16_MAX); + uint16_t minimumSamplesForPrediction = mFdp.ConsumeIntegralInRange<uint16_t>(1, UINT16_MAX); + scheduler::VSyncPredictor tracker{mFdp.ConsumeIntegral<uint16_t>() /*period*/, historySize, + minimumSamplesForPrediction, + mFdp.ConsumeIntegral<uint32_t>() /*outlierTolerancePercent*/}; + uint16_t period = mFdp.ConsumeIntegral<uint16_t>(); + tracker.setPeriod(period); + for (uint16_t i = 0; i < minimumSamplesForPrediction; ++i) { + if (!tracker.needsMoreSamples()) { + break; + } + tracker.addVsyncTimestamp(now += period); + } + tracker.nextAnticipatedVSyncTimeFrom(now); + tracker.resetModel(); +} + +void SchedulerFuzzer::fuzzOneShotTimer() { + FakeClock* clock = new FakeClock(); + std::unique_ptr<scheduler::OneShotTimer> idleTimer = std::make_unique<scheduler::OneShotTimer>( + mFdp.ConsumeRandomLengthString(kRandomStringLength) /*name*/, + (std::chrono::milliseconds)mFdp.ConsumeIntegral<uint8_t>() /*val*/, + [] {} /*resetCallback*/, [] {} /*timeoutCallback*/, std::unique_ptr<FakeClock>(clock)); + idleTimer->start(); + idleTimer->reset(); + idleTimer->stop(); +} + +void SchedulerFuzzer::fuzzLayerHistory() { + TestableSurfaceFlinger flinger; + flinger.setupScheduler(std::make_unique<android::mock::VsyncController>(), + std::make_unique<android::mock::VSyncTracker>(), + std::make_unique<android::mock::EventThread>(), + std::make_unique<android::mock::EventThread>()); + flinger.setupTimeStats(std::make_unique<android::mock::TimeStats>()); + std::unique_ptr<android::renderengine::RenderEngine> renderEngine = + std::make_unique<android::renderengine::mock::RenderEngine>(); + flinger.setupRenderEngine(std::move(renderEngine)); + flinger.setupComposer(std::make_unique<android::Hwc2::mock::Composer>()); + + scheduler::TestableScheduler* scheduler = flinger.scheduler(); + + scheduler::LayerHistory& historyV1 = scheduler->mutableLayerHistory(); + nsecs_t time1 = systemTime(); + nsecs_t time2 = time1; + uint8_t historySize = mFdp.ConsumeIntegral<uint8_t>(); + + sp<FuzzImplLayer> layer1 = new FuzzImplLayer(flinger.flinger()); + sp<FuzzImplLayer> layer2 = new FuzzImplLayer(flinger.flinger()); + + for (int i = 0; i < historySize; ++i) { + historyV1.record(layer1.get(), time1, time1, + scheduler::LayerHistory::LayerUpdateType::Buffer); + historyV1.record(layer2.get(), time2, time2, + scheduler::LayerHistory::LayerUpdateType::Buffer); + time1 += mFdp.PickValueInArray(kVsyncPeriods); + time2 += mFdp.PickValueInArray(kVsyncPeriods); + } + historyV1.summarize(*scheduler->refreshRateConfigs(), time1); + historyV1.summarize(*scheduler->refreshRateConfigs(), time2); + + scheduler->createConnection(std::make_unique<android::mock::EventThread>()); + + scheduler::ConnectionHandle handle; + scheduler->createDisplayEventConnection(handle); + scheduler->setDuration(handle, (std::chrono::nanoseconds)mFdp.ConsumeIntegral<uint64_t>(), + (std::chrono::nanoseconds)mFdp.ConsumeIntegral<uint64_t>()); + + dump<scheduler::TestableScheduler>(scheduler, &mFdp); +} + +void SchedulerFuzzer::fuzzVSyncReactor() { + std::shared_ptr<FuzzImplVSyncTracker> vSyncTracker = std::make_shared<FuzzImplVSyncTracker>(); + scheduler::VSyncReactor reactor(std::make_unique<ClockWrapper>( + std::make_shared<FuzzImplClock>()), + *vSyncTracker, mFdp.ConsumeIntegral<uint8_t>() /*pendingLimit*/, + false); + + reactor.startPeriodTransition(mFdp.ConsumeIntegral<nsecs_t>()); + bool periodFlushed = mFdp.ConsumeBool(); + reactor.addHwVsyncTimestamp(0, std::nullopt, &periodFlushed); + reactor.addHwVsyncTimestamp(mFdp.ConsumeIntegral<nsecs_t>() /*newPeriod*/, std::nullopt, + &periodFlushed); + sp<Fence> fence = new Fence(memfd_create("fd", MFD_ALLOW_SEALING)); + std::shared_ptr<FenceTime> ft = std::make_shared<FenceTime>(fence); + vSyncTracker->addVsyncTimestamp(mFdp.ConsumeIntegral<nsecs_t>()); + FenceTime::Snapshot snap(mFdp.ConsumeIntegral<nsecs_t>()); + ft->applyTrustedSnapshot(snap); + reactor.setIgnorePresentFences(mFdp.ConsumeBool()); + reactor.addPresentFence(ft); + dump<scheduler::VSyncReactor>(&reactor, &mFdp); +} + +void SchedulerFuzzer::fuzzVSyncModulator() { + enum { + SF_OFFSET_LATE, + APP_OFFSET_LATE, + SF_DURATION_LATE, + APP_DURATION_LATE, + SF_OFFSET_EARLY, + APP_OFFSET_EARLY, + SF_DURATION_EARLY, + APP_DURATION_EARLY, + SF_OFFSET_EARLY_GPU, + APP_OFFSET_EARLY_GPU, + SF_DURATION_EARLY_GPU, + APP_DURATION_EARLY_GPU, + HWC_MIN_WORK_DURATION, + }; + using Schedule = scheduler::TransactionSchedule; + using nanos = std::chrono::nanoseconds; + using VsyncModulator = scheduler::VsyncModulator; + using FuzzImplVsyncModulator = scheduler::FuzzImplVsyncModulator; + const VsyncModulator::VsyncConfig early{SF_OFFSET_EARLY, APP_OFFSET_EARLY, + nanos(SF_DURATION_LATE), nanos(APP_DURATION_LATE)}; + const VsyncModulator::VsyncConfig earlyGpu{SF_OFFSET_EARLY_GPU, APP_OFFSET_EARLY_GPU, + nanos(SF_DURATION_EARLY), nanos(APP_DURATION_EARLY)}; + const VsyncModulator::VsyncConfig late{SF_OFFSET_LATE, APP_OFFSET_LATE, + nanos(SF_DURATION_EARLY_GPU), + nanos(APP_DURATION_EARLY_GPU)}; + const VsyncModulator::VsyncConfigSet offsets = {early, earlyGpu, late, + nanos(HWC_MIN_WORK_DURATION)}; + sp<FuzzImplVsyncModulator> vSyncModulator = + sp<FuzzImplVsyncModulator>::make(offsets, scheduler::Now); + (void)vSyncModulator->setVsyncConfigSet(offsets); + (void)vSyncModulator->setTransactionSchedule(Schedule::Late); + const auto token = sp<BBinder>::make(); + (void)vSyncModulator->setTransactionSchedule(Schedule::EarlyStart, token); + vSyncModulator->binderDied(token); +} + +void SchedulerFuzzer::fuzzRefreshRateSelection() { + TestableSurfaceFlinger flinger; + flinger.setupScheduler(std::make_unique<android::mock::VsyncController>(), + std::make_unique<android::mock::VSyncTracker>(), + std::make_unique<android::mock::EventThread>(), + std::make_unique<android::mock::EventThread>()); + + sp<Client> client; + LayerCreationArgs args(flinger.flinger(), client, + mFdp.ConsumeRandomLengthString(kRandomStringLength) /*name*/, + mFdp.ConsumeIntegral<uint16_t>() /*layerFlags*/, LayerMetadata()); + sp<Layer> layer = new BufferQueueLayer(args); + + layer->setFrameRateSelectionPriority(mFdp.ConsumeIntegral<int16_t>()); +} + +void SchedulerFuzzer::fuzzRefreshRateConfigs() { + using RefreshRateConfigs = scheduler::RefreshRateConfigs; + using LayerRequirement = RefreshRateConfigs::LayerRequirement; + using RefreshRateStats = scheduler::RefreshRateStats; + uint16_t minRefreshRate = mFdp.ConsumeIntegralInRange<uint16_t>(1, UINT16_MAX >> 1); + uint16_t maxRefreshRate = mFdp.ConsumeIntegralInRange<uint16_t>(minRefreshRate + 1, UINT16_MAX); + + DisplayModeId hwcConfigIndexType = DisplayModeId(mFdp.ConsumeIntegralInRange<uint8_t>(0, 10)); + + DisplayModes displayModes; + for (uint16_t fps = minRefreshRate; fps < maxRefreshRate; ++fps) { + constexpr int32_t kGroup = 0; + const auto refreshRate = Fps::fromValue(static_cast<float>(fps)); + displayModes.push_back(scheduler::createDisplayMode(hwcConfigIndexType, kGroup, + refreshRate.getPeriodNsecs())); + } + auto refreshRateConfigs = + std::make_unique<RefreshRateConfigs>(displayModes, hwcConfigIndexType); + const RefreshRateConfigs::GlobalSignals globalSignals = {.touch = false, .idle = false}; + auto layers = std::vector<LayerRequirement>{ + LayerRequirement{.weight = mFdp.ConsumeFloatingPoint<float>()}}; + refreshRateConfigs->getBestRefreshRate(layers, globalSignals); + layers[0].name = mFdp.ConsumeRandomLengthString(kRandomStringLength); + layers[0].ownerUid = mFdp.ConsumeIntegral<uint16_t>(); + layers[0].desiredRefreshRate = Fps::fromValue(mFdp.ConsumeFloatingPoint<float>()); + layers[0].vote = mFdp.PickValueInArray(kLayerVoteTypes); + auto frameRateOverrides = + refreshRateConfigs->getFrameRateOverrides(layers, + Fps::fromValue( + mFdp.ConsumeFloatingPoint<float>()), + globalSignals); + + refreshRateConfigs->setDisplayManagerPolicy( + {hwcConfigIndexType, + {Fps::fromValue(mFdp.ConsumeFloatingPoint<float>()), + Fps::fromValue(mFdp.ConsumeFloatingPoint<float>())}}); + refreshRateConfigs->setCurrentModeId(hwcConfigIndexType); + + RefreshRateConfigs::isFractionalPairOrMultiple(Fps::fromValue( + mFdp.ConsumeFloatingPoint<float>()), + Fps::fromValue( + mFdp.ConsumeFloatingPoint<float>())); + RefreshRateConfigs::getFrameRateDivider(Fps::fromValue(mFdp.ConsumeFloatingPoint<float>()), + Fps::fromValue(mFdp.ConsumeFloatingPoint<float>())); + + android::mock::TimeStats timeStats; + std::unique_ptr<RefreshRateStats> refreshRateStats = + std::make_unique<RefreshRateStats>(timeStats, + Fps::fromValue(mFdp.ConsumeFloatingPoint<float>()), + PowerMode::OFF); + refreshRateStats->setRefreshRate( + refreshRateConfigs->getRefreshRateFromModeId(hwcConfigIndexType).getFps()); + refreshRateStats->setPowerMode(mFdp.PickValueInArray(kPowerModes)); +} + +void SchedulerFuzzer::process() { + fuzzRefreshRateSelection(); + fuzzRefreshRateConfigs(); + fuzzVSyncModulator(); + fuzzVSyncPredictor(); + fuzzVSyncReactor(); + fuzzLayerHistory(); + fuzzDispSyncSource(); + fuzzEventThread(); + fuzzVSyncDispatchTimerQueue(); + fuzzOneShotTimer(); +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + SchedulerFuzzer schedulerFuzzer(data, size); + schedulerFuzzer.process(); + return 0; +} + +} // namespace android::fuzz diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h new file mode 100644 index 0000000000..89cf819614 --- /dev/null +++ b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h @@ -0,0 +1,229 @@ +/* + * Copyright 2021 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. + * + */ + +/* + Reference for some of the classes and functions has been taken from unittests + present in frameworks/native/services/surfaceflinger/tests/unittests +*/ + +#pragma once + +#include "Clock.h" +#include "Layer.h" +#include "Scheduler/EventThread.h" +#include "Scheduler/RefreshRateConfigs.h" +#include "Scheduler/Scheduler.h" +#include "Scheduler/VSyncTracker.h" +#include "Scheduler/VsyncModulator.h" +#include "scheduler/TimeKeeper.h" + +namespace android::fuzz { + +constexpr int64_t kVsyncPeriods[] = {static_cast<int64_t>(1e9f / 30), + static_cast<int64_t>(1e9f / 60), + static_cast<int64_t>(1e9f / 72), + static_cast<int64_t>(1e9f / 90), + static_cast<int64_t>(1e9f / 120)}; + +android::scheduler::RefreshRateConfigs::LayerVoteType kLayerVoteTypes[] = + {android::scheduler::RefreshRateConfigs::LayerVoteType::NoVote, + android::scheduler::RefreshRateConfigs::LayerVoteType::Min, + android::scheduler::RefreshRateConfigs::LayerVoteType::Max, + android::scheduler::RefreshRateConfigs::LayerVoteType::Heuristic, + android::scheduler::RefreshRateConfigs::LayerVoteType::ExplicitDefault, + android::scheduler::RefreshRateConfigs::LayerVoteType::ExplicitExactOrMultiple}; + +class FuzzImplClock : public android::scheduler::Clock { +public: + nsecs_t now() const { return 1; } +}; + +class ClockWrapper : public android::scheduler::Clock { +public: + ClockWrapper(std::shared_ptr<android::scheduler::Clock> const& clock) : mClock(clock) {} + + nsecs_t now() const { return mClock->now(); } + +private: + std::shared_ptr<android::scheduler::Clock> const mClock; +}; + +} // namespace android::fuzz + +namespace android { + +using namespace std::chrono_literals; + +class FakeClock : public Clock { +public: + virtual ~FakeClock() = default; + std::chrono::steady_clock::time_point now() const override { return mNow; } + + void advanceTime(std::chrono::nanoseconds delta) { mNow += delta; } + +private: + std::chrono::steady_clock::time_point mNow; +}; + +class FuzzImplLayer : public Layer { +public: + FuzzImplLayer(SurfaceFlinger* flinger, std::string name) + : Layer(LayerCreationArgs(flinger, nullptr, std::move(name), 0, {})) {} + explicit FuzzImplLayer(SurfaceFlinger* flinger) : FuzzImplLayer(flinger, "FuzzLayer") {} + + const char* getType() const override { return ""; } + + bool isVisible() const override { return true; } + + sp<Layer> createClone() override { return nullptr; } +}; + +class FuzzImplVSyncSource : public VSyncSource { +public: + const char* getName() const override { return "fuzz"; } + + void setVSyncEnabled(bool /* enable */) override {} + + void setCallback(Callback* /* callback */) override {} + + void setDuration(std::chrono::nanoseconds /* workDuration */, + std::chrono::nanoseconds /* readyDuration */) override {} + + void dump(std::string& /* result */) const override {} +}; + +class FuzzImplVSyncTracker : public scheduler::VSyncTracker { +public: + FuzzImplVSyncTracker(nsecs_t period) { mPeriod = period; } + + FuzzImplVSyncTracker() = default; + + bool addVsyncTimestamp(nsecs_t /* timestamp */) override { return true; } + + nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t /* timePoint */) const override { return 1; } + + nsecs_t currentPeriod() const override { return 1; } + + void setPeriod(nsecs_t /* period */) override {} + + void resetModel() override {} + + bool needsMoreSamples() const override { return true; } + + bool isVSyncInPhase(nsecs_t /* timePoint */, Fps /* frameRate */) const override { + return true; + } + + nsecs_t nextVSyncTime(nsecs_t timePoint) const { + if (timePoint % mPeriod == 0) { + return timePoint; + } + return (timePoint - (timePoint % mPeriod) + mPeriod); + } + + void dump(std::string& /* result */) const override {} + +protected: + nsecs_t mPeriod; +}; + +class FuzzImplVSyncDispatch : public scheduler::VSyncDispatch { +public: + CallbackToken registerCallback(Callback /* callbackFn */, + std::string /* callbackName */) override { + return CallbackToken{}; + } + + void unregisterCallback(CallbackToken /* token */) override {} + + scheduler::ScheduleResult schedule(CallbackToken /* token */, + ScheduleTiming /* scheduleTiming */) override { + return (scheduler::ScheduleResult)0; + } + + scheduler::CancelResult cancel(CallbackToken /* token */) override { + return (scheduler::CancelResult)0; + } + + void dump(std::string& /* result */) const override {} +}; + +} // namespace android + +namespace android::scheduler { + +DisplayModePtr createDisplayMode(DisplayModeId modeId, int32_t group, int64_t vsyncPeriod, + ui::Size resolution = ui::Size()) { + return DisplayMode::Builder(hal::HWConfigId(modeId.value())) + .setId(modeId) + .setPhysicalDisplayId(PhysicalDisplayId::fromPort(0)) + .setVsyncPeriod(int32_t(vsyncPeriod)) + .setGroup(group) + .setHeight(resolution.height) + .setWidth(resolution.width) + .build(); +} + +class ControllableClock : public TimeKeeper { +public: + nsecs_t now() const { return 1; }; + void alarmAt(std::function<void()> /* callback */, nsecs_t /* time */) override {} + void alarmCancel() override {} + void dump(std::string& /* result */) const override {} + + void alarmAtDefaultBehavior(std::function<void()> const& callback, nsecs_t time) { + mCallback = callback; + mNextCallbackTime = time; + } + + nsecs_t fakeTime() const { return mCurrentTime; } + + void advanceToNextCallback() { + mCurrentTime = mNextCallbackTime; + if (mCallback) { + mCallback(); + } + } + + void advanceBy(nsecs_t advancement) { + mCurrentTime += advancement; + if (mCurrentTime >= (mNextCallbackTime + mLag) && mCallback) { + mCallback(); + } + }; + + void setLag(nsecs_t lag) { mLag = lag; } + +private: + std::function<void()> mCallback; + nsecs_t mNextCallbackTime = 0; + nsecs_t mCurrentTime = 0; + nsecs_t mLag = 0; +}; + +static VsyncModulator::TimePoint Now() { + static VsyncModulator::TimePoint now; + return now += VsyncModulator::MIN_EARLY_TRANSACTION_TIME; +} + +class FuzzImplVsyncModulator : public VsyncModulator { +public: + FuzzImplVsyncModulator(const VsyncConfigSet& config, Now now) : VsyncModulator(config, now) {} + + void binderDied(const wp<IBinder>& token) { VsyncModulator::binderDied(token); } +}; +} // namespace android::scheduler diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp index 2841f7c2fd..854084e7f9 100644 --- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp +++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp @@ -305,7 +305,7 @@ std::string LayerProtoParser::Layer::to_string() const { zOrderRelativeOf == nullptr ? "none" : zOrderRelativeOf->name.c_str()); StringAppendF(&result, " activeBuffer=%s,", activeBuffer.to_string().c_str()); StringAppendF(&result, " tr=%s", bufferTransform.to_string().c_str()); - StringAppendF(&result, " queued-frames=%d, mRefreshPending=%d,", queuedFrames, refreshPending); + StringAppendF(&result, " queued-frames=%d", queuedFrames); StringAppendF(&result, " metadata={"); bool first = true; for (const auto& entry : metadata.mMap) { diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp index 7b86229556..c5c0c3f788 100644 --- a/services/surfaceflinger/tests/Android.bp +++ b/services/surfaceflinger/tests/Android.bp @@ -47,6 +47,7 @@ cc_test { "ReleaseBufferCallback_test.cpp", "ScreenCapture_test.cpp", "SetFrameRate_test.cpp", + "SetFrameRateOverride_test.cpp", "SetGeometry_test.cpp", "Stress_test.cpp", "SurfaceInterceptor_test.cpp", diff --git a/services/surfaceflinger/tests/SetFrameRateOverride_test.cpp b/services/surfaceflinger/tests/SetFrameRateOverride_test.cpp new file mode 100644 index 0000000000..4efec7738a --- /dev/null +++ b/services/surfaceflinger/tests/SetFrameRateOverride_test.cpp @@ -0,0 +1,98 @@ +/* + * 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. + */ + +#include <gtest/gtest.h> +#include <gui/DisplayEventReceiver.h> +#include <gui/ISurfaceComposer.h> +#include <gui/SurfaceComposerClient.h> +#include <sys/epoll.h> +#include <algorithm> + +namespace android { +namespace { +using FrameRateOverride = DisplayEventReceiver::Event::FrameRateOverride; + +class SetFrameRateOverrideTest : public ::testing::Test { +protected: + void SetUp() override { + const ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp; + const ISurfaceComposer::EventRegistrationFlags eventRegistration = { + ISurfaceComposer::EventRegistration::frameRateOverride}; + + mDisplayEventReceiver = + std::make_unique<DisplayEventReceiver>(vsyncSource, eventRegistration); + EXPECT_EQ(NO_ERROR, mDisplayEventReceiver->initCheck()); + + mEpollFd = epoll_create1(EPOLL_CLOEXEC); + EXPECT_GT(mEpollFd, 1); + + epoll_event event; + event.events = EPOLLIN; + EXPECT_EQ(0, epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mDisplayEventReceiver->getFd(), &event)); + } + + void TearDown() override { close(mEpollFd); } + + void setFrameRateAndListenEvents(uid_t uid, float frameRate) { + status_t ret = SurfaceComposerClient::setOverrideFrameRate(uid, frameRate); + ASSERT_EQ(NO_ERROR, ret); + + DisplayEventReceiver::Event event; + bool isOverrideFlushReceived = false; + mFrameRateOverrides.clear(); + + epoll_event epollEvent; + while (epoll_wait(mEpollFd, &epollEvent, 1, 1000) > 0) { + while (mDisplayEventReceiver->getEvents(&event, 1) > 0) { + if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE) { + mFrameRateOverrides.emplace_back(event.frameRateOverride); + } + if (event.header.type == + DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH) { + isOverrideFlushReceived = true; + } + } + + if (isOverrideFlushReceived) break; + } + } + + std::unique_ptr<DisplayEventReceiver> mDisplayEventReceiver; + std::vector<FrameRateOverride> mFrameRateOverrides; + + int mEpollFd; +}; + +TEST_F(SetFrameRateOverrideTest, SetFrameRateOverrideCall) { + uid_t uid = getuid(); + float frameRate = 30.0f; + setFrameRateAndListenEvents(uid, frameRate); + // check if the frame rate override we set exists + ASSERT_TRUE(std::find_if(mFrameRateOverrides.begin(), mFrameRateOverrides.end(), + [uid = uid, frameRate = frameRate](auto i) { + return uid == i.uid && frameRate == i.frameRateHz; + }) != mFrameRateOverrides.end()); + + // test removing frame rate override + frameRate = 0.0f; + setFrameRateAndListenEvents(uid, frameRate); + ASSERT_TRUE(std::find_if(mFrameRateOverrides.begin(), mFrameRateOverrides.end(), + [uid = uid, frameRate = frameRate](auto i) { + return uid == i.uid && frameRate == i.frameRateHz; + }) == mFrameRateOverrides.end()); +} +} // namespace +} // namespace android diff --git a/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp b/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp index f613e43324..5a0ea352d5 100644 --- a/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp +++ b/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp @@ -128,13 +128,12 @@ protected: void createDispSync(); void createDispSyncSource(); - void onVSyncEvent(nsecs_t when, nsecs_t expectedVSyncTimestamp, - nsecs_t deadlineTimestamp) override; + void onVSyncEvent(nsecs_t when, VSyncSource::VSyncData) override; std::unique_ptr<MockVSyncDispatch> mVSyncDispatch; std::unique_ptr<scheduler::DispSyncSource> mDispSyncSource; - AsyncCallRecorder<void (*)(nsecs_t, nsecs_t, nsecs_t)> mVSyncEventCallRecorder; + AsyncCallRecorder<void (*)(nsecs_t, VSyncSource::VSyncData)> mVSyncEventCallRecorder; static constexpr std::chrono::nanoseconds mWorkDuration = 20ms; static constexpr std::chrono::nanoseconds mReadyDuration = 10ms; @@ -155,11 +154,10 @@ DispSyncSourceTest::~DispSyncSourceTest() { ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name()); } -void DispSyncSourceTest::onVSyncEvent(nsecs_t when, nsecs_t expectedVSyncTimestamp, - nsecs_t deadlineTimestamp) { +void DispSyncSourceTest::onVSyncEvent(nsecs_t when, VSyncSource::VSyncData vsyncData) { ALOGD("onVSyncEvent: %" PRId64, when); - mVSyncEventCallRecorder.recordCall(when, expectedVSyncTimestamp, deadlineTimestamp); + mVSyncEventCallRecorder.recordCall(when, vsyncData); } void DispSyncSourceTest::createDispSync() { @@ -233,8 +231,10 @@ TEST_F(DispSyncSourceTest, waitForCallbacks) { mVSyncDispatch->triggerCallbacks(); const auto callbackData = mVSyncEventCallRecorder.waitForCall(); ASSERT_TRUE(callbackData.has_value()); - const auto [when, expectedVSyncTimestamp, deadlineTimestamp] = callbackData.value(); - EXPECT_EQ(when, expectedVSyncTimestamp - mWorkDuration.count() - mReadyDuration.count()); + const auto [when, vsyncData] = callbackData.value(); + EXPECT_EQ(when, + vsyncData.expectedVSyncTimestamp - mWorkDuration.count() - + mReadyDuration.count()); } } @@ -265,8 +265,10 @@ TEST_F(DispSyncSourceTest, waitForCallbacksWithDurationChange) { mVSyncDispatch->triggerCallbacks(); const auto callbackData = mVSyncEventCallRecorder.waitForCall(); ASSERT_TRUE(callbackData.has_value()); - const auto [when, expectedVSyncTimestamp, deadlineTimestamp] = callbackData.value(); - EXPECT_EQ(when, expectedVSyncTimestamp - mWorkDuration.count() - mReadyDuration.count()); + const auto [when, vsyncData] = callbackData.value(); + EXPECT_EQ(when, + vsyncData.expectedVSyncTimestamp - mWorkDuration.count() - + mReadyDuration.count()); } const auto newDuration = mWorkDuration / 2; @@ -286,8 +288,8 @@ TEST_F(DispSyncSourceTest, waitForCallbacksWithDurationChange) { mVSyncDispatch->triggerCallbacks(); const auto callbackData = mVSyncEventCallRecorder.waitForCall(); ASSERT_TRUE(callbackData.has_value()); - const auto [when, expectedVSyncTimestamp, deadlineTimestamp] = callbackData.value(); - EXPECT_EQ(when, expectedVSyncTimestamp - newDuration.count()); + const auto [when, vsyncData] = callbackData.value(); + EXPECT_EQ(when, vsyncData.expectedVSyncTimestamp - newDuration.count()); } EXPECT_CALL(*mVSyncDispatch, cancel(_)).Times(1); diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp index 67a0d7ec32..e5f7b03732 100644 --- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp +++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp @@ -257,7 +257,7 @@ void EventThreadTest::expectVsyncEventFrameTimelinesCorrect(nsecs_t expectedTime ASSERT_TRUE(args.has_value()) << " did not receive an event for timestamp " << expectedTimestamp; const auto& event = std::get<0>(args.value()); - for (int i = 0; i < DisplayEventReceiver::kFrameTimelinesLength; i++) { + for (int i = 0; i < gui::VsyncEventData::kFrameTimelinesLength; i++) { auto prediction = mTokenManager->getPredictionsForToken(event.vsync.frameTimelines[i].vsyncId); EXPECT_TRUE(prediction.has_value()); @@ -275,17 +275,16 @@ void EventThreadTest::expectVsyncEventFrameTimelinesCorrect(nsecs_t expectedTime event.vsync.frameTimelines[i - 1].expectedVSyncTimestamp) << "Expected vsync timestamp out of order for frame timeline " << i; } - if (event.vsync.frameTimelines[i].deadlineTimestamp == preferredDeadline) { - EXPECT_EQ(i, event.vsync.preferredFrameTimelineIndex) - << "Preferred frame timeline index should be " << i; - // For the platform-preferred frame timeline, the vsync ID is 0 because the first frame - // timeline is made before the rest. - EXPECT_EQ(0, event.vsync.frameTimelines[i].vsyncId) - << "Vsync ID incorrect for frame timeline " << i; - } else { - // Vsync ID 0 is used for the preferred frame timeline. - EXPECT_EQ(i + 1, event.vsync.frameTimelines[i].vsyncId) - << "Vsync ID incorrect for frame timeline " << i; + + // Vsync ID order lines up with registration into test token manager. + EXPECT_EQ(i, event.vsync.frameTimelines[i].vsyncId) + << "Vsync ID incorrect for frame timeline " << i; + if (i == event.vsync.preferredFrameTimelineIndex) { + EXPECT_EQ(event.vsync.frameTimelines[i].deadlineTimestamp, preferredDeadline) + << "Preferred deadline timestamp incorrect" << i; + EXPECT_EQ(event.vsync.frameTimelines[i].expectedVSyncTimestamp, + event.vsync.expectedVSyncTimestamp) + << "Preferred expected vsync timestamp incorrect" << i; } } } @@ -369,7 +368,7 @@ TEST_F(EventThreadTest, requestNextVsyncPostsASingleVSyncEventToTheConnection) { // Use the received callback to signal a first vsync event. // The interceptor should receive the event, as well as the connection. - mCallback->onVSyncEvent(123, 456, 789); + mCallback->onVSyncEvent(123, {456, 789}); expectInterceptCallReceived(123); expectThrottleVsyncReceived(456, mConnectionUid); expectVsyncEventReceivedByConnection(123, 1u); @@ -377,7 +376,7 @@ TEST_F(EventThreadTest, requestNextVsyncPostsASingleVSyncEventToTheConnection) { // Use the received callback to signal a second vsync event. // The interceptor should receive the event, but the connection should // not as it was only interested in the first. - mCallback->onVSyncEvent(456, 123, 0); + mCallback->onVSyncEvent(456, {123, 0}); expectInterceptCallReceived(456); EXPECT_FALSE(mThrottleVsyncCallRecorder.waitForUnexpectedCall().has_value()); EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value()); @@ -395,7 +394,7 @@ TEST_F(EventThreadTest, requestNextVsyncEventFrameTimelinesCorrect) { // Use the received callback to signal a vsync event. // The interceptor should receive the event, as well as the connection. - mCallback->onVSyncEvent(123, 456, 789); + mCallback->onVSyncEvent(123, {456, 789}); expectInterceptCallReceived(123); expectVsyncEventFrameTimelinesCorrect(123, 789); } @@ -422,7 +421,7 @@ TEST_F(EventThreadTest, setVsyncRateZeroPostsNoVSyncEventsToThatConnection) { // Send a vsync event. EventThread should then make a call to the // interceptor, and the second connection. The first connection should not // get the event. - mCallback->onVSyncEvent(123, 456, 0); + mCallback->onVSyncEvent(123, {456, 0}); expectInterceptCallReceived(123); EXPECT_FALSE(firstConnectionEventRecorder.waitForUnexpectedCall().has_value()); expectVsyncEventReceivedByConnection("secondConnection", secondConnectionEventRecorder, 123, @@ -437,19 +436,19 @@ TEST_F(EventThreadTest, setVsyncRateOnePostsAllEventsToThatConnection) { // Send a vsync event. EventThread should then make a call to the // interceptor, and the connection. - mCallback->onVSyncEvent(123, 456, 789); + mCallback->onVSyncEvent(123, {456, 789}); expectInterceptCallReceived(123); expectThrottleVsyncReceived(456, mConnectionUid); expectVsyncEventReceivedByConnection(123, 1u); // A second event should go to the same places. - mCallback->onVSyncEvent(456, 123, 0); + mCallback->onVSyncEvent(456, {123, 0}); expectInterceptCallReceived(456); expectThrottleVsyncReceived(123, mConnectionUid); expectVsyncEventReceivedByConnection(456, 2u); // A third event should go to the same places. - mCallback->onVSyncEvent(789, 777, 111); + mCallback->onVSyncEvent(789, {777, 111}); expectInterceptCallReceived(789); expectThrottleVsyncReceived(777, mConnectionUid); expectVsyncEventReceivedByConnection(789, 3u); @@ -462,25 +461,25 @@ TEST_F(EventThreadTest, setVsyncRateTwoPostsEveryOtherEventToThatConnection) { expectVSyncSetEnabledCallReceived(true); // The first event will be seen by the interceptor, and not the connection. - mCallback->onVSyncEvent(123, 456, 789); + mCallback->onVSyncEvent(123, {456, 789}); expectInterceptCallReceived(123); EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value()); EXPECT_FALSE(mThrottleVsyncCallRecorder.waitForUnexpectedCall().has_value()); // The second event will be seen by the interceptor and the connection. - mCallback->onVSyncEvent(456, 123, 0); + mCallback->onVSyncEvent(456, {123, 0}); expectInterceptCallReceived(456); expectVsyncEventReceivedByConnection(456, 2u); EXPECT_FALSE(mThrottleVsyncCallRecorder.waitForUnexpectedCall().has_value()); // The third event will be seen by the interceptor, and not the connection. - mCallback->onVSyncEvent(789, 777, 744); + mCallback->onVSyncEvent(789, {777, 744}); expectInterceptCallReceived(789); EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value()); EXPECT_FALSE(mThrottleVsyncCallRecorder.waitForUnexpectedCall().has_value()); // The fourth event will be seen by the interceptor and the connection. - mCallback->onVSyncEvent(101112, 7847, 86); + mCallback->onVSyncEvent(101112, {7847, 86}); expectInterceptCallReceived(101112); expectVsyncEventReceivedByConnection(101112, 4u); } @@ -495,7 +494,7 @@ TEST_F(EventThreadTest, connectionsRemovedIfInstanceDestroyed) { mConnection = nullptr; // The first event will be seen by the interceptor, and not the connection. - mCallback->onVSyncEvent(123, 456, 789); + mCallback->onVSyncEvent(123, {456, 789}); expectInterceptCallReceived(123); EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value()); @@ -513,13 +512,13 @@ TEST_F(EventThreadTest, connectionsRemovedIfEventDeliveryError) { // The first event will be seen by the interceptor, and by the connection, // which then returns an error. - mCallback->onVSyncEvent(123, 456, 789); + mCallback->onVSyncEvent(123, {456, 789}); expectInterceptCallReceived(123); expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 123, 1u); // A subsequent event will be seen by the interceptor and not by the // connection. - mCallback->onVSyncEvent(456, 123, 0); + mCallback->onVSyncEvent(456, {123, 0}); expectInterceptCallReceived(456); EXPECT_FALSE(errorConnectionEventRecorder.waitForUnexpectedCall().has_value()); @@ -544,7 +543,7 @@ TEST_F(EventThreadTest, tracksEventConnections) { // The first event will be seen by the interceptor, and by the connection, // which then returns an error. - mCallback->onVSyncEvent(123, 456, 789); + mCallback->onVSyncEvent(123, {456, 789}); expectInterceptCallReceived(123); expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 123, 1u); expectVsyncEventReceivedByConnection("successConnection", secondConnectionEventRecorder, 123, @@ -562,13 +561,13 @@ TEST_F(EventThreadTest, eventsDroppedIfNonfatalEventDeliveryError) { // The first event will be seen by the interceptor, and by the connection, // which then returns an non-fatal error. - mCallback->onVSyncEvent(123, 456, 789); + mCallback->onVSyncEvent(123, {456, 789}); expectInterceptCallReceived(123); expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 123, 1u); // A subsequent event will be seen by the interceptor, and by the connection, // which still then returns an non-fatal error. - mCallback->onVSyncEvent(456, 123, 0); + mCallback->onVSyncEvent(456, {123, 0}); expectInterceptCallReceived(456); expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 456, 2u); @@ -692,7 +691,7 @@ TEST_F(EventThreadTest, requestNextVsyncWithThrottleVsyncDoesntPostVSync) { // Use the received callback to signal a first vsync event. // The interceptor should receive the event, but not the connection. - mCallback->onVSyncEvent(123, 456, 789); + mCallback->onVSyncEvent(123, {456, 789}); expectInterceptCallReceived(123); expectThrottleVsyncReceived(456, mThrottledConnectionUid); mThrottledConnectionEventCallRecorder.waitForUnexpectedCall(); @@ -700,7 +699,7 @@ TEST_F(EventThreadTest, requestNextVsyncWithThrottleVsyncDoesntPostVSync) { // Use the received callback to signal a second vsync event. // The interceptor should receive the event, but the connection should // not as it was only interested in the first. - mCallback->onVSyncEvent(456, 123, 0); + mCallback->onVSyncEvent(456, {123, 0}); expectInterceptCallReceived(456); expectThrottleVsyncReceived(123, mThrottledConnectionUid); EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value()); diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index d292e0879d..4fe1e98dbe 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -177,6 +177,11 @@ class TestableSurfaceFlinger { public: using HotplugEvent = SurfaceFlinger::HotplugEvent; + TestableSurfaceFlinger() + : mFlinger(sp<SurfaceFlinger>::make(mFactory, SurfaceFlinger::SkipInitialization)) { + mFlinger->mAnimationTransactionTimeout = ms2ns(10); + } + SurfaceFlinger* flinger() { return mFlinger.get(); } scheduler::TestableScheduler* scheduler() { return mScheduler; } @@ -466,6 +471,10 @@ public: return static_cast<mock::FrameTracer*>(mFlinger->mFrameTracer.get()); } + nsecs_t getAnimationTransactionTimeout() const { + return mFlinger->mAnimationTransactionTimeout; + } + /* ------------------------------------------------------------------------ * Read-write access to private data to set up preconditions and assert * post-conditions. diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp index 1ce0309683..ed23176718 100644 --- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp @@ -89,10 +89,10 @@ public: mock::VsyncController* mVsyncController = new mock::VsyncController(); mock::VSyncTracker* mVSyncTracker = new mock::VSyncTracker(); - mock::MockFence* mFenceUnsignaled = new mock::MockFence(); - mock::MockFence* mFenceSignaled = new mock::MockFence(); - mock::MockFence* mFenceUnsignaled2 = new mock::MockFence(); - mock::MockFence* mFenceSignaled2 = new mock::MockFence(); + sp<mock::MockFence> mFenceUnsignaled = sp<mock::MockFence>::make(); + sp<mock::MockFence> mFenceSignaled = sp<mock::MockFence>::make(); + sp<mock::MockFence> mFenceUnsignaled2 = sp<mock::MockFence>::make(); + sp<mock::MockFence> mFenceSignaled2 = sp<mock::MockFence>::make(); struct TransactionInfo { Vector<ComposerState> states; @@ -159,9 +159,9 @@ public: // completed. If this is animation, it should not time out waiting. nsecs_t returnedTime = systemTime(); if (flags & ISurfaceComposer::eSynchronous || syncInputWindows) { - EXPECT_GE(returnedTime, applicationTime + s2ns(5)); + EXPECT_GE(returnedTime, applicationTime + mFlinger.getAnimationTransactionTimeout()); } else { - EXPECT_LE(returnedTime, applicationTime + s2ns(5)); + EXPECT_LE(returnedTime, applicationTime + mFlinger.getAnimationTransactionTimeout()); } // Each transaction should have been placed on the transaction queue auto transactionQueue = mFlinger.getTransactionQueue(); @@ -188,9 +188,11 @@ public: nsecs_t returnedTime = systemTime(); if ((flags & ISurfaceComposer::eSynchronous) || syncInputWindows) { - EXPECT_GE(systemTime(), applicationSentTime + s2ns(5)); + EXPECT_GE(systemTime(), + applicationSentTime + mFlinger.getAnimationTransactionTimeout()); } else { - EXPECT_LE(returnedTime, applicationSentTime + s2ns(5)); + EXPECT_LE(returnedTime, + applicationSentTime + mFlinger.getAnimationTransactionTimeout()); } // This transaction should have been placed on the transaction queue auto transactionQueue = mFlinger.getTransactionQueue(); @@ -228,7 +230,7 @@ public: // This thread should not have been blocked by the above transaction // (5s is the timeout period that applyTransactionState waits for SF to // commit the transaction) - EXPECT_LE(systemTime(), applicationSentTime + s2ns(5)); + EXPECT_LE(systemTime(), applicationSentTime + mFlinger.getAnimationTransactionTimeout()); // transaction that would goes to pending transaciton queue. mFlinger.flushTransactionQueues(); @@ -246,9 +248,11 @@ public: // the transaction should be placed on the pending queue if (flags & (ISurfaceComposer::eAnimation | ISurfaceComposer::eSynchronous) || syncInputWindows) { - EXPECT_GE(systemTime(), applicationSentTime + s2ns(5)); + EXPECT_GE(systemTime(), + applicationSentTime + mFlinger.getAnimationTransactionTimeout()); } else { - EXPECT_LE(systemTime(), applicationSentTime + s2ns(5)); + EXPECT_LE(systemTime(), + applicationSentTime + mFlinger.getAnimationTransactionTimeout()); } // transaction that would goes to pending transaciton queue. |