Merge "Read prop for Skia tracing after boot"
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 2207405..240e6be 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -698,9 +698,6 @@
if (!status.isOk()) {
return status;
}
- if (previousUid != uid) {
- chown_app_profile_dir(packageName, appId, userId);
- }
// Remember inode numbers of cache directories so that we can clear
// contents while CE storage is locked
@@ -726,6 +723,9 @@
if (!status.isOk()) {
return status;
}
+ if (previousUid != uid) {
+ chown_app_profile_dir(packageName, appId, userId);
+ }
if (!prepare_app_profile_dir(packageName, appId, userId)) {
return error("Failed to prepare profiles for " + packageName);
diff --git a/include/android/sensor.h b/include/android/sensor.h
index cf1ca02..c714b05 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -743,11 +743,36 @@
ASensorManager* ASensorManager_getInstanceForPackage(const char* packageName) __INTRODUCED_IN(26);
/**
- * Returns the list of available sensors.
+ * Returns the list of available sensors. The returned list is owned by the
+ * sensor manager and will not change between calls to this function.
+ *
+ * \param manager the {@link ASensorManager} instance obtained from
+ * {@link ASensorManager_getInstanceForPackage}.
+ * \param list the returned list of sensors.
+ * \return positive number of returned sensors or negative error code.
+ * BAD_VALUE: manager is NULL.
*/
int ASensorManager_getSensorList(ASensorManager* manager, ASensorList* list);
/**
+ * Returns the list of available dynamic sensors. If there are no dynamic
+ * sensors available, returns nullptr in list.
+ *
+ * Each time this is called, the previously returned list is deallocated and
+ * must no longer be used.
+ *
+ * Available since API level 33.
+ *
+ * \param manager the {@link ASensorManager} instance obtained from
+ * {@link ASensorManager_getInstanceForPackage}.
+ * \param list the returned list of dynamic sensors.
+ * \return positive number of returned sensors or negative error code.
+ * BAD_VALUE: manager is NULL.
+ */
+ssize_t ASensorManager_getDynamicSensorList(
+ ASensorManager* manager, ASensorList* list) __INTRODUCED_IN(33);
+
+/**
* Returns the default sensor for the given type, or NULL if no sensor
* of that type exists.
*/
diff --git a/libs/cputimeinstate/Android.bp b/libs/cputimeinstate/Android.bp
index 4f63194..79cc15f 100644
--- a/libs/cputimeinstate/Android.bp
+++ b/libs/cputimeinstate/Android.bp
@@ -13,12 +13,13 @@
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 @@
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/gui/Android.bp b/libs/gui/Android.bp
index ec3587b..e17b2c8 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -198,6 +198,7 @@
"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 aeb237d..7ce72ff 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -842,6 +842,14 @@
mPendingTransactions.end());
}
+SurfaceComposerClient::Transaction* BLASTBufferQueue::gatherPendingTransactions(
+ uint64_t frameNumber) {
+ std::lock_guard _lock{mMutex};
+ SurfaceComposerClient::Transaction* t = new SurfaceComposerClient::Transaction();
+ mergePendingTransactions(t, frameNumber);
+ return t;
+}
+
// Maintains a single worker thread per process that services a list of runnables.
class AsyncWorker : public Singleton<AsyncWorker> {
private:
diff --git a/libs/gui/DisplayEventDispatcher.cpp b/libs/gui/DisplayEventDispatcher.cpp
index ee80082..26db59b 100644
--- a/libs/gui/DisplayEventDispatcher.cpp
+++ b/libs/gui/DisplayEventDispatcher.cpp
@@ -148,14 +148,13 @@
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/DisplayEventReceiver.cpp b/libs/gui/DisplayEventReceiver.cpp
index b916e48..36e7d80 100644
--- a/libs/gui/DisplayEventReceiver.cpp
+++ b/libs/gui/DisplayEventReceiver.cpp
@@ -20,6 +20,7 @@
#include <gui/DisplayEventReceiver.h>
#include <gui/ISurfaceComposer.h>
+#include <gui/VsyncEventData.h>
#include <private/gui/ComposerService.h>
@@ -79,6 +80,20 @@
return NO_INIT;
}
+status_t DisplayEventReceiver::getLatestVsyncEventData(VsyncEventData* outVsyncEventData) const {
+ if (mEventConnection != nullptr) {
+ VsyncEventData vsyncEventData;
+ auto status = mEventConnection->getLatestVsyncEventData(&vsyncEventData);
+ if (!status.isOk()) {
+ ALOGE("Failed to get latest vsync event data: %s", status.exceptionMessage().c_str());
+ return status.transactionError();
+ }
+ *outVsyncEventData = vsyncEventData;
+ return NO_ERROR;
+ }
+ return NO_INIT;
+}
+
ssize_t DisplayEventReceiver::getEvents(DisplayEventReceiver::Event* events,
size_t count) {
return DisplayEventReceiver::getEvents(mDataChannel.get(), events, count);
diff --git a/libs/gui/VsyncEventData.cpp b/libs/gui/VsyncEventData.cpp
new file mode 100644
index 0000000..aad81d0
--- /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/aidl/android/gui/IDisplayEventConnection.aidl b/libs/gui/aidl/android/gui/IDisplayEventConnection.aidl
index 9f41593..e9a6a0c 100644
--- a/libs/gui/aidl/android/gui/IDisplayEventConnection.aidl
+++ b/libs/gui/aidl/android/gui/IDisplayEventConnection.aidl
@@ -17,6 +17,7 @@
package android.gui;
import android.gui.BitTube;
+import android.gui.VsyncEventData;
/** @hide */
interface IDisplayEventConnection {
@@ -38,4 +39,9 @@
* requestNextVsync() schedules the next vsync event. It has no effect if the vsync rate is > 0.
*/
oneway void requestNextVsync(); // Asynchronous
+
+ /*
+ * getLatestVsyncEventData() gets the latest vsync event data.
+ */
+ VsyncEventData getLatestVsyncEventData();
}
diff --git a/libs/gui/aidl/android/gui/VsyncEventData.aidl b/libs/gui/aidl/android/gui/VsyncEventData.aidl
new file mode 100644
index 0000000..7343515
--- /dev/null
+++ b/libs/gui/aidl/android/gui/VsyncEventData.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+package android.gui;
+
+parcelable VsyncEventData cpp_header "gui/VsyncEventData.h";
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index f77cfe6..1ed592b 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -98,6 +98,7 @@
void setSyncTransaction(SurfaceComposerClient::Transaction* t, bool acquireSingleBuffer = true);
void mergeWithNextTransaction(SurfaceComposerClient::Transaction* t, uint64_t frameNumber);
void applyPendingTransactions(uint64_t frameNumber);
+ SurfaceComposerClient::Transaction* gatherPendingTransactions(uint64_t frameNumber);
void update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format,
SurfaceComposerClient::Transaction* outTransaction = nullptr);
diff --git a/libs/gui/include/gui/DisplayEventDispatcher.h b/libs/gui/include/gui/DisplayEventDispatcher.h
index 40621dd..71968fa 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 456bbfb..4e04db3 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 @@
// ----------------------------------------------------------------------------
using gui::IDisplayEventConnection;
+using gui::VsyncEventData;
namespace gui {
class BitTube;
@@ -49,8 +51,6 @@
// ----------------------------------------------------------------------------
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 @@
nsecs_t expectedVSyncTimestamp __attribute__((aligned(8)));
nsecs_t deadlineTimestamp __attribute__((aligned(8)));
int64_t vsyncId;
- } frameTimelines[kFrameTimelinesLength];
+ } frameTimelines[VsyncEventData::kFrameTimelinesLength];
};
struct Hotplug {
@@ -172,6 +172,11 @@
*/
status_t requestNextVsync();
+ /**
+ * getLatestVsyncEventData() gets the latest vsync event data.
+ */
+ status_t getLatestVsyncEventData(VsyncEventData* outVsyncEventData) const;
+
private:
sp<IDisplayEventConnection> mEventConnection;
std::unique_ptr<gui::BitTube> mDataChannel;
diff --git a/libs/gui/include/gui/VsyncEventData.h b/libs/gui/include/gui/VsyncEventData.h
new file mode 100644
index 0000000..abac61c
--- /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/tests/Android.bp b/libs/gui/tests/Android.bp
index 6dd1073..e58543a 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -44,6 +44,7 @@
"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 0000000..a670d42
--- /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/nativedisplay/AChoreographer.cpp b/libs/nativedisplay/AChoreographer.cpp
index d90ee57..b182a4a 100644
--- a/libs/nativedisplay/AChoreographer.cpp
+++ b/libs/nativedisplay/AChoreographer.cpp
@@ -73,6 +73,7 @@
} // namespace
namespace android {
+using gui::VsyncEventData;
struct FrameCallback {
AChoreographer_frameCallback callback;
@@ -102,8 +103,7 @@
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/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp
index 62f4b4e..0ba9704 100644
--- a/libs/sensor/SensorManager.cpp
+++ b/libs/sensor/SensorManager.cpp
@@ -100,6 +100,7 @@
SensorManager::~SensorManager() {
free(mSensorList);
+ free(mDynamicSensorList);
}
status_t SensorManager::waitForSensorService(sp<ISensorServer> *server) {
@@ -130,6 +131,9 @@
free(mSensorList);
mSensorList = nullptr;
mSensors.clear();
+ free(mDynamicSensorList);
+ mDynamicSensorList = nullptr;
+ mDynamicSensors.clear();
}
status_t SensorManager::assertStateLocked() {
@@ -197,6 +201,35 @@
return static_cast<ssize_t>(count);
}
+ssize_t SensorManager::getDynamicSensorList(Sensor const* const** list) {
+ Mutex::Autolock _l(mLock);
+ status_t err = assertStateLocked();
+ if (err < 0) {
+ return static_cast<ssize_t>(err);
+ }
+
+ free(mDynamicSensorList);
+ mDynamicSensorList = nullptr;
+ mDynamicSensors = mSensorServer->getDynamicSensorList(mOpPackageName);
+ size_t dynamicCount = mDynamicSensors.size();
+ if (dynamicCount > 0) {
+ mDynamicSensorList = static_cast<Sensor const**>(
+ malloc(dynamicCount * sizeof(Sensor*)));
+ if (mDynamicSensorList == nullptr) {
+ ALOGE("Failed to allocate dynamic sensor list for %zu sensors.",
+ dynamicCount);
+ return static_cast<ssize_t>(NO_MEMORY);
+ }
+
+ for (size_t i = 0; i < dynamicCount; i++) {
+ mDynamicSensorList[i] = mDynamicSensors.array() + i;
+ }
+ }
+
+ *list = mDynamicSensorList;
+ return static_cast<ssize_t>(mDynamicSensors.size());
+}
+
Sensor const* SensorManager::getDefaultSensor(int type)
{
Mutex::Autolock _l(mLock);
diff --git a/libs/sensor/include/sensor/SensorManager.h b/libs/sensor/include/sensor/SensorManager.h
index 09ac7ed..8d0a8a4 100644
--- a/libs/sensor/include/sensor/SensorManager.h
+++ b/libs/sensor/include/sensor/SensorManager.h
@@ -58,6 +58,7 @@
ssize_t getSensorList(Sensor const* const** list);
ssize_t getDynamicSensorList(Vector<Sensor>& list);
+ ssize_t getDynamicSensorList(Sensor const* const** list);
Sensor const* getDefaultSensor(int type);
sp<SensorEventQueue> createEventQueue(
String8 packageName = String8(""), int mode = 0, String16 attributionTag = String16(""));
@@ -83,6 +84,8 @@
sp<ISensorServer> mSensorServer;
Sensor const** mSensorList;
Vector<Sensor> mSensors;
+ Sensor const** mDynamicSensorList = nullptr;
+ Vector<Sensor> mDynamicSensors;
sp<IBinder::DeathRecipient> mDeathObserver;
const String16 mOpPackageName;
std::unordered_map<int, sp<ISensorEventConnection>> mDirectConnection;
diff --git a/services/gpuservice/bpfprogs/Android.bp b/services/gpuservice/bpfprogs/Android.bp
index 9842ed7..076affd 100644
--- a/services/gpuservice/bpfprogs/Android.bp
+++ b/services/gpuservice/bpfprogs/Android.bp
@@ -24,6 +24,7 @@
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 24087ac..d0ea856 100644
--- a/services/gpuservice/gpumem/Android.bp
+++ b/services/gpuservice/gpumem/Android.bp
@@ -26,19 +26,17 @@
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 5b69f96..4fb0d2e 100644
--- a/services/gpuservice/tests/unittests/Android.bp
+++ b/services/gpuservice/tests/unittests/Android.bp
@@ -32,10 +32,10 @@
"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 6c321bc..7062aef 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -4920,7 +4920,7 @@
const sp<IBinder> focusedToken =
mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
- // TODO(b/198487159): if no window is currently focused, then we need to check the last
+ // 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) {
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 29c146b..a3188f3 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -39,6 +39,7 @@
#include "DisplayHardware/PowerAdvisor.h"
+using aidl::android::hardware::graphics::composer3::Capability;
using aidl::android::hardware::graphics::composer3::DisplayCapability;
namespace android::compositionengine::impl {
@@ -284,7 +285,7 @@
DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM);
}
- return hwc.hasCapability(hal::Capability::SKIP_CLIENT_COLOR_TRANSFORM);
+ return hwc.hasCapability(Capability::SKIP_CLIENT_COLOR_TRANSFORM);
}
bool Display::anyLayersRequireClientComposition() const {
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index 125ce74..44d34a3 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -41,6 +41,7 @@
#include <aidl/android/hardware/graphics/composer3/Composition.h>
+using aidl::android::hardware::graphics::composer3::Capability;
using aidl::android::hardware::graphics::composer3::Composition;
namespace android::compositionengine {
@@ -672,7 +673,7 @@
using aidl::android::hardware::graphics::composer3::DisplayCapability;
TEST_F(DisplayGetSkipColorTransformTest, checksCapabilityIfGpuDisplay) {
- EXPECT_CALL(mHwComposer, hasCapability(hal::Capability::SKIP_CLIENT_COLOR_TRANSFORM))
+ EXPECT_CALL(mHwComposer, hasCapability(Capability::SKIP_CLIENT_COLOR_TRANSFORM))
.WillOnce(Return(true));
auto args = getDisplayCreationArgsForGpuVirtualDisplay();
auto gpuDisplay{impl::createDisplay(mCompositionEngine, args)};
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index 660f664..8ec8f00 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -42,7 +42,8 @@
MOCK_METHOD1(setCallback, void(HWC2::ComposerCallback&));
MOCK_CONST_METHOD3(getDisplayIdentificationData,
bool(hal::HWDisplayId, uint8_t*, DisplayIdentificationData*));
- MOCK_CONST_METHOD1(hasCapability, bool(hal::Capability));
+ MOCK_CONST_METHOD1(hasCapability,
+ bool(aidl::android::hardware::graphics::composer3::Capability));
MOCK_CONST_METHOD2(hasDisplayCapability,
bool(HalDisplayId,
aidl::android::hardware::graphics::composer3::DisplayCapability));
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
index b1057c3..d10468a 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
@@ -251,14 +251,14 @@
}
}
-std::vector<IComposer::Capability> AidlComposer::getCapabilities() {
+std::vector<Capability> AidlComposer::getCapabilities() {
std::vector<Capability> capabilities;
const auto status = mAidlComposer->getCapabilities(&capabilities);
if (!status.isOk()) {
ALOGE("getCapabilities failed %s", status.getDescription().c_str());
return {};
}
- return translate<IComposer::Capability>(capabilities);
+ return capabilities;
}
std::string AidlComposer::dumpDebugInfo() {
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
index 374a436..a9f7606 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
@@ -60,7 +60,8 @@
bool isSupported(OptionalFeature) const;
- std::vector<IComposer::Capability> getCapabilities() override;
+ std::vector<aidl::android::hardware::graphics::composer3::Capability> getCapabilities()
+ override;
std::string dumpDebugInfo() override;
void registerCallback(HWC2::ComposerCallback& callback) override;
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index fe55e6b..5cc5a12 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -31,6 +31,7 @@
#include <ui/GraphicBuffer.h>
#include <utils/StrongPointer.h>
+#include <aidl/android/hardware/graphics/composer3/Capability.h>
#include <aidl/android/hardware/graphics/composer3/Color.h>
#include <aidl/android/hardware/graphics/composer3/Composition.h>
#include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
@@ -93,7 +94,8 @@
virtual bool isSupported(OptionalFeature) const = 0;
- virtual std::vector<IComposer::Capability> getCapabilities() = 0;
+ virtual std::vector<aidl::android::hardware::graphics::composer3::Capability>
+ getCapabilities() = 0;
virtual std::string dumpDebugInfo() = 0;
virtual void registerCallback(HWC2::ComposerCallback& callback) = 0;
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 05e3aef..b59b333 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -39,6 +39,7 @@
using aidl::android::hardware::graphics::composer3::Color;
using aidl::android::hardware::graphics::composer3::Composition;
+using AidlCapability = aidl::android::hardware::graphics::composer3::Capability;
using aidl::android::hardware::graphics::composer3::DisplayCapability;
namespace android {
@@ -73,7 +74,7 @@
namespace impl {
Display::Display(android::Hwc2::Composer& composer,
- const std::unordered_set<Capability>& capabilities, HWDisplayId id,
+ const std::unordered_set<AidlCapability>& capabilities, HWDisplayId id,
DisplayType type)
: mComposer(composer), mCapabilities(capabilities), mId(id), mType(type) {
ALOGV("Created display %" PRIu64, id);
@@ -470,7 +471,7 @@
} else if (error == Error::UNSUPPORTED) {
std::scoped_lock lock(mDisplayCapabilitiesMutex);
mDisplayCapabilities.emplace();
- if (mCapabilities.count(Capability::SKIP_CLIENT_COLOR_TRANSFORM)) {
+ if (mCapabilities.count(AidlCapability::SKIP_CLIENT_COLOR_TRANSFORM)) {
mDisplayCapabilities->emplace(DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM);
}
bool dozeSupport = false;
@@ -618,8 +619,9 @@
namespace impl {
-Layer::Layer(android::Hwc2::Composer& composer, const std::unordered_set<Capability>& capabilities,
- HWC2::Display& display, HWLayerId layerId)
+Layer::Layer(android::Hwc2::Composer& composer,
+ const std::unordered_set<AidlCapability>& capabilities, HWC2::Display& display,
+ HWLayerId layerId)
: mComposer(composer),
mCapabilities(capabilities),
mDisplay(&display),
@@ -849,7 +851,7 @@
return Error::BAD_DISPLAY;
}
- if (mCapabilities.count(Capability::SIDEBAND_STREAM) == 0) {
+ if (mCapabilities.count(AidlCapability::SIDEBAND_STREAM) == 0) {
ALOGE("Attempted to call setSidebandStream without checking that the "
"device supports sideband streams");
return Error::UNSUPPORTED;
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 0a605a8..b183924 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -37,6 +37,7 @@
#include "ComposerHal.h"
#include "Hal.h"
+#include <aidl/android/hardware/graphics/composer3/Capability.h>
#include <aidl/android/hardware/graphics/composer3/Color.h>
#include <aidl/android/hardware/graphics/composer3/Composition.h>
#include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
@@ -169,8 +170,9 @@
class Display : public HWC2::Display {
public:
- Display(android::Hwc2::Composer&, const std::unordered_set<hal::Capability>&, hal::HWDisplayId,
- hal::DisplayType);
+ Display(android::Hwc2::Composer&,
+ const std::unordered_set<aidl::android::hardware::graphics::composer3::Capability>&,
+ hal::HWDisplayId, hal::DisplayType);
~Display() override;
// Required by HWC2
@@ -257,7 +259,8 @@
// this HWC2::Display, so these references are guaranteed to be valid for
// the lifetime of this object.
android::Hwc2::Composer& mComposer;
- const std::unordered_set<hal::Capability>& mCapabilities;
+ const std::unordered_set<aidl::android::hardware::graphics::composer3::Capability>&
+ mCapabilities;
const hal::HWDisplayId mId;
hal::DisplayType mType;
@@ -329,8 +332,9 @@
class Layer : public HWC2::Layer {
public:
Layer(android::Hwc2::Composer& composer,
- const std::unordered_set<hal::Capability>& capabilities, HWC2::Display& display,
- hal::HWLayerId layerId);
+ const std::unordered_set<aidl::android::hardware::graphics::composer3::Capability>&
+ capabilities,
+ HWC2::Display& display, hal::HWLayerId layerId);
~Layer() override;
void onOwningDisplayDestroyed();
@@ -373,7 +377,8 @@
// this HWC2::Layer, so these references are guaranteed to be valid for
// the lifetime of this object.
android::Hwc2::Composer& mComposer;
- const std::unordered_set<hal::Capability>& mCapabilities;
+ const std::unordered_set<aidl::android::hardware::graphics::composer3::Capability>&
+ mCapabilities;
HWC2::Display* mDisplay;
hal::HWLayerId mId;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 2696bd8..0ed4ec9 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -71,6 +71,8 @@
#define RETURN_IF_HWC_ERROR(error, displayId, ...) \
RETURN_IF_HWC_ERROR_FOR(__FUNCTION__, error, displayId, __VA_ARGS__)
+using aidl::android::hardware::graphics::composer3::Capability;
+using aidl::android::hardware::graphics::composer3::DisplayCapability;
namespace hal = android::hardware::graphics::composer::hal;
namespace android {
@@ -118,13 +120,11 @@
return true;
}
-bool HWComposer::hasCapability(hal::Capability capability) const {
+bool HWComposer::hasCapability(Capability capability) const {
return mCapabilities.count(capability) > 0;
}
-bool HWComposer::hasDisplayCapability(
- HalDisplayId displayId,
- aidl::android::hardware::graphics::composer3::DisplayCapability capability) const {
+bool HWComposer::hasDisplayCapability(HalDisplayId displayId, DisplayCapability capability) const {
RETURN_IF_INVALID_DISPLAY(displayId, false);
return mDisplayData.at(displayId).hwcDisplay->hasCapability(capability);
}
@@ -952,7 +952,7 @@
static_assert(sizeof(hal::Capability) == sizeof(int32_t), "Capability size has changed");
auto capabilities = mComposer->getCapabilities();
for (auto capability : capabilities) {
- mCapabilities.emplace(static_cast<hal::Capability>(capability));
+ mCapabilities.emplace(capability);
}
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 29335d5..1376f51 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -43,6 +43,7 @@
#include "HWC2.h"
#include "Hal.h"
+#include <aidl/android/hardware/graphics/composer3/Capability.h>
#include <aidl/android/hardware/graphics/composer3/Composition.h>
#include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
@@ -110,7 +111,7 @@
virtual bool getDisplayIdentificationData(hal::HWDisplayId, uint8_t* outPort,
DisplayIdentificationData* outData) const = 0;
- virtual bool hasCapability(hal::Capability) const = 0;
+ virtual bool hasCapability(aidl::android::hardware::graphics::composer3::Capability) const = 0;
virtual bool hasDisplayCapability(
HalDisplayId,
aidl::android::hardware::graphics::composer3::DisplayCapability) const = 0;
@@ -277,7 +278,7 @@
bool getDisplayIdentificationData(hal::HWDisplayId, uint8_t* outPort,
DisplayIdentificationData* outData) const override;
- bool hasCapability(hal::Capability) const override;
+ bool hasCapability(aidl::android::hardware::graphics::composer3::Capability) const override;
bool hasDisplayCapability(
HalDisplayId,
aidl::android::hardware::graphics::composer3::DisplayCapability) const override;
@@ -447,7 +448,7 @@
std::unordered_map<HalDisplayId, DisplayData> mDisplayData;
std::unique_ptr<android::Hwc2::Composer> mComposer;
- std::unordered_set<hal::Capability> mCapabilities;
+ std::unordered_set<aidl::android::hardware::graphics::composer3::Capability> mCapabilities;
std::unordered_map<std::string, bool> mSupportedLayerGenericMetadata;
bool mRegisteredCallback = false;
diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
index 746ac64..25f03be 100644
--- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
@@ -36,6 +36,7 @@
#include <algorithm>
#include <cinttypes>
+using aidl::android::hardware::graphics::composer3::Capability;
using aidl::android::hardware::graphics::composer3::DisplayCapability;
namespace android {
@@ -168,6 +169,20 @@
return unwrapRet(ret, kDefaultError);
}
+template <typename To, typename From>
+To translate(From x) {
+ return static_cast<To>(x);
+}
+
+template <typename To, typename From>
+std::vector<To> translate(const hidl_vec<From>& in) {
+ std::vector<To> out;
+ out.reserve(in.size());
+ std::transform(in.begin(), in.end(), std::back_inserter(out),
+ [](From x) { return translate<To>(x); });
+ return out;
+}
+
} // anonymous namespace
HidlComposer::HidlComposer(const std::string& serviceName) : mWriter(kWriterInitialSize) {
@@ -225,10 +240,11 @@
}
}
-std::vector<IComposer::Capability> HidlComposer::getCapabilities() {
- std::vector<IComposer::Capability> capabilities;
- mComposer->getCapabilities(
- [&](const auto& tmpCapabilities) { capabilities = tmpCapabilities; });
+std::vector<Capability> HidlComposer::getCapabilities() {
+ std::vector<Capability> capabilities;
+ mComposer->getCapabilities([&](const auto& tmpCapabilities) {
+ capabilities = translate<Capability>(tmpCapabilities);
+ });
return capabilities;
}
@@ -1101,15 +1117,6 @@
// Composer HAL 2.4
-namespace {
-template <typename T>
-void copyCapabilities(const T& tmpCaps, std::vector<DisplayCapability>* outCapabilities) {
- outCapabilities->resize(tmpCaps.size());
- std::transform(tmpCaps.begin(), tmpCaps.end(), outCapabilities->begin(),
- [](auto cap) { return static_cast<DisplayCapability>(cap); });
-}
-} // anonymous namespace
-
Error HidlComposer::getDisplayCapabilities(Display display,
std::vector<DisplayCapability>* outCapabilities) {
if (!mClient_2_3) {
@@ -1124,7 +1131,8 @@
if (error != V2_4::Error::NONE) {
return;
}
- copyCapabilities(tmpCaps, outCapabilities);
+ *outCapabilities =
+ translate<DisplayCapability>(tmpCaps);
});
} else {
mClient_2_3
@@ -1134,7 +1142,7 @@
return;
}
- copyCapabilities(tmpCaps, outCapabilities);
+ *outCapabilities = translate<DisplayCapability>(tmpCaps);
});
}
diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
index 1ffca6e..0f15598 100644
--- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
@@ -169,7 +169,8 @@
bool isSupported(OptionalFeature) const;
- std::vector<IComposer::Capability> getCapabilities() override;
+ std::vector<aidl::android::hardware::graphics::composer3::Capability> getCapabilities()
+ override;
std::string dumpDebugInfo() override;
void registerCallback(HWC2::ComposerCallback& callback) override;
diff --git a/services/surfaceflinger/Scheduler/DispSyncSource.cpp b/services/surfaceflinger/Scheduler/DispSyncSource.cpp
index 50b38c9..747032b 100644
--- a/services/surfaceflinger/Scheduler/DispSyncSource.cpp
+++ b/services/surfaceflinger/Scheduler/DispSyncSource.cpp
@@ -23,6 +23,7 @@
#include <mutex>
#include "EventThread.h"
+#include "VSyncTracker.h"
#include "VsyncController.h"
namespace android::scheduler {
@@ -114,7 +115,7 @@
std::chrono::nanoseconds mLastCallTime GUARDED_BY(mMutex) = 0ns;
};
-DispSyncSource::DispSyncSource(scheduler::VSyncDispatch& vSyncDispatch,
+DispSyncSource::DispSyncSource(VSyncDispatch& vSyncDispatch, VSyncTracker& vSyncTracker,
std::chrono::nanoseconds workDuration,
std::chrono::nanoseconds readyDuration, bool traceVsync,
const char* name)
@@ -122,6 +123,7 @@
mValue(base::StringPrintf("VSYNC-%s", name), 0),
mTraceVsync(traceVsync),
mVsyncOnLabel(base::StringPrintf("VsyncOn-%s", name)),
+ mVSyncTracker(vSyncTracker),
mWorkDuration(base::StringPrintf("VsyncWorkDuration-%s", name), workDuration),
mReadyDuration(readyDuration) {
mCallbackRepeater =
@@ -180,10 +182,18 @@
}
if (callback != nullptr) {
- callback->onVSyncEvent(targetWakeupTime, vsyncTime, readyTime);
+ callback->onVSyncEvent(targetWakeupTime, {vsyncTime, readyTime});
}
}
+VSyncSource::VSyncData DispSyncSource::getLatestVSyncData() const {
+ std::lock_guard lock(mVsyncMutex);
+ nsecs_t expectedPresentTime = mVSyncTracker.nextAnticipatedVSyncTimeFrom(
+ systemTime() + mWorkDuration.get().count() + mReadyDuration.count());
+ nsecs_t deadline = expectedPresentTime - mWorkDuration.get().count() - mReadyDuration.count();
+ return {expectedPresentTime, deadline};
+}
+
void DispSyncSource::dump(std::string& result) const {
std::lock_guard lock(mVsyncMutex);
StringAppendF(&result, "DispSyncSource: %s(%s)\n", mName, mEnabled ? "enabled" : "disabled");
diff --git a/services/surfaceflinger/Scheduler/DispSyncSource.h b/services/surfaceflinger/Scheduler/DispSyncSource.h
index 2fce235..edcd3ac 100644
--- a/services/surfaceflinger/Scheduler/DispSyncSource.h
+++ b/services/surfaceflinger/Scheduler/DispSyncSource.h
@@ -24,11 +24,13 @@
namespace android::scheduler {
class CallbackRepeater;
+class VSyncTracker;
class DispSyncSource final : public VSyncSource {
public:
- DispSyncSource(VSyncDispatch& vSyncDispatch, std::chrono::nanoseconds workDuration,
- std::chrono::nanoseconds readyDuration, bool traceVsync, const char* name);
+ DispSyncSource(VSyncDispatch& vSyncDispatch, VSyncTracker& vSyncTracker,
+ std::chrono::nanoseconds workDuration, std::chrono::nanoseconds readyDuration,
+ bool traceVsync, const char* name);
~DispSyncSource() override;
@@ -38,6 +40,7 @@
void setCallback(VSyncSource::Callback* callback) override;
void setDuration(std::chrono::nanoseconds workDuration,
std::chrono::nanoseconds readyDuration) override;
+ VSyncData getLatestVSyncData() const override;
void dump(std::string&) const override;
@@ -50,6 +53,8 @@
const bool mTraceVsync;
const std::string mVsyncOnLabel;
+ const VSyncTracker& mVSyncTracker;
+
std::unique_ptr<CallbackRepeater> mCallbackRepeater;
std::mutex mCallbackMutex;
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 627c49a..2d0da46 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -108,13 +108,12 @@
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;
}
@@ -182,11 +181,17 @@
}
binder::Status EventThreadConnection::requestNextVsync() {
- ATRACE_NAME("requestNextVsync");
+ ATRACE_CALL();
mEventThread->requestNextVsync(this);
return binder::Status::ok();
}
+binder::Status EventThreadConnection::getLatestVsyncEventData(VsyncEventData* outVsyncEventData) {
+ ATRACE_CALL();
+ *outVsyncEventData = mEventThread->getLatestVsyncEventData(this);
+ return binder::Status::ok();
+}
+
status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
constexpr auto toStatus = [](ssize_t size) {
return size < 0 ? status_t(size) : status_t(NO_ERROR);
@@ -331,6 +336,15 @@
}
}
+VsyncEventData EventThread::getLatestVsyncEventData(
+ const sp<EventThreadConnection>& connection) const {
+ nsecs_t frameInterval = mGetVsyncPeriodFunction(connection->mOwnerUid);
+ VsyncEventData vsyncEventData;
+ vsyncEventData.frameInterval = frameInterval;
+ generateFrameTimeline(vsyncEventData, frameInterval, systemTime(SYSTEM_TIME_MONOTONIC));
+ return vsyncEventData;
+}
+
void EventThread::onScreenReleased() {
std::lock_guard<std::mutex> lock(mMutex);
if (!mVSyncState || mVSyncState->synthetic) {
@@ -351,14 +365,13 @@
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 +506,9 @@
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));
}
}
}
@@ -570,32 +576,64 @@
return FrameTimelineInfo::INVALID_VSYNC_ID;
}
-void EventThread::generateFrameTimeline(DisplayEventReceiver::Event& event) const {
+void EventThread::generateFrameTimeline(
+ nsecs_t frameInterval, nsecs_t timestamp, nsecs_t preferredExpectedVSyncTimestamp,
+ nsecs_t preferredDeadlineTimestamp,
+ std::function<void(int64_t index)> setPreferredFrameTimelineIndex,
+ std::function<void(int64_t index, int64_t vsyncId, nsecs_t expectedVSyncTimestamp,
+ nsecs_t deadlineTimestamp)>
+ setFrameTimeline) 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++) {
- nsecs_t deadline = event.vsync.deadlineTimestamp + multiplier * event.vsync.frameInterval;
+ for (int64_t multiplier = -VsyncEventData::kFrameTimelinesLength + 1, currentIndex = 0;
+ currentIndex < VsyncEventData::kFrameTimelinesLength; multiplier++) {
+ nsecs_t deadline = preferredDeadlineTimestamp + multiplier * frameInterval;
// Valid possible frame timelines must have future values.
- if (deadline > event.header.timestamp) {
+ if (deadline > 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};
+ setPreferredFrameTimelineIndex(currentIndex);
}
+ nsecs_t expectedVSyncTimestamp =
+ preferredExpectedVSyncTimestamp + multiplier * frameInterval;
+ setFrameTimeline(currentIndex,
+ generateToken(timestamp, deadline, expectedVSyncTimestamp),
+ expectedVSyncTimestamp, deadline);
currentIndex++;
}
}
}
+void EventThread::generateFrameTimeline(DisplayEventReceiver::Event& event) const {
+ generateFrameTimeline(
+ event.vsync.frameInterval, event.header.timestamp, event.vsync.expectedVSyncTimestamp,
+ event.vsync.deadlineTimestamp,
+ [&](int index) { event.vsync.preferredFrameTimelineIndex = index; },
+ [&](int64_t index, int64_t vsyncId, nsecs_t expectedVSyncTimestamp,
+ nsecs_t deadlineTimestamp) {
+ event.vsync.frameTimelines[index] = {.vsyncId = vsyncId,
+ .deadlineTimestamp = deadlineTimestamp,
+ .expectedVSyncTimestamp =
+ expectedVSyncTimestamp};
+ });
+}
+
+void EventThread::generateFrameTimeline(VsyncEventData& out, const nsecs_t frameInterval,
+ const nsecs_t timestamp) const {
+ VSyncSource::VSyncData vsyncData;
+ {
+ std::lock_guard<std::mutex> lock(mMutex);
+ vsyncData = mVSyncSource->getLatestVSyncData();
+ }
+ generateFrameTimeline(
+ frameInterval, timestamp, vsyncData.expectedVSyncTimestamp, vsyncData.deadlineTimestamp,
+ [&](int index) { out.preferredFrameTimelineIndex = index; },
+ [&](int64_t index, int64_t vsyncId, nsecs_t expectedVSyncTimestamp,
+ nsecs_t deadlineTimestamp) {
+ out.frameTimelines[index] =
+ VsyncEventData::FrameTimeline(vsyncId, deadlineTimestamp,
+ expectedVSyncTimestamp);
+ });
+}
+
void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event,
const DisplayEventConsumers& consumers) {
for (const auto& consumer : consumers) {
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index fa9af09..a858169 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -45,6 +45,8 @@
class TokenManager;
} // namespace frametimeline
+using gui::VsyncEventData;
+
// ---------------------------------------------------------------------------
using ResyncCallback = std::function<void()>;
@@ -62,11 +64,16 @@
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() {}
@@ -76,6 +83,7 @@
virtual void setCallback(Callback* callback) = 0;
virtual void setDuration(std::chrono::nanoseconds workDuration,
std::chrono::nanoseconds readyDuration) = 0;
+ virtual VSyncData getLatestVSyncData() const = 0;
virtual void dump(std::string& result) const = 0;
};
@@ -91,6 +99,7 @@
binder::Status stealReceiveChannel(gui::BitTube* outChannel) override;
binder::Status setVsyncRate(int rate) override;
binder::Status requestNextVsync() override; // asynchronous
+ binder::Status getLatestVsyncEventData(VsyncEventData* outVsyncEventData) override;
// Called in response to requestNextVsync.
const ResyncCallback resyncCallback;
@@ -140,6 +149,8 @@
virtual void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) = 0;
// Requests the next vsync. If resetIdleTimer is set to true, it resets the idle timer.
virtual void requestNextVsync(const sp<EventThreadConnection>& connection) = 0;
+ virtual VsyncEventData getLatestVsyncEventData(
+ const sp<EventThreadConnection>& connection) const = 0;
// Retrieves the number of event connections tracked by this EventThread.
virtual size_t getEventThreadConnectionCount() = 0;
@@ -164,6 +175,8 @@
status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override;
void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) override;
void requestNextVsync(const sp<EventThreadConnection>& connection) override;
+ VsyncEventData getLatestVsyncEventData(
+ const sp<EventThreadConnection>& connection) const override;
// called before the screen is turned off from main thread
void onScreenReleased() override;
@@ -201,12 +214,20 @@
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;
void generateFrameTimeline(DisplayEventReceiver::Event& event) const;
+ void generateFrameTimeline(VsyncEventData& out, const nsecs_t frameInterval,
+ const nsecs_t timestamp) const;
+ void generateFrameTimeline(
+ nsecs_t frameInterval, nsecs_t timestamp, nsecs_t preferredExpectedVSyncTimestamp,
+ nsecs_t preferredDeadlineTimestamp,
+ std::function<void(int64_t index)> setPreferredFrameTimelineIndex,
+ std::function<void(int64_t index, int64_t vsyncId, nsecs_t expectedVSyncTimestamp,
+ nsecs_t deadlineTimestamp)>
+ setFrameTimeline) const;
const std::unique_ptr<VSyncSource> mVSyncSource GUARDED_BY(mMutex);
frametimeline::TokenManager* const mTokenManager;
diff --git a/services/surfaceflinger/Scheduler/InjectVSyncSource.h b/services/surfaceflinger/Scheduler/InjectVSyncSource.h
index 016b076..760a4ee 100644
--- a/services/surfaceflinger/Scheduler/InjectVSyncSource.h
+++ b/services/surfaceflinger/Scheduler/InjectVSyncSource.h
@@ -39,13 +39,14 @@
nsecs_t deadlineTimestamp) {
std::lock_guard<std::mutex> lock(mCallbackMutex);
if (mCallback) {
- mCallback->onVSyncEvent(when, expectedVSyncTimestamp, deadlineTimestamp);
+ mCallback->onVSyncEvent(when, {expectedVSyncTimestamp, deadlineTimestamp});
}
}
const char* getName() const override { return "inject"; }
void setVSyncEnabled(bool) override {}
void setDuration(std::chrono::nanoseconds, std::chrono::nanoseconds) override {}
+ VSyncData getLatestVSyncData() const override { return {}; }
void dump(std::string&) const override {}
private:
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 665d36982..de27bd1 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -134,7 +134,8 @@
std::unique_ptr<VSyncSource> Scheduler::makePrimaryDispSyncSource(
const char* name, std::chrono::nanoseconds workDuration,
std::chrono::nanoseconds readyDuration, bool traceVsync) {
- return std::make_unique<scheduler::DispSyncSource>(getVsyncDispatch(), workDuration,
+ return std::make_unique<scheduler::DispSyncSource>(mVsyncSchedule->getDispatch(),
+ mVsyncSchedule->getTracker(), workDuration,
readyDuration, traceVsync, name);
}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index fbad654..f99a2a3 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -163,6 +163,7 @@
#define NO_THREAD_SAFETY_ANALYSIS \
_Pragma("GCC error \"Prefer MAIN_THREAD macros or {Conditional,Timed,Unnecessary}Lock.\"")
+using aidl::android::hardware::graphics::composer3::Capability;
using aidl::android::hardware::graphics::composer3::DisplayCapability;
namespace android {
@@ -892,7 +893,7 @@
// Inform native graphics APIs whether the present timestamp is supported:
const bool presentFenceReliable =
- !getHwComposer().hasCapability(hal::Capability::PRESENT_FENCE_IS_NOT_RELIABLE);
+ !getHwComposer().hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE);
mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);
if (mStartPropertySetThread->Start() != NO_ERROR) {
@@ -956,7 +957,7 @@
};
ConditionalLock _l(mStateLock,
std::this_thread::get_id() != mMainThreadId);
- if (!getHwComposer().hasCapability(hal::Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
+ if (!getHwComposer().hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
outSupported->push_back(FrameEvent::DISPLAY_PRESENT);
}
return NO_ERROR;
@@ -3378,7 +3379,7 @@
features |= Feature::kTracePredictedVsync;
}
if (!base::GetBoolProperty("debug.sf.vsync_reactor_ignore_present_fences"s, false) &&
- !getHwComposer().hasCapability(hal::Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
+ !getHwComposer().hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
features |= Feature::kPresentFences;
}
@@ -3735,7 +3736,7 @@
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,
@@ -4028,7 +4029,7 @@
}
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 +4051,9 @@
}
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 +5509,13 @@
}
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) {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 1b8f62a..b95cd91 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -714,7 +714,7 @@
/*
* 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,
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer.cpp
index 816d2f1..3c4ab95 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer.cpp
@@ -44,6 +44,7 @@
using namespace android::hardware::graphics::common;
using namespace android::hardware::graphics::composer;
+namespace aidl = aidl::android::hardware::graphics::composer3;
namespace hal = android::hardware::graphics::composer::hal;
using Config = hal::V2_1::Config;
using Display = hal::V2_1::Display;
@@ -58,10 +59,11 @@
hal::Transform::ROT_90, hal::Transform::ROT_180,
hal::Transform::ROT_270};
-static constexpr hal::Capability kCapability[] = {hal::Capability::INVALID,
- hal::Capability::SIDEBAND_STREAM,
- hal::Capability::SKIP_CLIENT_COLOR_TRANSFORM,
- hal::Capability::PRESENT_FENCE_IS_NOT_RELIABLE};
+static constexpr aidl::Capability kCapability[] = {aidl::Capability::INVALID,
+ aidl::Capability::SIDEBAND_STREAM,
+ aidl::Capability::SKIP_CLIENT_COLOR_TRANSFORM,
+ aidl::Capability::PRESENT_FENCE_IS_NOT_RELIABLE,
+ aidl::Capability::SKIP_VALIDATE};
static constexpr hal::BlendMode kBlendModes[] = {hal::BlendMode::INVALID, hal::BlendMode::NONE,
hal::BlendMode::PREMULTIPLIED,
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
index 51a5081..09ffb02 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
@@ -63,8 +63,7 @@
FuzzedDataProvider mFdp;
protected:
- void onVSyncEvent(nsecs_t /* when */, nsecs_t /* expectedVSyncTimestamp */,
- nsecs_t /* deadlineTimestamp */) {}
+ void onVSyncEvent(nsecs_t /* when */, VSyncSource::VSyncData) {}
};
PhysicalDisplayId SchedulerFuzzer::getPhysicalDisplayId() {
@@ -101,8 +100,9 @@
void SchedulerFuzzer::fuzzDispSyncSource() {
std::unique_ptr<FuzzImplVSyncDispatch> vSyncDispatch =
std::make_unique<FuzzImplVSyncDispatch>();
+ std::unique_ptr<FuzzImplVSyncTracker> vSyncTracker = std::make_unique<FuzzImplVSyncTracker>();
std::unique_ptr<scheduler::DispSyncSource> dispSyncSource = std::make_unique<
- scheduler::DispSyncSource>(*vSyncDispatch,
+ scheduler::DispSyncSource>(*vSyncDispatch, *vSyncTracker,
(std::chrono::nanoseconds)
mFdp.ConsumeIntegral<uint64_t>() /*workDuration*/,
(std::chrono::nanoseconds)mFdp.ConsumeIntegral<uint64_t>()
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h
index 89cf819..84b3912 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h
@@ -103,6 +103,8 @@
void setDuration(std::chrono::nanoseconds /* workDuration */,
std::chrono::nanoseconds /* readyDuration */) override {}
+ VSyncData getLatestVSyncData() const override { return {}; }
+
void dump(std::string& /* result */) const override {}
};
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index 7b86229..efcc386 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -31,6 +31,7 @@
"Credentials_test.cpp",
"DereferenceSurfaceControl_test.cpp",
"DisplayConfigs_test.cpp",
+ "DisplayEventReceiver_test.cpp",
"EffectLayer_test.cpp",
"InvalidHandles_test.cpp",
"LayerCallback_test.cpp",
@@ -47,6 +48,7 @@
"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/DisplayEventReceiver_test.cpp b/services/surfaceflinger/tests/DisplayEventReceiver_test.cpp
new file mode 100644
index 0000000..01adbc8
--- /dev/null
+++ b/services/surfaceflinger/tests/DisplayEventReceiver_test.cpp
@@ -0,0 +1,53 @@
+/*
+ * 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>
+
+namespace android {
+
+class DisplayEventReceiverTest : public ::testing::Test {
+public:
+ void SetUp() override { EXPECT_EQ(NO_ERROR, mDisplayEventReceiver.initCheck()); }
+
+ DisplayEventReceiver mDisplayEventReceiver;
+};
+
+TEST_F(DisplayEventReceiverTest, getLatestVsyncEventData) {
+ const nsecs_t now = systemTime();
+ VsyncEventData vsyncEventData;
+ EXPECT_EQ(NO_ERROR, mDisplayEventReceiver.getLatestVsyncEventData(&vsyncEventData));
+
+ EXPECT_NE(std::numeric_limits<size_t>::max(), vsyncEventData.preferredFrameTimelineIndex);
+ EXPECT_GT(vsyncEventData.frameTimelines[0].deadlineTimestamp, now)
+ << "Deadline timestamp should be greater than frame time";
+ for (size_t i = 0; i < vsyncEventData.frameTimelines.size(); i++) {
+ EXPECT_NE(FrameTimelineInfo::INVALID_VSYNC_ID, vsyncEventData.frameTimelines[i].id);
+ EXPECT_GT(vsyncEventData.frameTimelines[i].expectedPresentTime,
+ vsyncEventData.frameTimelines[i].deadlineTimestamp)
+ << "Expected vsync timestamp should be greater than deadline";
+ if (i > 0) {
+ EXPECT_GT(vsyncEventData.frameTimelines[i].deadlineTimestamp,
+ vsyncEventData.frameTimelines[i - 1].deadlineTimestamp)
+ << "Deadline timestamp out of order for frame timeline " << i;
+ EXPECT_GT(vsyncEventData.frameTimelines[i].expectedPresentTime,
+ vsyncEventData.frameTimelines[i - 1].expectedPresentTime)
+ << "Expected vsync timestamp out of order for frame timeline " << i;
+ }
+ }
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/SetFrameRateOverride_test.cpp b/services/surfaceflinger/tests/SetFrameRateOverride_test.cpp
new file mode 100644
index 0000000..4efec77
--- /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/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 3716f59..1669075 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -61,6 +61,8 @@
using hal::PowerMode;
using hal::Transform;
+using aidl::android::hardware::graphics::composer3::Capability;
+
using testing::_;
using testing::AtLeast;
using testing::DoAll;
@@ -169,7 +171,7 @@
template <typename Case>
void captureScreenComposition();
- std::unordered_set<hal::Capability> mDefaultCapabilities = {hal::Capability::SIDEBAND_STREAM};
+ std::unordered_set<Capability> mDefaultCapabilities = {Capability::SIDEBAND_STREAM};
bool mDisplayOff = false;
TestableSurfaceFlinger mFlinger;
diff --git a/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp b/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp
index f613e43..0b6b475 100644
--- a/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp
@@ -28,6 +28,7 @@
#include "AsyncCallRecorder.h"
#include "Scheduler/DispSyncSource.h"
#include "Scheduler/VSyncDispatch.h"
+#include "mock/MockVSyncTracker.h"
namespace android {
namespace {
@@ -125,16 +126,16 @@
DispSyncSourceTest();
~DispSyncSourceTest() override;
- void createDispSync();
+ void SetUp() override;
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<mock::VSyncTracker> mVSyncTracker;
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,21 +156,21 @@
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) {
- ALOGD("onVSyncEvent: %" PRId64, when);
-
- mVSyncEventCallRecorder.recordCall(when, expectedVSyncTimestamp, deadlineTimestamp);
+void DispSyncSourceTest::SetUp() {
+ mVSyncDispatch = std::make_unique<MockVSyncDispatch>();
+ mVSyncTracker = std::make_unique<mock::VSyncTracker>();
}
-void DispSyncSourceTest::createDispSync() {
- mVSyncDispatch = std::make_unique<MockVSyncDispatch>();
+void DispSyncSourceTest::onVSyncEvent(nsecs_t when, VSyncSource::VSyncData vsyncData) {
+ ALOGD("onVSyncEvent: %" PRId64, when);
+
+ mVSyncEventCallRecorder.recordCall(when, vsyncData);
}
void DispSyncSourceTest::createDispSyncSource() {
- mDispSyncSource =
- std::make_unique<scheduler::DispSyncSource>(*mVSyncDispatch, mWorkDuration,
- mReadyDuration, true, mName.c_str());
+ mDispSyncSource = std::make_unique<scheduler::DispSyncSource>(*mVSyncDispatch, *mVSyncTracker,
+ mWorkDuration, mReadyDuration,
+ true, mName.c_str());
mDispSyncSource->setCallback(this);
}
@@ -178,13 +179,10 @@
*/
TEST_F(DispSyncSourceTest, createDispSync) {
- createDispSync();
EXPECT_TRUE(mVSyncDispatch);
}
TEST_F(DispSyncSourceTest, createDispSyncSource) {
- createDispSync();
-
InSequence seq;
EXPECT_CALL(*mVSyncDispatch, registerCallback(_, mName)).WillOnce(Return(mFakeToken));
EXPECT_CALL(*mVSyncDispatch, cancel(mFakeToken))
@@ -196,8 +194,6 @@
}
TEST_F(DispSyncSourceTest, noCallbackAfterInit) {
- createDispSync();
-
InSequence seq;
EXPECT_CALL(*mVSyncDispatch, registerCallback(_, mName)).Times(1);
EXPECT_CALL(*mVSyncDispatch, cancel(_)).Times(1);
@@ -212,8 +208,6 @@
}
TEST_F(DispSyncSourceTest, waitForCallbacks) {
- createDispSync();
-
InSequence seq;
EXPECT_CALL(*mVSyncDispatch, registerCallback(_, mName)).Times(1);
EXPECT_CALL(*mVSyncDispatch,
@@ -233,14 +227,14 @@
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());
}
}
TEST_F(DispSyncSourceTest, waitForCallbacksWithDurationChange) {
- createDispSync();
-
InSequence seq;
EXPECT_CALL(*mVSyncDispatch, registerCallback(_, mName)).Times(1);
EXPECT_CALL(*mVSyncDispatch,
@@ -265,8 +259,10 @@
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,13 +282,35 @@
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);
EXPECT_CALL(*mVSyncDispatch, unregisterCallback(_)).Times(1);
}
+TEST_F(DispSyncSourceTest, getLatestVsyncData) {
+ const nsecs_t now = systemTime();
+ const nsecs_t vsyncInternalDuration = mWorkDuration.count() + mReadyDuration.count();
+ EXPECT_CALL(*mVSyncTracker, nextAnticipatedVSyncTimeFrom(_))
+ .WillOnce(Return(now + vsyncInternalDuration + 1));
+ {
+ InSequence seq;
+ EXPECT_CALL(*mVSyncDispatch, registerCallback(_, mName)).Times(1);
+ EXPECT_CALL(*mVSyncDispatch, cancel(_)).Times(1);
+ EXPECT_CALL(*mVSyncDispatch, unregisterCallback(_)).Times(1);
+ }
+
+ createDispSyncSource();
+ EXPECT_TRUE(mDispSyncSource);
+
+ const auto vsyncData = mDispSyncSource->getLatestVSyncData();
+ ASSERT_GT(vsyncData.deadlineTimestamp, now);
+ ASSERT_GT(vsyncData.expectedVSyncTimestamp, vsyncData.deadlineTimestamp);
+ EXPECT_EQ(vsyncData.deadlineTimestamp,
+ vsyncData.expectedVSyncTimestamp - vsyncInternalDuration);
+}
+
} // namespace
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
index 67a0d7e..cc0a40f 100644
--- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
+++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
@@ -59,6 +59,7 @@
void(std::chrono::nanoseconds workDuration,
std::chrono::nanoseconds readyDuration));
MOCK_METHOD1(pauseVsyncCallback, void(bool));
+ MOCK_METHOD(VSyncSource::VSyncData, getLatestVSyncData, (), (const, override));
MOCK_CONST_METHOD1(dump, void(std::string&));
};
@@ -257,7 +258,7 @@
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 < VsyncEventData::kFrameTimelinesLength; i++) {
auto prediction =
mTokenManager->getPredictionsForToken(event.vsync.frameTimelines[i].vsyncId);
EXPECT_TRUE(prediction.has_value());
@@ -275,17 +276,16 @@
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;
}
}
}
@@ -333,6 +333,8 @@
namespace {
+using namespace testing;
+
/* ------------------------------------------------------------------------
* Test cases
*/
@@ -369,7 +371,7 @@
// 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 +379,7 @@
// 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,11 +397,57 @@
// 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);
}
+TEST_F(EventThreadTest, getLatestVsyncEventData) {
+ const nsecs_t now = systemTime();
+ const nsecs_t preferredDeadline = now + 10000000;
+ const nsecs_t preferredExpectedVSyncTimestamp = now + 20000000;
+ const VSyncSource::VSyncData preferredData = {preferredExpectedVSyncTimestamp,
+ preferredDeadline};
+ EXPECT_CALL(*mVSyncSource, getLatestVSyncData()).WillOnce(Return(preferredData));
+
+ VsyncEventData vsyncEventData = mThread->getLatestVsyncEventData(mConnection);
+ EXPECT_GT(vsyncEventData.frameTimelines[0].deadlineTimestamp, now)
+ << "Deadline timestamp should be greater than frame time";
+ for (size_t i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
+ auto prediction =
+ mTokenManager->getPredictionsForToken(vsyncEventData.frameTimelines[i].id);
+ EXPECT_TRUE(prediction.has_value());
+ EXPECT_EQ(prediction.value().endTime, vsyncEventData.frameTimelines[i].deadlineTimestamp)
+ << "Deadline timestamp does not match cached value";
+ EXPECT_EQ(prediction.value().presentTime,
+ vsyncEventData.frameTimelines[i].expectedPresentTime)
+ << "Expected vsync timestamp does not match cached value";
+ EXPECT_GT(vsyncEventData.frameTimelines[i].expectedPresentTime,
+ vsyncEventData.frameTimelines[i].deadlineTimestamp)
+ << "Expected vsync timestamp should be greater than deadline";
+
+ if (i > 0) {
+ EXPECT_GT(vsyncEventData.frameTimelines[i].deadlineTimestamp,
+ vsyncEventData.frameTimelines[i - 1].deadlineTimestamp)
+ << "Deadline timestamp out of order for frame timeline " << i;
+ EXPECT_GT(vsyncEventData.frameTimelines[i].expectedPresentTime,
+ vsyncEventData.frameTimelines[i - 1].expectedPresentTime)
+ << "Expected vsync timestamp out of order for frame timeline " << i;
+ }
+
+ // Vsync ID order lines up with registration into test token manager.
+ EXPECT_EQ(i, vsyncEventData.frameTimelines[i].id)
+ << "Vsync ID incorrect for frame timeline " << i;
+ if (i == vsyncEventData.preferredFrameTimelineIndex) {
+ EXPECT_EQ(vsyncEventData.frameTimelines[i].deadlineTimestamp, preferredDeadline)
+ << "Preferred deadline timestamp incorrect" << i;
+ EXPECT_EQ(vsyncEventData.frameTimelines[i].expectedPresentTime,
+ preferredExpectedVSyncTimestamp)
+ << "Preferred expected vsync timestamp incorrect" << i;
+ }
+ }
+}
+
TEST_F(EventThreadTest, setVsyncRateZeroPostsNoVSyncEventsToThatConnection) {
// Create a first connection, register it, and request a vsync rate of zero.
ConnectionEventRecorder firstConnectionEventRecorder{0};
@@ -422,7 +470,7 @@
// 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 +485,19 @@
// 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 +510,25 @@
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 +543,7 @@
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 +561,13 @@
// 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 +592,7 @@
// 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 +610,13 @@
// 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 +740,7 @@
// 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 +748,7 @@
// 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/HWComposerTest.cpp b/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
index 0069441..5241604 100644
--- a/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
@@ -48,6 +48,7 @@
namespace V2_1 = hardware::graphics::composer::V2_1;
namespace V2_4 = hardware::graphics::composer::V2_4;
+namespace aidl = aidl::android::hardware::graphics::composer3;
using Hwc2::Config;
@@ -103,7 +104,7 @@
const std::string kMetadata2Name = "com.example.metadata.2";
constexpr bool kMetadata2Mandatory = true;
- EXPECT_CALL(*mHal, getCapabilities()).WillOnce(Return(std::vector<hal::Capability>{}));
+ EXPECT_CALL(*mHal, getCapabilities()).WillOnce(Return(std::vector<aidl::Capability>{}));
EXPECT_CALL(*mHal, getLayerGenericMetadataKeys(_))
.WillOnce(DoAll(SetArgPointee<0>(std::vector<hal::LayerGenericMetadataKey>{
{kMetadata1Name, kMetadata1Mandatory},
@@ -124,7 +125,7 @@
}
TEST_F(HWComposerSetCallbackTest, handlesUnsupportedCallToGetLayerGenericMetadataKeys) {
- EXPECT_CALL(*mHal, getCapabilities()).WillOnce(Return(std::vector<hal::Capability>{}));
+ EXPECT_CALL(*mHal, getCapabilities()).WillOnce(Return(std::vector<aidl::Capability>{}));
EXPECT_CALL(*mHal, getLayerGenericMetadataKeys(_))
.WillOnce(Return(hardware::graphics::composer::V2_4::Error::UNSUPPORTED));
EXPECT_CALL(*mHal, registerCallback(_));
@@ -140,7 +141,7 @@
static constexpr hal::HWDisplayId kDisplayId = static_cast<hal::HWDisplayId>(1001);
static constexpr hal::HWLayerId kLayerId = static_cast<hal::HWLayerId>(1002);
- HWComposerLayerTest(const std::unordered_set<hal::Capability>& capabilities)
+ HWComposerLayerTest(const std::unordered_set<aidl::Capability>& capabilities)
: mCapabilies(capabilities) {
EXPECT_CALL(mDisplay, getId()).WillRepeatedly(Return(kDisplayId));
}
@@ -151,7 +152,7 @@
}
std::unique_ptr<Hwc2::mock::Composer> mHal{new StrictMock<Hwc2::mock::Composer>()};
- const std::unordered_set<hal::Capability> mCapabilies;
+ const std::unordered_set<aidl::Capability> mCapabilies;
StrictMock<HWC2::mock::Display> mDisplay;
HWC2::impl::Layer mLayer{*mHal, mCapabilies, mDisplay, kLayerId};
};
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 4fe1e98..8cadb31 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -526,9 +526,11 @@
* preconditions and assert post-conditions.
*/
struct HWC2Display : public HWC2::impl::Display {
- HWC2Display(Hwc2::Composer& composer,
- const std::unordered_set<hal::Capability>& capabilities, hal::HWDisplayId id,
- hal::DisplayType type)
+ HWC2Display(
+ Hwc2::Composer& composer,
+ const std::unordered_set<aidl::android::hardware::graphics::composer3::Capability>&
+ capabilities,
+ hal::HWDisplayId id, hal::DisplayType type)
: HWC2::impl::Display(composer, capabilities, id, type) {}
~HWC2Display() {
// Prevents a call to disable vsyncs.
@@ -589,7 +591,9 @@
return *this;
}
- auto& setCapabilities(const std::unordered_set<hal::Capability>* capabilities) {
+ auto& setCapabilities(
+ const std::unordered_set<aidl::android::hardware::graphics::composer3::Capability>*
+ capabilities) {
mCapabilities = capabilities;
return *this;
}
@@ -605,7 +609,9 @@
using ::testing::Return;
using ::testing::SetArgPointee;
- static const std::unordered_set<hal::Capability> defaultCapabilities;
+ static const std::unordered_set<
+ aidl::android::hardware::graphics::composer3::Capability>
+ defaultCapabilities;
if (mCapabilities == nullptr) mCapabilities = &defaultCapabilities;
// Caution - Make sure that any values passed by reference here do
@@ -682,7 +688,8 @@
int32_t mConfigGroup = DEFAULT_CONFIG_GROUP;
hal::HWConfigId mActiveConfig = DEFAULT_ACTIVE_CONFIG;
hal::PowerMode mPowerMode = DEFAULT_POWER_MODE;
- const std::unordered_set<hal::Capability>* mCapabilities = nullptr;
+ const std::unordered_set<aidl::android::hardware::graphics::composer3::Capability>*
+ mCapabilities = nullptr;
};
class FakeDisplayDeviceInjector {
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
index 0765d5b..ce9ec96 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -50,7 +50,8 @@
~Composer() override;
MOCK_METHOD(bool, isSupported, (OptionalFeature), (const, override));
- MOCK_METHOD0(getCapabilities, std::vector<IComposer::Capability>());
+ MOCK_METHOD0(getCapabilities,
+ std::vector<aidl::android::hardware::graphics::composer3::Capability>());
MOCK_METHOD0(dumpDebugInfo, std::string());
MOCK_METHOD1(registerCallback, void(HWC2::ComposerCallback&));
MOCK_METHOD0(resetCommands, void());
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
index d25973e..c5ca86a 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
@@ -44,6 +44,8 @@
status_t(const sp<android::EventThreadConnection> &));
MOCK_METHOD2(setVsyncRate, void(uint32_t, const sp<android::EventThreadConnection> &));
MOCK_METHOD1(requestNextVsync, void(const sp<android::EventThreadConnection> &));
+ MOCK_METHOD(VsyncEventData, getLatestVsyncEventData,
+ (const sp<android::EventThreadConnection> &), (const));
MOCK_METHOD1(requestLatestConfig, void(const sp<android::EventThreadConnection> &));
MOCK_METHOD1(pauseVsyncCallback, void(bool));
MOCK_METHOD0(getEventThreadConnectionCount, size_t());