summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/dumpstate/DumpstateService.cpp1
-rw-r--r--cmds/dumpstate/dumpstate.cpp100
-rw-r--r--cmds/dumpstate/dumpstate.h9
-rw-r--r--data/etc/Android.bp6
-rw-r--r--data/etc/android.hardware.sensor.accelerometer_limited_axes.xml20
-rw-r--r--data/etc/android.hardware.sensor.accelerometer_limited_axes_uncalibrated.xml20
-rw-r--r--data/etc/android.hardware.sensor.dynamic.head_tracker.xml20
-rw-r--r--data/etc/android.hardware.sensor.gyroscope_limited_axes.xml20
-rw-r--r--data/etc/android.hardware.sensor.gyroscope_limited_axes_uncalibrated.xml20
-rw-r--r--data/etc/android.hardware.sensor.heading.xml20
-rw-r--r--data/etc/android.hardware.telephony.calling.xml2
-rw-r--r--data/etc/android.hardware.telephony.cdma.xml2
-rw-r--r--data/etc/android.hardware.telephony.data.xml2
-rw-r--r--data/etc/android.hardware.telephony.gsm.xml2
-rw-r--r--data/etc/android.hardware.telephony.radio.access.xml (renamed from data/etc/android.hardware.telephony.radio.xml)2
-rw-r--r--include/android/sensor.h112
-rw-r--r--libs/binder/Binder.cpp6
-rw-r--r--libs/binder/BpBinder.cpp11
-rw-r--r--libs/binder/Status.cpp6
-rw-r--r--libs/binder/include/binder/Status.h4
-rw-r--r--libs/binder/ndk/Android.bp10
-rw-r--r--libs/binder/tests/Android.bp44
-rw-r--r--libs/binder/tests/binderStatusUnitTest.cpp35
-rw-r--r--libs/cputimeinstate/Android.bp14
-rw-r--r--libs/gralloc/types/Android.bp1
-rw-r--r--libs/gralloc/types/fuzzer/Android.bp3
-rw-r--r--libs/gui/Android.bp1
-rw-r--r--libs/gui/BLASTBufferQueue.cpp18
-rw-r--r--libs/gui/DisplayEventDispatcher.cpp11
-rw-r--r--libs/gui/LayerDebugInfo.cpp5
-rw-r--r--libs/gui/VsyncEventData.cpp76
-rw-r--r--libs/gui/WindowInfo.cpp4
-rw-r--r--libs/gui/WindowInfosListenerReporter.cpp5
-rw-r--r--libs/gui/include/gui/DisplayEventDispatcher.h35
-rw-r--r--libs/gui/include/gui/DisplayEventReceiver.h6
-rw-r--r--libs/gui/include/gui/ISurfaceComposer.h7
-rw-r--r--libs/gui/include/gui/LayerDebugInfo.h1
-rw-r--r--libs/gui/include/gui/LayerState.h3
-rw-r--r--libs/gui/include/gui/SpHash.h31
-rw-r--r--libs/gui/include/gui/VsyncEventData.h74
-rw-r--r--libs/gui/include/gui/WindowInfo.h1
-rw-r--r--libs/gui/include/gui/WindowInfosListenerReporter.h6
-rw-r--r--libs/gui/tests/Android.bp1
-rw-r--r--libs/gui/tests/VsyncEventData_test.cpp75
-rw-r--r--libs/gui/tests/WindowInfo_test.cpp2
-rw-r--r--libs/nativedisplay/AChoreographer.cpp4
-rw-r--r--libs/renderengine/skia/filters/BlurFilter.cpp4
-rw-r--r--libs/renderengine/skia/filters/LinearEffect.cpp2
-rw-r--r--libs/renderengine/skia/filters/StretchShaderFactory.cpp2
-rw-r--r--libs/sensor/Sensor.cpp20
-rw-r--r--services/gpuservice/bpfprogs/Android.bp1
-rw-r--r--services/gpuservice/gpumem/Android.bp8
-rw-r--r--services/gpuservice/tests/unittests/Android.bp2
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.cpp357
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.h21
-rw-r--r--services/inputflinger/dispatcher/TouchState.cpp32
-rw-r--r--services/inputflinger/dispatcher/TouchState.h24
-rw-r--r--services/inputflinger/dispatcher/include/InputDispatcherInterface.h10
-rw-r--r--services/inputflinger/tests/InputDispatcher_test.cpp97
-rw-r--r--services/sensorservice/AidlSensorHalWrapper.cpp79
-rw-r--r--services/sensorservice/Android.bp1
-rw-r--r--services/sensorservice/LimitedAxesImuSensor.cpp134
-rw-r--r--services/sensorservice/LimitedAxesImuSensor.h46
-rw-r--r--services/sensorservice/SensorService.cpp65
-rw-r--r--services/sensorservice/SensorServiceUtils.cpp9
-rw-r--r--services/surfaceflinger/BufferLayer.cpp16
-rw-r--r--services/surfaceflinger/BufferLayer.h6
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h12
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp6
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp6
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp4
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp18
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp266
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/planner/PredictorTest.cpp96
-rw-r--r--services/surfaceflinger/Layer.cpp2
-rw-r--r--services/surfaceflinger/Layer.h2
-rw-r--r--services/surfaceflinger/RegionSamplingThread.cpp6
-rw-r--r--services/surfaceflinger/Scheduler/DispSyncSource.cpp2
-rw-r--r--services/surfaceflinger/Scheduler/EventThread.cpp40
-rw-r--r--services/surfaceflinger/Scheduler/EventThread.h12
-rw-r--r--services/surfaceflinger/Scheduler/InjectVSyncSource.h2
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp35
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h9
-rw-r--r--services/surfaceflinger/TransactionState.h2
-rw-r--r--services/surfaceflinger/WindowInfosListenerInvoker.cpp3
-rw-r--r--services/surfaceflinger/fuzzer/Android.bp10
-rw-r--r--services/surfaceflinger/fuzzer/README.md19
-rw-r--r--services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp391
-rw-r--r--services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h229
-rw-r--r--services/surfaceflinger/layerproto/LayerProtoParser.cpp2
-rw-r--r--services/surfaceflinger/tests/Android.bp1
-rw-r--r--services/surfaceflinger/tests/SetFrameRateOverride_test.cpp98
-rw-r--r--services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp26
-rw-r--r--services/surfaceflinger/tests/unittests/EventThreadTest.cpp61
-rw-r--r--services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h9
-rw-r--r--services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp26
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.