Merge "Add smooth switch bool for setFrameRateCategory" into main
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index aa67869..9f091ef 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -29,7 +29,6 @@
#include <binder/Parcel.h>
#include <binder/RecordedTransaction.h>
#include <binder/RpcServer.h>
-#include <private/android_filesystem_config.h>
#include <pthread.h>
#include <utils/misc.h>
@@ -45,6 +44,8 @@
namespace android {
+constexpr uid_t kUidRoot = 0;
+
// Service implementations inherit from BBinder and IBinder, and this is frozen
// in prebuilts.
#ifdef __LP64__
@@ -300,7 +301,7 @@
return INVALID_OPERATION;
}
uid_t uid = IPCThreadState::self()->getCallingUid();
- if (uid != AID_ROOT) {
+ if (uid != kUidRoot) {
ALOGE("Binder recording not allowed because client %" PRIu32 " is not root", uid);
return PERMISSION_DENIED;
}
@@ -330,7 +331,7 @@
return INVALID_OPERATION;
}
uid_t uid = IPCThreadState::self()->getCallingUid();
- if (uid != AID_ROOT) {
+ if (uid != kUidRoot) {
ALOGE("Binder recording not allowed because client %" PRIu32 " is not root", uid);
return PERMISSION_DENIED;
}
@@ -634,7 +635,7 @@
return INVALID_OPERATION;
}
uid_t uid = IPCThreadState::self()->getCallingUid();
- if (uid != AID_ROOT) {
+ if (uid != kUidRoot) {
ALOGE("%s: not allowed because client %" PRIu32 " is not root", __PRETTY_FUNCTION__, uid);
return PERMISSION_DENIED;
}
diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp
index f7dd9c9..47da296 100644
--- a/libs/binder/ndk/ibinder.cpp
+++ b/libs/binder/ndk/ibinder.cpp
@@ -21,7 +21,9 @@
#include <android/binder_status.h>
#include <binder/IPCThreadState.h>
#include <binder/IResultReceiver.h>
+#if __has_include(<private/android_filesystem_config.h>)
#include <private/android_filesystem_config.h>
+#endif
#include "ibinder_internal.h"
#include "parcel_internal.h"
@@ -229,7 +231,11 @@
// Shell commands should only be callable by ADB.
uid_t uid = AIBinder_getCallingUid();
- if (uid != AID_ROOT && uid != AID_SHELL) {
+ if (uid != 0 /* root */
+#ifdef AID_SHELL
+ && uid != AID_SHELL
+#endif
+ ) {
if (resultReceiver != nullptr) {
resultReceiver->send(-1);
}
diff --git a/libs/binder/ndk/tests/iface.cpp b/libs/binder/ndk/tests/iface.cpp
index 76acff5..3ee36cd 100644
--- a/libs/binder/ndk/tests/iface.cpp
+++ b/libs/binder/ndk/tests/iface.cpp
@@ -156,7 +156,10 @@
}
sp<IFoo> IFoo::getService(const char* instance, AIBinder** outBinder) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
AIBinder* binder = AServiceManager_getService(instance); // maybe nullptr
+#pragma clang diagnostic pop
if (binder == nullptr) {
return nullptr;
}
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index 15708ca..cab1a60 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -341,7 +341,10 @@
// libbinder across processes to the NDK service which doesn't implement
// shell
static const sp<android::IServiceManager> sm(android::defaultServiceManager());
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
sp<IBinder> testService = sm->getService(String16(IFoo::kSomeInstanceName));
+#pragma clang diagnostic pop
Vector<String16> argsVec;
EXPECT_EQ(OK, IBinder::shellCommand(testService, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO,
@@ -384,7 +387,10 @@
// checkService on it, since the other process serving it might not be started yet.
{
// getService, not waitForService, to take advantage of timeout
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
auto binder = ndk::SpAIBinder(AServiceManager_getService(IFoo::kSomeInstanceName));
+#pragma clang diagnostic pop
ASSERT_NE(nullptr, binder.get());
}
@@ -574,7 +580,10 @@
}
TEST(NdkBinder, RetrieveNonNdkService) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
+#pragma clang diagnostic pop
ASSERT_NE(nullptr, binder);
EXPECT_TRUE(AIBinder_isRemote(binder));
EXPECT_TRUE(AIBinder_isAlive(binder));
@@ -588,7 +597,10 @@
}
TEST(NdkBinder, LinkToDeath) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
+#pragma clang diagnostic pop
ASSERT_NE(nullptr, binder);
AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(OnBinderDeath);
@@ -618,7 +630,10 @@
}
TEST(NdkBinder, SetInheritRtNonLocal) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
+#pragma clang diagnostic pop
ASSERT_NE(binder, nullptr);
ASSERT_TRUE(AIBinder_isRemote(binder));
@@ -654,11 +669,14 @@
}
TEST(NdkBinder, EqualityOfRemoteBinderPointer) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
AIBinder* binderA = AServiceManager_getService(kExistingNonNdkService);
ASSERT_NE(nullptr, binderA);
AIBinder* binderB = AServiceManager_getService(kExistingNonNdkService);
ASSERT_NE(nullptr, binderB);
+#pragma clang diagnostic pop
EXPECT_EQ(binderA, binderB);
@@ -672,7 +690,10 @@
}
TEST(NdkBinder, ABpBinderRefCount) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
+#pragma clang diagnostic pop
AIBinder_Weak* wBinder = AIBinder_Weak_new(binder);
ASSERT_NE(nullptr, binder);
@@ -695,7 +716,10 @@
}
TEST(NdkBinder, RequestedSidWorks) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService));
+#pragma clang diagnostic pop
std::shared_ptr<aidl::IBinderNdkUnitTest> service =
aidl::IBinderNdkUnitTest::fromBinder(binder);
@@ -718,7 +742,10 @@
std::shared_ptr<MyEmpty> empty = ndk::SharedRefBase::make<MyEmpty>();
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService));
+#pragma clang diagnostic pop
std::shared_ptr<aidl::IBinderNdkUnitTest> service =
aidl::IBinderNdkUnitTest::fromBinder(binder);
@@ -741,7 +768,10 @@
TEST(NdkBinder, ConvertToPlatformBinder) {
for (const ndk::SpAIBinder& binder :
{// remote
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
ndk::SpAIBinder(AServiceManager_getService(kBinderNdkUnitTestService)),
+#pragma clang diagnostic pop
// local
ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder()}) {
// convert to platform binder
@@ -774,7 +804,10 @@
TEST(NdkBinder, GetAndVerifyScopedAIBinder_Weak) {
for (const ndk::SpAIBinder& binder :
{// remote
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
ndk::SpAIBinder(AServiceManager_getService(kBinderNdkUnitTestService)),
+#pragma clang diagnostic pop
// local
ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder()}) {
// get a const ScopedAIBinder_Weak and verify promote
@@ -869,7 +902,10 @@
TEST(NdkBinder, UseHandleShellCommand) {
static const sp<android::IServiceManager> sm(android::defaultServiceManager());
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
sp<IBinder> testService = sm->getService(String16(kBinderNdkUnitTestService));
+#pragma clang diagnostic pop
EXPECT_EQ("", shellCmdToString(testService, {}));
EXPECT_EQ("", shellCmdToString(testService, {"", ""}));
@@ -879,7 +915,10 @@
TEST(NdkBinder, FlaggedServiceAccessible) {
static const sp<android::IServiceManager> sm(android::defaultServiceManager());
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
sp<IBinder> testService = sm->getService(String16(kBinderNdkUnitTestServiceFlagged));
+#pragma clang diagnostic pop
ASSERT_NE(nullptr, testService);
}
diff --git a/libs/binder/rust/tests/serialization.hpp b/libs/binder/rust/tests/serialization.hpp
index 0041608..9edcd6d 100644
--- a/libs/binder/rust/tests/serialization.hpp
+++ b/libs/binder/rust/tests/serialization.hpp
@@ -14,7 +14,10 @@
* limitations under the License.
*/
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpragma-once-outside-header"
#pragma once
+#pragma clang diagnostic pop
#include <binder/IBinder.h>
diff --git a/libs/binder/servicedispatcher.cpp b/libs/binder/servicedispatcher.cpp
index 8e95d69..5bf9680 100644
--- a/libs/binder/servicedispatcher.cpp
+++ b/libs/binder/servicedispatcher.cpp
@@ -279,7 +279,10 @@
while (-1 != (opt = getopt(argc, argv, "gi:"))) {
switch (opt) {
case 'g': {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
serviceRetriever = &android::IServiceManager::getService;
+#pragma clang diagnostic pop
} break;
case 'i': {
ip_address = optarg;
diff --git a/libs/binder/tests/binderClearBufTest.cpp b/libs/binder/tests/binderClearBufTest.cpp
index 307151c..3ea5b55 100644
--- a/libs/binder/tests/binderClearBufTest.cpp
+++ b/libs/binder/tests/binderClearBufTest.cpp
@@ -74,7 +74,10 @@
};
TEST(BinderClearBuf, ClearKernelBuffer) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
sp<IBinder> binder = defaultServiceManager()->getService(kServerName);
+#pragma clang diagnostic pop
ASSERT_NE(nullptr, binder);
std::string replyBuffer;
diff --git a/libs/binder/tests/binderHostDeviceTest.cpp b/libs/binder/tests/binderHostDeviceTest.cpp
index 77a5fa8..0075688 100644
--- a/libs/binder/tests/binderHostDeviceTest.cpp
+++ b/libs/binder/tests/binderHostDeviceTest.cpp
@@ -135,7 +135,10 @@
TEST_F(HostDeviceTest, GetService) {
auto sm = defaultServiceManager();
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
auto rpcBinder = sm->getService(String16(kServiceName));
+#pragma clang diagnostic pop
ASSERT_NE(nullptr, rpcBinder);
EXPECT_THAT(rpcBinder->pingBinder(), StatusEq(OK));
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 0396869..341e9ce 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -213,7 +213,10 @@
sp<IServiceManager> sm = defaultServiceManager();
//printf("%s: pid %d, get service\n", __func__, m_pid);
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
m_server = sm->getService(binderLibTestServiceName);
+#pragma clang diagnostic pop
ASSERT_TRUE(m_server != nullptr);
//printf("%s: pid %d, get service done\n", __func__, m_pid);
}
@@ -1107,6 +1110,7 @@
status_t ret;
data.writeInterfaceToken(binderLibTestServiceName);
ret = m_server->transact(BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION, data, &reply);
+ EXPECT_EQ(NO_ERROR, ret);
Parcel data2, reply2;
status_t ret2;
@@ -1595,9 +1599,8 @@
}
switch (code) {
case BINDER_LIB_TEST_REGISTER_SERVER: {
- int32_t id;
sp<IBinder> binder;
- id = data.readInt32();
+ /*id =*/data.readInt32();
binder = data.readStrongBinder();
if (binder == nullptr) {
return BAD_VALUE;
@@ -1993,7 +1996,10 @@
if (index == 0) {
ret = sm->addService(binderLibTestServiceName, testService);
} else {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
sp<IBinder> server = sm->getService(binderLibTestServiceName);
+#pragma clang diagnostic pop
Parcel data, reply;
data.writeInt32(index);
data.writeStrongBinder(testService);
diff --git a/libs/binder/tests/binderRecordReplayTest.cpp b/libs/binder/tests/binderRecordReplayTest.cpp
index 6773c95..d08a9bb 100644
--- a/libs/binder/tests/binderRecordReplayTest.cpp
+++ b/libs/binder/tests/binderRecordReplayTest.cpp
@@ -133,7 +133,10 @@
public:
void SetUp() override {
// get the remote service
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
auto binder = defaultServiceManager()->getService(kServerName);
+#pragma clang diagnostic pop
ASSERT_NE(nullptr, binder);
mInterface = interface_cast<IBinderRecordReplayTest>(binder);
mBpBinder = binder->remoteBinder();
diff --git a/libs/binder/tests/binderSafeInterfaceTest.cpp b/libs/binder/tests/binderSafeInterfaceTest.cpp
index 5e8a32a..1c13866 100644
--- a/libs/binder/tests/binderSafeInterfaceTest.cpp
+++ b/libs/binder/tests/binderSafeInterfaceTest.cpp
@@ -605,7 +605,10 @@
static constexpr const char* getLogTag() { return "SafeInterfaceTest"; }
sp<ISafeInterfaceTest> getRemoteService() {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
sp<IBinder> binder = defaultServiceManager()->getService(kServiceName);
+#pragma clang diagnostic pop
sp<ISafeInterfaceTest> iface = interface_cast<ISafeInterfaceTest>(binder);
EXPECT_TRUE(iface != nullptr);
diff --git a/libs/binder/tests/binderStabilityTest.cpp b/libs/binder/tests/binderStabilityTest.cpp
index 2398e1e..3d99358 100644
--- a/libs/binder/tests/binderStabilityTest.cpp
+++ b/libs/binder/tests/binderStabilityTest.cpp
@@ -155,7 +155,10 @@
}
TEST(BinderStability, ForceDowngradeToVendorStability) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
sp<IBinder> serverBinder = android::defaultServiceManager()->getService(kSystemStabilityServer);
+#pragma clang diagnostic pop
auto server = interface_cast<IBinderStabilityTest>(serverBinder);
ASSERT_NE(nullptr, server.get());
@@ -206,7 +209,10 @@
EXPECT_EQ(connectionInfo, std::nullopt);
}
TEST(BinderStability, CantCallVendorBinderInSystemContext) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
sp<IBinder> serverBinder = android::defaultServiceManager()->getService(kSystemStabilityServer);
+#pragma clang diagnostic pop
auto server = interface_cast<IBinderStabilityTest>(serverBinder);
ASSERT_NE(nullptr, server.get());
@@ -310,8 +316,11 @@
extern "C" void AIBinder_markVendorStability(AIBinder* binder); // <- BAD DO NOT COPY
TEST(BinderStability, NdkCantCallVendorBinderInSystemContext) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
SpAIBinder binder = SpAIBinder(AServiceManager_getService(
String8(kSystemStabilityServer).c_str()));
+#pragma clang diagnostic pop
std::shared_ptr<aidl::IBinderStabilityTest> remoteServer =
aidl::IBinderStabilityTest::fromBinder(binder);
diff --git a/libs/binder/tests/binderThroughputTest.cpp b/libs/binder/tests/binderThroughputTest.cpp
index cfaf2a9..0ea4a3f 100644
--- a/libs/binder/tests/binderThroughputTest.cpp
+++ b/libs/binder/tests/binderThroughputTest.cpp
@@ -204,7 +204,10 @@
for (int i = 0; i < server_count; i++) {
if (num == i)
continue;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
workers.push_back(serviceMgr->getService(generateServiceName(i)));
+#pragma clang diagnostic pop
}
// Run the benchmark if client
diff --git a/libs/binder/tests/schd-dbg.cpp b/libs/binder/tests/schd-dbg.cpp
index 0035e4e..d3cd528 100644
--- a/libs/binder/tests/schd-dbg.cpp
+++ b/libs/binder/tests/schd-dbg.cpp
@@ -340,7 +340,10 @@
for (int i = 0; i < server_count; i++) {
// self service is in-process so just skip
if (num == i) continue;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
workers.push_back(serviceMgr->getService(generateServiceName(i)));
+#pragma clang diagnostic pop
}
// Client for each pair iterates here
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index d9d99a4..300ac2e 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -2605,6 +2605,7 @@
outMode.xDpi = mode.xDpi;
outMode.yDpi = mode.yDpi;
outMode.refreshRate = mode.refreshRate;
+ outMode.vsyncRate = mode.vsyncRate;
outMode.appVsyncOffset = mode.appVsyncOffset;
outMode.sfVsyncOffset = mode.sfVsyncOffset;
outMode.presentationDeadline = mode.presentationDeadline;
diff --git a/libs/gui/aidl/android/gui/DisplayMode.aidl b/libs/gui/aidl/android/gui/DisplayMode.aidl
index ce30426..b057653 100644
--- a/libs/gui/aidl/android/gui/DisplayMode.aidl
+++ b/libs/gui/aidl/android/gui/DisplayMode.aidl
@@ -29,7 +29,9 @@
float yDpi = 0.0f;
int[] supportedHdrTypes;
+ // Some modes have peak refresh rate lower than the panel vsync rate.
float refreshRate = 0.0f;
+ float vsyncRate = 0.0f;
long appVsyncOffset = 0;
long sfVsyncOffset = 0;
long presentationDeadline = 0;
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index ab4af1a..69a4f0a 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -46,6 +46,14 @@
name: "aconfig_input_flags_c_lib",
aconfig_declarations: "aconfig_input_flags",
host_supported: true,
+ // Use the test version of the aconfig flag library by default to allow tests to set local
+ // overrides for flags, without having to link against a separate version of libinput or of this
+ // library. Bundling this library directly into libinput prevents us from having to add this
+ // library as a shared lib dependency everywhere where libinput is used.
+ test: true,
+ shared: {
+ enabled: false,
+ },
}
aidl_interface {
diff --git a/libs/renderengine/skia/Cache.cpp b/libs/renderengine/skia/Cache.cpp
index 9d61d62..25296f0 100644
--- a/libs/renderengine/skia/Cache.cpp
+++ b/libs/renderengine/skia/Cache.cpp
@@ -49,6 +49,15 @@
// a color correction effect is added to the shader.
constexpr auto kDestDataSpace = ui::Dataspace::SRGB;
constexpr auto kOtherDataSpace = ui::Dataspace::DISPLAY_P3;
+constexpr auto kBT2020DataSpace = ui::Dataspace::BT2020_ITU_PQ;
+constexpr auto kExtendedHdrDataSpce =
+ static_cast<ui::Dataspace>(ui::Dataspace::RANGE_EXTENDED | ui::Dataspace::TRANSFER_SRGB |
+ ui::Dataspace::STANDARD_DCI_P3);
+// Dimming is needed to trigger linear effects for some dataspace pairs
+const std::array<float, 3> kLayerWhitePoints = {
+ 1000.0f, 500.0f,
+ 100.0f, // trigger dithering by dimming below 20%
+};
} // namespace
static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
@@ -317,6 +326,298 @@
renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
}
+static void drawImageDimmedLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
+ const std::shared_ptr<ExternalTexture>& dstTexture,
+ const std::shared_ptr<ExternalTexture>& srcTexture) {
+ const Rect& displayRect = display.physicalDisplay;
+ FloatRect rect(0, 0, displayRect.width(), displayRect.height());
+ LayerSettings layer{
+ .geometry =
+ Geometry{
+ // The position transform doesn't matter when the reduced shader mode
+ // in in effect. A matrix transform stage is always included.
+ .positionTransform = mat4(),
+ .boundaries = rect,
+ .roundedCornersCrop = rect,
+ .roundedCornersRadius = {0.f, 0.f},
+ },
+ .source = PixelSource{.buffer = Buffer{.buffer = srcTexture,
+ .maxLuminanceNits = 1000.f,
+ .usePremultipliedAlpha = true,
+ .isOpaque = true}},
+ .alpha = 1.f,
+ .sourceDataspace = kDestDataSpace,
+ };
+
+ std::vector<LayerSettings> layers;
+
+ for (auto layerWhitePoint : kLayerWhitePoints) {
+ layer.whitePointNits = layerWhitePoint;
+ layers.push_back(layer);
+ }
+ renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
+}
+
+static void drawTransparentImageDimmedLayers(SkiaRenderEngine* renderengine,
+ const DisplaySettings& display,
+ const std::shared_ptr<ExternalTexture>& dstTexture,
+ const std::shared_ptr<ExternalTexture>& srcTexture) {
+ const Rect& displayRect = display.physicalDisplay;
+ FloatRect rect(0, 0, displayRect.width(), displayRect.height());
+ LayerSettings layer{
+ .geometry =
+ Geometry{
+ .positionTransform = mat4(),
+ .boundaries = rect,
+ .roundedCornersCrop = rect,
+ },
+ .source = PixelSource{.buffer =
+ Buffer{
+ .buffer = srcTexture,
+ .maxLuminanceNits = 1000.f,
+ .usePremultipliedAlpha = true,
+ .isOpaque = false,
+ }},
+ .sourceDataspace = kDestDataSpace,
+ };
+
+ for (auto roundedCornerRadius : {0.f, 50.f}) {
+ layer.geometry.roundedCornersRadius = {roundedCornerRadius, roundedCornerRadius};
+ for (auto alpha : {0.5f, 1.0f}) {
+ layer.alpha = alpha;
+ for (auto isOpaque : {true, false}) {
+ if (roundedCornerRadius == 0.f && isOpaque) {
+ // already covered in drawImageDimmedLayers
+ continue;
+ }
+
+ layer.source.buffer.isOpaque = isOpaque;
+ std::vector<LayerSettings> layers;
+
+ for (auto layerWhitePoint : kLayerWhitePoints) {
+ layer.whitePointNits = layerWhitePoint;
+ layers.push_back(layer);
+ }
+ renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
+ }
+ }
+ }
+}
+
+static void drawClippedDimmedImageLayers(SkiaRenderEngine* renderengine,
+ const DisplaySettings& display,
+ const std::shared_ptr<ExternalTexture>& dstTexture,
+ const std::shared_ptr<ExternalTexture>& srcTexture) {
+ const Rect& displayRect = display.physicalDisplay;
+
+ // If rect and boundary is too small compared to roundedCornersRadius, Skia will switch to
+ // blending instead of EllipticalRRect, so enlarge them a bit.
+ FloatRect rect(0, 0, displayRect.width(), displayRect.height());
+ FloatRect boundary(0, 0, displayRect.width(),
+ displayRect.height() - 20); // boundary is smaller
+ LayerSettings layer{
+ .geometry =
+ Geometry{
+ .positionTransform = mat4(),
+ .boundaries = boundary,
+ .roundedCornersCrop = rect,
+ .roundedCornersRadius = {27.f, 27.f},
+ },
+ .source = PixelSource{.buffer =
+ Buffer{
+ .buffer = srcTexture,
+ .maxLuminanceNits = 1000.f,
+ .usePremultipliedAlpha = true,
+ .isOpaque = false,
+ }},
+ .alpha = 1.f,
+ .sourceDataspace = kDestDataSpace,
+ };
+
+ std::array<mat4, 2> transforms = {kScaleAndTranslate, kScaleAsymmetric};
+
+ constexpr float radius = 27.f;
+
+ for (size_t i = 0; i < transforms.size(); i++) {
+ layer.geometry.positionTransform = transforms[i];
+ layer.geometry.roundedCornersRadius = {radius, radius};
+
+ std::vector<LayerSettings> layers;
+
+ for (auto layerWhitePoint : kLayerWhitePoints) {
+ layer.whitePointNits = layerWhitePoint;
+ layers.push_back(layer);
+ }
+ renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
+ }
+}
+
+static void drawSolidDimmedLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
+ const std::shared_ptr<ExternalTexture>& dstTexture) {
+ const Rect& displayRect = display.physicalDisplay;
+ FloatRect rect(0, 0, displayRect.width(), displayRect.height());
+ LayerSettings layer{
+ .geometry =
+ Geometry{
+ .boundaries = rect,
+ .roundedCornersCrop = rect,
+ },
+ .source =
+ PixelSource{
+ .solidColor = half3(0.1f, 0.2f, 0.3f),
+ },
+ .alpha = 1.f,
+ };
+
+ std::vector<LayerSettings> layers;
+
+ for (auto layerWhitePoint : kLayerWhitePoints) {
+ layer.whitePointNits = layerWhitePoint;
+ layers.push_back(layer);
+ }
+ renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
+}
+
+static void drawBT2020ImageLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
+ const std::shared_ptr<ExternalTexture>& dstTexture,
+ const std::shared_ptr<ExternalTexture>& srcTexture) {
+ const Rect& displayRect = display.physicalDisplay;
+ FloatRect rect(0, 0, displayRect.width(), displayRect.height());
+ LayerSettings layer{
+ .geometry =
+ Geometry{
+ // The position transform doesn't matter when the reduced shader mode
+ // in in effect. A matrix transform stage is always included.
+ .positionTransform = mat4(),
+ .boundaries = rect,
+ .roundedCornersCrop = rect,
+ .roundedCornersRadius = {0.f, 0.f},
+ },
+ .source = PixelSource{.buffer = Buffer{.buffer = srcTexture,
+ .maxLuminanceNits = 1000.f,
+ .usePremultipliedAlpha = true,
+ .isOpaque = true}},
+ .alpha = 1.f,
+ .sourceDataspace = kBT2020DataSpace,
+ };
+
+ for (auto alpha : {0.5f, 1.f}) {
+ layer.alpha = alpha;
+ std::vector<LayerSettings> layers;
+ layer.whitePointNits = -1.f;
+ layers.push_back(layer);
+
+ renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
+ }
+}
+static void drawBT2020ClippedImageLayers(SkiaRenderEngine* renderengine,
+ const DisplaySettings& display,
+ const std::shared_ptr<ExternalTexture>& dstTexture,
+ const std::shared_ptr<ExternalTexture>& srcTexture) {
+ const Rect& displayRect = display.physicalDisplay;
+
+ // If rect and boundary is too small compared to roundedCornersRadius, Skia will switch to
+ // blending instead of EllipticalRRect, so enlarge them a bit.
+ FloatRect rect(0, 0, displayRect.width(), displayRect.height());
+ FloatRect boundary(0, 0, displayRect.width(),
+ displayRect.height() - 10); // boundary is smaller
+ LayerSettings layer{
+ .geometry =
+ Geometry{
+ .positionTransform = kScaleAsymmetric,
+ .boundaries = boundary,
+ .roundedCornersCrop = rect,
+ .roundedCornersRadius = {64.1f, 64.1f},
+ },
+ .source = PixelSource{.buffer =
+ Buffer{
+ .buffer = srcTexture,
+ .maxLuminanceNits = 1000.f,
+ .usePremultipliedAlpha = true,
+ .isOpaque = true,
+ }},
+ .alpha = 0.5f,
+ .sourceDataspace = kBT2020DataSpace,
+ };
+
+ std::vector<LayerSettings> layers = {layer};
+ renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
+}
+
+static void drawExtendedHDRImageLayers(SkiaRenderEngine* renderengine,
+ const DisplaySettings& display,
+ const std::shared_ptr<ExternalTexture>& dstTexture,
+ const std::shared_ptr<ExternalTexture>& srcTexture) {
+ const Rect& displayRect = display.physicalDisplay;
+ FloatRect rect(0, 0, displayRect.width(), displayRect.height());
+ LayerSettings layer{
+ .geometry =
+ Geometry{
+ // The position transform doesn't matter when the reduced shader mode
+ // in in effect. A matrix transform stage is always included.
+ .positionTransform = mat4(),
+ .boundaries = rect,
+ .roundedCornersCrop = rect,
+ .roundedCornersRadius = {50.f, 50.f},
+ },
+ .source = PixelSource{.buffer = Buffer{.buffer = srcTexture,
+ .maxLuminanceNits = 1000.f,
+ .usePremultipliedAlpha = true,
+ .isOpaque = true}},
+ .alpha = 0.5f,
+ .sourceDataspace = kExtendedHdrDataSpce,
+ };
+
+ for (auto roundedCornerRadius : {0.f, 50.f}) {
+ layer.geometry.roundedCornersRadius = {roundedCornerRadius, roundedCornerRadius};
+ for (auto alpha : {0.5f, 1.f}) {
+ layer.alpha = alpha;
+ std::vector<LayerSettings> layers;
+
+ for (auto layerWhitePoint : kLayerWhitePoints) {
+ layer.whitePointNits = layerWhitePoint;
+ layers.push_back(layer);
+ }
+ renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
+ }
+ }
+}
+
+static void drawP3ImageLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
+ const std::shared_ptr<ExternalTexture>& dstTexture,
+ const std::shared_ptr<ExternalTexture>& srcTexture) {
+ const Rect& displayRect = display.physicalDisplay;
+ FloatRect rect(0, 0, displayRect.width(), displayRect.height());
+ LayerSettings layer{
+ .geometry =
+ Geometry{
+ // The position transform doesn't matter when the reduced shader mode
+ // in in effect. A matrix transform stage is always included.
+ .positionTransform = mat4(),
+ .boundaries = rect,
+ .roundedCornersCrop = rect,
+ .roundedCornersRadius = {50.f, 50.f},
+ },
+ .source = PixelSource{.buffer = Buffer{.buffer = srcTexture,
+ .maxLuminanceNits = 1000.f,
+ .usePremultipliedAlpha = true,
+ .isOpaque = false}},
+ .alpha = 0.5f,
+ .sourceDataspace = kOtherDataSpace,
+ };
+
+ for (auto alpha : {0.5f, 1.f}) {
+ layer.alpha = alpha;
+ std::vector<LayerSettings> layers;
+
+ for (auto layerWhitePoint : kLayerWhitePoints) {
+ layer.whitePointNits = layerWhitePoint;
+ layers.push_back(layer);
+ }
+ renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
+ }
+}
+
//
// The collection of shaders cached here were found by using perfetto to record shader compiles
// during actions that involve RenderEngine, logging the layer settings, and the shader code
@@ -353,6 +654,23 @@
.maxLuminance = 500,
.outputDataspace = kOtherDataSpace,
};
+ DisplaySettings p3DisplayEnhance{.physicalDisplay = displayRect,
+ .clip = displayRect,
+ .maxLuminance = 500,
+ .outputDataspace = kOtherDataSpace,
+ .dimmingStage = aidl::android::hardware::graphics::
+ composer3::DimmingStage::GAMMA_OETF,
+ .renderIntent = aidl::android::hardware::graphics::
+ composer3::RenderIntent::ENHANCE};
+ DisplaySettings bt2020Display{.physicalDisplay = displayRect,
+ .clip = displayRect,
+ .maxLuminance = 500,
+ .outputDataspace = ui::Dataspace::BT2020,
+ .deviceHandlesColorTransform = true,
+ .dimmingStage = aidl::android::hardware::graphics::composer3::
+ DimmingStage::GAMMA_OETF,
+ .renderIntent = aidl::android::hardware::graphics::composer3::
+ RenderIntent::TONE_MAP_ENHANCE};
const int64_t usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
@@ -377,6 +695,8 @@
impl::ExternalTexture::Usage::WRITEABLE);
drawHolePunchLayer(renderengine, display, dstTexture);
drawSolidLayers(renderengine, display, dstTexture);
+ drawSolidLayers(renderengine, p3Display, dstTexture);
+ drawSolidDimmedLayers(renderengine, display, dstTexture);
drawShadowLayers(renderengine, display, srcTexture);
drawShadowLayers(renderengine, p3Display, srcTexture);
@@ -417,12 +737,35 @@
for (auto texture : textures) {
drawImageLayers(renderengine, display, dstTexture, texture);
+
+ drawImageDimmedLayers(renderengine, display, dstTexture, texture);
+ drawImageDimmedLayers(renderengine, p3Display, dstTexture, texture);
+ drawImageDimmedLayers(renderengine, bt2020Display, dstTexture, texture);
+
// Draw layers for b/185569240.
drawClippedLayers(renderengine, display, dstTexture, texture);
}
drawPIPImageLayer(renderengine, display, dstTexture, externalTexture);
+ drawTransparentImageDimmedLayers(renderengine, bt2020Display, dstTexture, externalTexture);
+ drawTransparentImageDimmedLayers(renderengine, display, dstTexture, externalTexture);
+ drawTransparentImageDimmedLayers(renderengine, p3Display, dstTexture, externalTexture);
+ drawTransparentImageDimmedLayers(renderengine, p3DisplayEnhance, dstTexture,
+ externalTexture);
+
+ drawClippedDimmedImageLayers(renderengine, bt2020Display, dstTexture, externalTexture);
+ drawBT2020ClippedImageLayers(renderengine, bt2020Display, dstTexture, externalTexture);
+
+ drawBT2020ImageLayers(renderengine, bt2020Display, dstTexture, externalTexture);
+ drawBT2020ImageLayers(renderengine, p3Display, dstTexture, externalTexture);
+
+ drawExtendedHDRImageLayers(renderengine, display, dstTexture, externalTexture);
+ drawExtendedHDRImageLayers(renderengine, p3Display, dstTexture, externalTexture);
+ drawExtendedHDRImageLayers(renderengine, p3DisplayEnhance, dstTexture, externalTexture);
+
+ drawP3ImageLayers(renderengine, p3DisplayEnhance, dstTexture, externalTexture);
+
// draw one final layer synchronously to force GL submit
LayerSettings layer{
.source = PixelSource{.solidColor = half3(0.f, 0.f, 0.f)},
diff --git a/libs/renderengine/skia/SkiaVkRenderEngine.cpp b/libs/renderengine/skia/SkiaVkRenderEngine.cpp
index 17f263d..8821c0e 100644
--- a/libs/renderengine/skia/SkiaVkRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaVkRenderEngine.cpp
@@ -25,6 +25,7 @@
#include <GrContextOptions.h>
#include <vk/GrVkExtensions.h>
#include <vk/GrVkTypes.h>
+#include <include/gpu/ganesh/vk/GrVkDirectContext.h>
#include <android-base/stringprintf.h>
#include <gui/TraceUtils.h>
@@ -603,11 +604,11 @@
sSetupVulkanInterface();
SkiaRenderEngine::Contexts contexts;
- contexts.first = GrDirectContext::MakeVulkan(sVulkanInterface.getBackendContext(), options);
+ contexts.first = GrDirectContexts::MakeVulkan(sVulkanInterface.getBackendContext(), options);
if (supportsProtectedContentImpl()) {
contexts.second =
- GrDirectContext::MakeVulkan(sProtectedContentVulkanInterface.getBackendContext(),
- options);
+ GrDirectContexts::MakeVulkan(sProtectedContentVulkanInterface.getBackendContext(),
+ options);
}
return contexts;
diff --git a/libs/ui/include/ui/DisplayMode.h b/libs/ui/include/ui/DisplayMode.h
index 65a8769..a469c78 100644
--- a/libs/ui/include/ui/DisplayMode.h
+++ b/libs/ui/include/ui/DisplayMode.h
@@ -37,7 +37,9 @@
float yDpi = 0;
std::vector<ui::Hdr> supportedHdrTypes;
- float refreshRate = 0;
+ // Some modes have peak refresh rate lower than the panel vsync rate.
+ float refreshRate = 0.f;
+ float vsyncRate = 0.f;
nsecs_t appVsyncOffset = 0;
nsecs_t sfVsyncOffset = 0;
nsecs_t presentationDeadline = 0;
diff --git a/libs/vibrator/OWNERS b/libs/vibrator/OWNERS
index d073e2b..c4de58a 100644
--- a/libs/vibrator/OWNERS
+++ b/libs/vibrator/OWNERS
@@ -1 +1,2 @@
+# Bug component: 345036
include platform/frameworks/base:/services/core/java/com/android/server/vibrator/OWNERS
diff --git a/services/inputflinger/TEST_MAPPING b/services/inputflinger/TEST_MAPPING
index ee1f3cb..6f092a6 100644
--- a/services/inputflinger/TEST_MAPPING
+++ b/services/inputflinger/TEST_MAPPING
@@ -39,6 +39,9 @@
"options": [
{
"include-filter": "android.hardware.input.cts.tests"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
}
]
},
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 276f75c..d0a72ee 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -3958,28 +3958,24 @@
android_log_event_list(LOGTAG_INPUT_CANCEL)
<< connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
- sp<WindowInfoHandle> windowHandle;
- if (options.displayId) {
- windowHandle = getWindowHandleLocked(connection->inputChannel->getConnectionToken(),
- options.displayId.value());
- } else {
- windowHandle = getWindowHandleLocked(connection->inputChannel->getConnectionToken());
- }
-
const bool wasEmpty = connection->outboundQueue.empty();
+ // The target to use if we don't find a window associated with the channel.
+ const InputTarget fallbackTarget{.inputChannel = connection->inputChannel,
+ .flags = InputTarget::Flags::DISPATCH_AS_IS};
+ const auto& token = connection->inputChannel->getConnectionToken();
for (size_t i = 0; i < cancelationEvents.size(); i++) {
std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
std::vector<InputTarget> targets{};
- // The target to use if we don't find a window associated with the channel.
- const InputTarget fallbackTarget{.inputChannel = connection->inputChannel,
- .flags = InputTarget::Flags::DISPATCH_AS_IS};
switch (cancelationEventEntry->type) {
case EventEntry::Type::KEY: {
const auto& keyEntry = static_cast<const KeyEntry&>(*cancelationEventEntry);
- if (windowHandle != nullptr) {
- addWindowTargetLocked(windowHandle, InputTarget::Flags::DISPATCH_AS_IS,
+ const std::optional<int32_t> targetDisplay = keyEntry.displayId != ADISPLAY_ID_NONE
+ ? std::make_optional(keyEntry.displayId)
+ : std::nullopt;
+ if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) {
+ addWindowTargetLocked(window, InputTarget::Flags::DISPATCH_AS_IS,
/*pointerIds=*/{}, keyEntry.downTime, targets);
} else {
targets.emplace_back(fallbackTarget);
@@ -3989,14 +3985,18 @@
}
case EventEntry::Type::MOTION: {
const auto& motionEntry = static_cast<const MotionEntry&>(*cancelationEventEntry);
- if (windowHandle != nullptr) {
+ const std::optional<int32_t> targetDisplay =
+ motionEntry.displayId != ADISPLAY_ID_NONE
+ ? std::make_optional(motionEntry.displayId)
+ : std::nullopt;
+ if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) {
std::bitset<MAX_POINTER_ID + 1> pointerIds;
for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount;
pointerIndex++) {
pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
}
- addWindowTargetLocked(windowHandle, InputTarget::Flags::DISPATCH_AS_IS,
- pointerIds, motionEntry.downTime, targets);
+ addWindowTargetLocked(window, InputTarget::Flags::DISPATCH_AS_IS, pointerIds,
+ motionEntry.downTime, targets);
} else {
targets.emplace_back(fallbackTarget);
const auto it = mDisplayInfos.find(motionEntry.displayId);
@@ -4905,29 +4905,26 @@
}
sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
- const sp<IBinder>& windowHandleToken) const {
+ const sp<IBinder>& windowHandleToken, std::optional<int32_t> displayId) const {
if (windowHandleToken == nullptr) {
return nullptr;
}
- for (auto& it : mWindowHandlesByDisplay) {
- const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
- for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
- if (windowHandle->getToken() == windowHandleToken) {
- return windowHandle;
+ if (!displayId) {
+ // Look through all displays.
+ for (auto& it : mWindowHandlesByDisplay) {
+ const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
+ for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
+ if (windowHandle->getToken() == windowHandleToken) {
+ return windowHandle;
+ }
}
}
- }
- return nullptr;
-}
-
-sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
- int displayId) const {
- if (windowHandleToken == nullptr) {
return nullptr;
}
- for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
+ // Only look through the requested display.
+ for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(*displayId)) {
if (windowHandle->getToken() == windowHandleToken) {
return windowHandle;
}
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index ee5a797..0020301 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -354,14 +354,11 @@
// Get a reference to window handles by display, return an empty vector if not found.
const std::vector<sp<android::gui::WindowInfoHandle>>& getWindowHandlesLocked(
int32_t displayId) const REQUIRES(mLock);
- sp<android::gui::WindowInfoHandle> getWindowHandleLocked(
- const sp<IBinder>& windowHandleToken) const REQUIRES(mLock);
ui::Transform getTransformLocked(int32_t displayId) const REQUIRES(mLock);
- // Same function as above, but faster. Since displayId is provided, this avoids the need
- // to loop through all displays.
- sp<android::gui::WindowInfoHandle> getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
- int displayId) const REQUIRES(mLock);
+ sp<android::gui::WindowInfoHandle> getWindowHandleLocked(
+ const sp<IBinder>& windowHandleToken, std::optional<int32_t> displayId = {}) const
+ REQUIRES(mLock);
sp<android::gui::WindowInfoHandle> getWindowHandleLocked(
const sp<android::gui::WindowInfoHandle>& windowHandle) const REQUIRES(mLock);
std::shared_ptr<InputChannel> getInputChannelLocked(const sp<IBinder>& windowToken) const
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 2f63b2a..ff3eff1 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -4699,6 +4699,36 @@
firstWindow->assertNoEvents();
}
+TEST_F(InputDispatcherDisplayProjectionTest,
+ SynthesizeHoverCancelationWithCorrectCoordinatesWhenMirrored) {
+ auto [firstWindow, secondWindow] = setupScaledDisplayScenario();
+
+ const std::array<float, 9> matrix = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 0.0, 0.0, 1.0};
+ ui::Transform secondDisplayTransform;
+ secondDisplayTransform.set(matrix);
+ addDisplayInfo(SECOND_DISPLAY_ID, secondDisplayTransform);
+
+ sp<FakeWindowHandle> secondWindowClone = secondWindow->clone(SECOND_DISPLAY_ID);
+ secondWindowClone->setWindowTransform(1.1, 2.2, 3.3, 4.4);
+ addWindow(secondWindowClone);
+
+ // Send hover enter to second window
+ mDispatcher->notifyMotion(generateMotionArgs(ACTION_HOVER_ENTER, AINPUT_SOURCE_STYLUS,
+ ADISPLAY_ID_DEFAULT, {PointF{150, 220}}));
+ secondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_ENTER),
+ WithCoords(100, 80), WithRawCoords(300, 880),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
+
+ mDispatcher->cancelCurrentTouch();
+
+ // Ensure the cancelation happens with the correct displayId and the correct coordinates.
+ secondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_EXIT), WithCoords(100, 80),
+ WithRawCoords(300, 880),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ secondWindow->assertNoEvents();
+ firstWindow->assertNoEvents();
+}
+
/** Ensure consistent behavior of InputDispatcher in all orientations. */
class InputDispatcherDisplayOrientationFixture
: public InputDispatcherDisplayProjectionTest,
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
index 03c0993..4db2b66 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
@@ -731,6 +731,10 @@
: parentSnapshot.outputFilter.layerStack;
}
+ if (forceUpdate || snapshot.clientChanges & layer_state_t::eTrustedOverlayChanged) {
+ snapshot.isTrustedOverlay = parentSnapshot.isTrustedOverlay || requested.isTrustedOverlay;
+ }
+
if (snapshot.isHiddenByPolicyFromParent &&
!snapshot.changes.test(RequestedLayerState::Changes::Created)) {
if (forceUpdate ||
@@ -761,10 +765,6 @@
(requested.flags & layer_state_t::eLayerSkipScreenshot);
}
- if (forceUpdate || snapshot.clientChanges & layer_state_t::eTrustedOverlayChanged) {
- snapshot.isTrustedOverlay = parentSnapshot.isTrustedOverlay || requested.isTrustedOverlay;
- }
-
if (forceUpdate || snapshot.clientChanges & layer_state_t::eStretchChanged) {
snapshot.stretchEffect = (requested.stretchEffect.hasEffect())
? requested.stretchEffect
diff --git a/services/surfaceflinger/LayerFE.cpp b/services/surfaceflinger/LayerFE.cpp
index 48a9190..f25619a 100644
--- a/services/surfaceflinger/LayerFE.cpp
+++ b/services/surfaceflinger/LayerFE.cpp
@@ -247,10 +247,13 @@
layerSettings.frameNumber = mSnapshot->frameNumber;
layerSettings.bufferId = mSnapshot->externalTexture->getId();
+ const bool useFiltering = targetSettings.needsFiltering ||
+ mSnapshot->geomLayerTransform.needsBilinearFiltering();
+
// Query the texture matrix given our current filtering mode.
float textureMatrix[16];
getDrawingTransformMatrix(layerSettings.source.buffer.buffer, mSnapshot->geomContentCrop,
- mSnapshot->geomBufferTransform, targetSettings.needsFiltering,
+ mSnapshot->geomBufferTransform, useFiltering,
textureMatrix);
if (mSnapshot->geomBufferUsesDisplayInverseTransform) {
@@ -301,7 +304,7 @@
mat4::translate(vec4(translateX, translateY, 0.f, 1.f)) *
mat4::scale(vec4(scaleWidth, scaleHeight, 1.0f, 1.0f));
- layerSettings.source.buffer.useTextureFiltering = targetSettings.needsFiltering;
+ layerSettings.source.buffer.useTextureFiltering = useFiltering;
layerSettings.source.buffer.textureTransform =
mat4(static_cast<const float*>(textureMatrix)) * tr;
diff --git a/services/surfaceflinger/Scheduler/include/scheduler/Timer.h b/services/surfaceflinger/Scheduler/include/scheduler/Timer.h
index 58ad6cb..67f7abe 100644
--- a/services/surfaceflinger/Scheduler/include/scheduler/Timer.h
+++ b/services/surfaceflinger/Scheduler/include/scheduler/Timer.h
@@ -60,6 +60,7 @@
void reset() EXCLUDES(mMutex);
void cleanup() REQUIRES(mMutex);
void setDebugState(DebugState) EXCLUDES(mMutex);
+ void setCallback(std::function<void()>&&) REQUIRES(mMutex);
int mTimerFd = -1;
@@ -71,6 +72,7 @@
void endDispatch();
mutable std::mutex mMutex;
+
std::function<void()> mCallback GUARDED_BY(mMutex);
bool mExpectingCallback GUARDED_BY(mMutex) = false;
DebugState mDebugState GUARDED_BY(mMutex);
diff --git a/services/surfaceflinger/Scheduler/src/Timer.cpp b/services/surfaceflinger/Scheduler/src/Timer.cpp
index a4cf57f..09e8a1e 100644
--- a/services/surfaceflinger/Scheduler/src/Timer.cpp
+++ b/services/surfaceflinger/Scheduler/src/Timer.cpp
@@ -93,8 +93,8 @@
close(mPipes[kWritePipe]);
mPipes[kWritePipe] = -1;
}
- mExpectingCallback = false;
- mCallback = {};
+
+ setCallback({});
}
void Timer::endDispatch() {
@@ -112,8 +112,7 @@
static constexpr int ns_per_s =
std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count();
- mCallback = std::move(callback);
- mExpectingCallback = true;
+ setCallback(std::move(callback));
struct itimerspec old_timer;
struct itimerspec new_timer {
@@ -142,6 +141,8 @@
if (timerfd_settime(mTimerFd, 0, &new_timer, &old_timer)) {
ALOGW("Failed to disarm timerfd");
}
+
+ setCallback({});
}
void Timer::threadMain() {
@@ -231,6 +232,11 @@
mDebugState = state;
}
+void Timer::setCallback(std::function<void()>&& callback) {
+ mExpectingCallback = bool(callback);
+ mCallback = std::move(callback);
+}
+
void Timer::dump(std::string& result) const {
std::lock_guard lock(mMutex);
result.append("\t\tDebugState: ");
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 3d3c169..533c276 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1047,6 +1047,7 @@
const auto peakFps = mode->getPeakFps();
outMode.refreshRate = peakFps.getValue();
+ outMode.vsyncRate = mode->getVsyncRate().getValue();
const auto vsyncConfigSet =
mVsyncConfiguration->getConfigsForRefreshRate(Fps::fromValue(outMode.refreshRate));
@@ -9189,6 +9190,7 @@
outMode.xDpi = mode.xDpi;
outMode.yDpi = mode.yDpi;
outMode.refreshRate = mode.refreshRate;
+ outMode.vsyncRate = mode.vsyncRate;
outMode.appVsyncOffset = mode.appVsyncOffset;
outMode.sfVsyncOffset = mode.sfVsyncOffset;
outMode.presentationDeadline = mode.presentationDeadline;
diff --git a/services/surfaceflinger/TEST_MAPPING b/services/surfaceflinger/TEST_MAPPING
index 922fd07..f339d22 100644
--- a/services/surfaceflinger/TEST_MAPPING
+++ b/services/surfaceflinger/TEST_MAPPING
@@ -40,5 +40,10 @@
{
"name": "libsurfaceflinger_unittest"
}
+ ],
+ "postsubmit": [
+ {
+ "name": "CtsSurfaceControlTestsStaging"
+ }
]
}
diff --git a/services/surfaceflinger/tests/BootDisplayMode_test.cpp b/services/surfaceflinger/tests/BootDisplayMode_test.cpp
index f2874ae..4f41a81 100644
--- a/services/surfaceflinger/tests/BootDisplayMode_test.cpp
+++ b/services/surfaceflinger/tests/BootDisplayMode_test.cpp
@@ -28,33 +28,95 @@
using gui::aidl_utils::statusTFromBinderStatus;
-TEST(BootDisplayModeTest, setBootDisplayMode) {
- sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
+struct BootDisplayModeTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ mSf = ComposerServiceAIDL::getComposerService();
- const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
- ASSERT_FALSE(ids.empty());
- auto displayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
- bool bootModeSupport = false;
- binder::Status status = sf->getBootDisplayModeSupport(&bootModeSupport);
- ASSERT_NO_FATAL_FAILURE(statusTFromBinderStatus(status));
- if (bootModeSupport) {
- status = sf->setBootDisplayMode(displayToken, 0);
+ const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
+ ASSERT_FALSE(ids.empty());
+ mDisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
+ bool bootModeSupport = false;
+ binder::Status status = mSf->getBootDisplayModeSupport(&bootModeSupport);
+ ASSERT_NO_FATAL_FAILURE(statusTFromBinderStatus(status));
+
+ if (!bootModeSupport) {
+ GTEST_SKIP() << "Boot mode not supported";
+ }
+
+ gui::DynamicDisplayInfo info;
+ status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
ASSERT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+ mOldMode = info.preferredBootDisplayMode;
+ const auto newMode = [&]() -> std::optional<ui::DisplayModeId> {
+ for (const auto& mode : info.supportedDisplayModes) {
+ if (mode.id != mOldMode) {
+ return std::optional(mode.id);
+ }
+ }
+ return std::nullopt;
+ }();
+
+ if (!newMode) {
+ GTEST_SKIP() << "Only a single mode is supported";
+ }
+
+ mNewMode = *newMode;
}
+
+ void TearDown() override {
+ binder::Status status = mSf->setBootDisplayMode(mDisplayToken, mOldMode);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+
+ gui::DynamicDisplayInfo info;
+ status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+ EXPECT_EQ(mOldMode, info.preferredBootDisplayMode);
+ }
+
+ ui::DisplayModeId mOldMode;
+ ui::DisplayModeId mNewMode;
+ sp<gui::ISurfaceComposer> mSf;
+ sp<IBinder> mDisplayToken;
+};
+
+TEST_F(BootDisplayModeTest, setBootDisplayMode) {
+ // Set a new mode and check that it got applied
+ binder::Status status = mSf->setBootDisplayMode(mDisplayToken, mNewMode);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+
+ gui::DynamicDisplayInfo info;
+ status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+ EXPECT_EQ(mNewMode, info.preferredBootDisplayMode);
}
-TEST(BootDisplayModeTest, clearBootDisplayMode) {
- sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
- const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
- ASSERT_FALSE(ids.empty());
- auto displayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
- bool bootModeSupport = false;
- binder::Status status = sf->getBootDisplayModeSupport(&bootModeSupport);
- ASSERT_NO_FATAL_FAILURE(statusTFromBinderStatus(status));
- if (bootModeSupport) {
- status = sf->clearBootDisplayMode(displayToken);
- ASSERT_EQ(NO_ERROR, statusTFromBinderStatus(status));
- }
+TEST_F(BootDisplayModeTest, clearBootDisplayMode) {
+ // Clear once to figure out what the system default is
+ binder::Status status = mSf->clearBootDisplayMode(mDisplayToken);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+
+ gui::DynamicDisplayInfo info;
+ status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+
+ const ui::DisplayModeId systemMode = info.preferredBootDisplayMode;
+ const ui::DisplayModeId newMode = systemMode == mOldMode ? mNewMode : mOldMode;
+
+ // Now set a new mode and clear the boot mode again to figure out if the api worked.
+ status = mSf->setBootDisplayMode(mDisplayToken, newMode);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+
+ status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+ EXPECT_EQ(newMode, info.preferredBootDisplayMode);
+
+ status = mSf->clearBootDisplayMode(mDisplayToken);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+
+ status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+ EXPECT_EQ(systemMode, info.preferredBootDisplayMode);
}
} // namespace android
diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp
index 69e9a16..822ac4d 100644
--- a/services/surfaceflinger/tests/Credentials_test.cpp
+++ b/services/surfaceflinger/tests/Credentials_test.cpp
@@ -275,18 +275,6 @@
ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
}
-TEST_F(CredentialsTest, CaptureTest) {
- const auto display = getFirstDisplayToken();
- std::function<status_t()> condition = [=]() {
- sp<GraphicBuffer> outBuffer;
- DisplayCaptureArgs captureArgs;
- captureArgs.displayToken = display;
- ScreenCaptureResults captureResults;
- return ScreenCapture::captureDisplay(captureArgs, captureResults);
- };
- ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
-}
-
TEST_F(CredentialsTest, CaptureLayersTest) {
setupBackgroundSurface();
sp<GraphicBuffer> outBuffer;
diff --git a/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp
index 34c9182..f9b4bba 100644
--- a/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp
@@ -167,18 +167,18 @@
.setFlags(layer, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure)
.apply(true);
- DisplayCaptureArgs args;
- args.displayToken = mDisplay;
+ LayerCaptureArgs args;
+ args.layerHandle = layer->getHandle();
ScreenCaptureResults captureResults;
{
// Ensure the UID is not root because root has all permissions
UIDFaker f(AID_APP_START);
- ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureDisplay(args, captureResults));
+ ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(args, captureResults));
}
Transaction().setFlags(layer, 0, layer_state_t::eLayerSecure).apply(true);
- ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(args, captureResults));
+ ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(args, captureResults));
}
TEST_P(LayerTypeTransactionTest, RefreshRateIsInitialized) {
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 91910c7..ec21eaf 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -45,8 +45,7 @@
cc_aconfig_library {
name: "libsurfaceflingerflags_test",
aconfig_declarations: "surfaceflinger_flags",
- // TODO(b/304338314): uncomment the below line once the bug is fixed
- // test: true,
+ test: true,
}
cc_test {
diff --git a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
index d319dcc..7f3171f 100644
--- a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
+++ b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
@@ -443,6 +443,17 @@
mLifecycleManager.applyTransactions(transactions);
}
+ void setTrustedOverlay(uint32_t id, bool isTrustedOverlay) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eTrustedOverlayChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.isTrustedOverlay = isTrustedOverlay;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
LayerLifecycleManager mLifecycleManager;
};
diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
index 50dfcaa..fc4bb22 100644
--- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
@@ -861,4 +861,15 @@
EXPECT_EQ(getSnapshot(1)->shadowSettings.length, SHADOW_RADIUS);
}
+TEST_F(LayerSnapshotTest, setTrustedOverlayForNonVisibleInput) {
+ hideLayer(1);
+ setTrustedOverlay(1, true);
+ Region touch{Rect{0, 0, 1000, 1000}};
+ setTouchableRegion(1, touch);
+
+ UPDATE_AND_VERIFY(mSnapshotBuilder, {2});
+ EXPECT_TRUE(getSnapshot(1)->inputInfo.inputConfig.test(
+ gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+}
+
} // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
index a1eda94..b8fdce1 100644
--- a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
@@ -1065,10 +1065,8 @@
EXPECT_THAT(cb.mReadyTime[0], Eq(2000));
}
-// TODO(b/304338314): Set the flag value instead of skipping the test
TEST_F(VSyncDispatchTimerQueueTest, skipAVsyc) {
- // SET_FLAG_FOR_TEST(flags::dont_skip_on_early, false);
- if (flags::dont_skip_on_early()) GTEST_SKIP();
+ SET_FLAG_FOR_TEST(flags::dont_skip_on_early, false);
EXPECT_CALL(mMockClock, alarmAt(_, 500));
CountingCallback cb(mDispatch);
@@ -1088,10 +1086,8 @@
ASSERT_THAT(cb.mCalls.size(), Eq(1));
}
-// TODO(b/304338314): Set the flag value instead of skipping the test
TEST_F(VSyncDispatchTimerQueueTest, dontskipAVsyc) {
- // SET_FLAG_FOR_TEST(flags::dont_skip_on_early, true);
- if (!flags::dont_skip_on_early()) GTEST_SKIP();
+ SET_FLAG_FOR_TEST(flags::dont_skip_on_early, true);
EXPECT_CALL(mMockClock, alarmAt(_, 500));
CountingCallback cb(mDispatch);