Merge "Introduce InputConfig::SENSITIVE_FOR_TRACING" into main
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 42dd691..54457fc 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -44,6 +44,7 @@
int BpBinder::sNumTrackedUids = 0;
std::atomic_bool BpBinder::sCountByUidEnabled(false);
binder_proxy_limit_callback BpBinder::sLimitCallback;
+binder_proxy_warning_callback BpBinder::sWarningCallback;
bool BpBinder::sBinderProxyThrottleCreate = false;
static StaticString16 kDescriptorUninit(u"");
@@ -52,6 +53,9 @@
uint32_t BpBinder::sBinderProxyCountHighWatermark = 2500;
// Another arbitrary value a binder count needs to drop below before another callback will be called
uint32_t BpBinder::sBinderProxyCountLowWatermark = 2000;
+// Arbitrary value between low and high watermark on a bad behaving app to
+// trigger a warning callback.
+uint32_t BpBinder::sBinderProxyCountWarningWatermark = 2250;
std::atomic<uint32_t> BpBinder::sBinderProxyCount(0);
std::atomic<uint32_t> BpBinder::sBinderProxyCountWarned(0);
@@ -63,7 +67,8 @@
enum {
LIMIT_REACHED_MASK = 0x80000000, // A flag denoting that the limit has been reached
- COUNTING_VALUE_MASK = 0x7FFFFFFF, // A mask of the remaining bits for the count value
+ WARNING_REACHED_MASK = 0x40000000, // A flag denoting that the warning has been reached
+ COUNTING_VALUE_MASK = 0x3FFFFFFF, // A mask of the remaining bits for the count value
};
BpBinder::ObjectManager::ObjectManager()
@@ -181,7 +186,13 @@
sLastLimitCallbackMap[trackedUid] = trackedValue;
}
} else {
- if ((trackedValue & COUNTING_VALUE_MASK) >= sBinderProxyCountHighWatermark) {
+ uint32_t currentValue = trackedValue & COUNTING_VALUE_MASK;
+ if (currentValue >= sBinderProxyCountWarningWatermark
+ && currentValue < sBinderProxyCountHighWatermark
+ && ((trackedValue & WARNING_REACHED_MASK) == 0)) [[unlikely]] {
+ sTrackingMap[trackedUid] |= WARNING_REACHED_MASK;
+ if (sWarningCallback) sWarningCallback(trackedUid);
+ } else if (currentValue >= sBinderProxyCountHighWatermark) {
ALOGE("Too many binder proxy objects sent to uid %d from uid %d (%d proxies held)",
getuid(), trackedUid, trackedValue);
sTrackingMap[trackedUid] |= LIMIT_REACHED_MASK;
@@ -609,11 +620,11 @@
binderHandle());
} else {
auto countingValue = trackedValue & COUNTING_VALUE_MASK;
- if ((trackedValue & LIMIT_REACHED_MASK) &&
+ if ((trackedValue & (LIMIT_REACHED_MASK | WARNING_REACHED_MASK)) &&
(countingValue <= sBinderProxyCountLowWatermark)) [[unlikely]] {
ALOGI("Limit reached bit reset for uid %d (fewer than %d proxies from uid %d held)",
getuid(), sBinderProxyCountLowWatermark, mTrackedUid);
- sTrackingMap[mTrackedUid] &= ~LIMIT_REACHED_MASK;
+ sTrackingMap[mTrackedUid] &= ~(LIMIT_REACHED_MASK | WARNING_REACHED_MASK);
sLastLimitCallbackMap.erase(mTrackedUid);
}
if (--sTrackingMap[mTrackedUid] == 0) {
@@ -730,15 +741,18 @@
void BpBinder::disableCountByUid() { sCountByUidEnabled.store(false); }
void BpBinder::setCountByUidEnabled(bool enable) { sCountByUidEnabled.store(enable); }
-void BpBinder::setLimitCallback(binder_proxy_limit_callback cb) {
+void BpBinder::setBinderProxyCountEventCallback(binder_proxy_limit_callback cbl,
+ binder_proxy_warning_callback cbw) {
RpcMutexUniqueLock _l(sTrackingLock);
- sLimitCallback = cb;
+ sLimitCallback = std::move(cbl);
+ sWarningCallback = std::move(cbw);
}
-void BpBinder::setBinderProxyCountWatermarks(int high, int low) {
+void BpBinder::setBinderProxyCountWatermarks(int high, int low, int warning) {
RpcMutexUniqueLock _l(sTrackingLock);
sBinderProxyCountHighWatermark = high;
sBinderProxyCountLowWatermark = low;
+ sBinderProxyCountWarningWatermark = warning;
}
// ---------------------------------------------------------------------------
diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h
index 89a4d27..9f03907 100644
--- a/libs/binder/include/binder/BpBinder.h
+++ b/libs/binder/include/binder/BpBinder.h
@@ -35,7 +35,8 @@
}
class ProcessState;
-using binder_proxy_limit_callback = void(*)(int);
+using binder_proxy_limit_callback = std::function<void(int)>;
+using binder_proxy_warning_callback = std::function<void(int)>;
class BpBinder : public IBinder
{
@@ -86,8 +87,9 @@
static void enableCountByUid();
static void disableCountByUid();
static void setCountByUidEnabled(bool enable);
- static void setLimitCallback(binder_proxy_limit_callback cb);
- static void setBinderProxyCountWatermarks(int high, int low);
+ static void setBinderProxyCountEventCallback(binder_proxy_limit_callback cbl,
+ binder_proxy_warning_callback cbw);
+ static void setBinderProxyCountWatermarks(int high, int low, int warning);
static uint32_t getBinderProxyCount();
std::optional<int32_t> getDebugBinderHandle() const;
@@ -212,6 +214,8 @@
static std::unordered_map<int32_t,uint32_t> sLastLimitCallbackMap;
static std::atomic<uint32_t> sBinderProxyCount;
static std::atomic<uint32_t> sBinderProxyCountWarned;
+ static binder_proxy_warning_callback sWarningCallback;
+ static uint32_t sBinderProxyCountWarningWatermark;
};
} // namespace android
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 0ee96e7..2cea14f 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -115,6 +115,7 @@
BINDER_LIB_TEST_GET_SCHEDULING_POLICY,
BINDER_LIB_TEST_NOP_TRANSACTION_WAIT,
BINDER_LIB_TEST_GETPID,
+ BINDER_LIB_TEST_GETUID,
BINDER_LIB_TEST_ECHO_VECTOR,
BINDER_LIB_TEST_GET_NON_BLOCKING_FD,
BINDER_LIB_TEST_REJECT_OBJECTS,
@@ -1477,6 +1478,86 @@
EXPECT_EQ(BpBinder::getBinderProxyCount(), initialCount);
}
+static constexpr int kBpCountHighWatermark = 20;
+static constexpr int kBpCountLowWatermark = 10;
+static constexpr int kBpCountWarningWatermark = 15;
+static constexpr int kInvalidUid = -1;
+
+TEST_F(BinderLibTest, BinderProxyCountCallback) {
+ Parcel data, reply;
+ sp<IBinder> server = addServer();
+ ASSERT_NE(server, nullptr);
+
+ BpBinder::enableCountByUid();
+ EXPECT_THAT(m_server->transact(BINDER_LIB_TEST_GETUID, data, &reply), StatusEq(NO_ERROR));
+ int32_t uid = reply.readInt32();
+ ASSERT_NE(uid, kInvalidUid);
+
+ uint32_t initialCount = BpBinder::getBinderProxyCount();
+ {
+ uint32_t count = initialCount;
+ BpBinder::setBinderProxyCountWatermarks(kBpCountHighWatermark,
+ kBpCountLowWatermark,
+ kBpCountWarningWatermark);
+ int limitCallbackUid = kInvalidUid;
+ int warningCallbackUid = kInvalidUid;
+ BpBinder::setBinderProxyCountEventCallback([&](int uid) { limitCallbackUid = uid; },
+ [&](int uid) { warningCallbackUid = uid; });
+
+ std::vector<sp<IBinder> > proxies;
+ auto createProxyOnce = [&](int expectedWarningCallbackUid, int expectedLimitCallbackUid) {
+ warningCallbackUid = limitCallbackUid = kInvalidUid;
+ ASSERT_THAT(server->transact(BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION, data, &reply),
+ StatusEq(NO_ERROR));
+ proxies.push_back(reply.readStrongBinder());
+ EXPECT_EQ(BpBinder::getBinderProxyCount(), ++count);
+ EXPECT_EQ(warningCallbackUid, expectedWarningCallbackUid);
+ EXPECT_EQ(limitCallbackUid, expectedLimitCallbackUid);
+ };
+ auto removeProxyOnce = [&](int expectedWarningCallbackUid, int expectedLimitCallbackUid) {
+ warningCallbackUid = limitCallbackUid = kInvalidUid;
+ proxies.pop_back();
+ EXPECT_EQ(BpBinder::getBinderProxyCount(), --count);
+ EXPECT_EQ(warningCallbackUid, expectedWarningCallbackUid);
+ EXPECT_EQ(limitCallbackUid, expectedLimitCallbackUid);
+ };
+
+ // Test the increment/decrement of the binder proxies.
+ for (int i = 1; i <= kBpCountWarningWatermark; i++) {
+ createProxyOnce(kInvalidUid, kInvalidUid);
+ }
+ createProxyOnce(uid, kInvalidUid); // Warning callback should have been triggered.
+ for (int i = kBpCountWarningWatermark + 2; i <= kBpCountHighWatermark; i++) {
+ createProxyOnce(kInvalidUid, kInvalidUid);
+ }
+ createProxyOnce(kInvalidUid, uid); // Limit callback should have been triggered.
+ createProxyOnce(kInvalidUid, kInvalidUid);
+ for (int i = kBpCountHighWatermark + 2; i >= kBpCountHighWatermark; i--) {
+ removeProxyOnce(kInvalidUid, kInvalidUid);
+ }
+ createProxyOnce(kInvalidUid, kInvalidUid);
+
+ // Go down below the low watermark.
+ for (int i = kBpCountHighWatermark; i >= kBpCountLowWatermark; i--) {
+ removeProxyOnce(kInvalidUid, kInvalidUid);
+ }
+ for (int i = kBpCountLowWatermark; i <= kBpCountWarningWatermark; i++) {
+ createProxyOnce(kInvalidUid, kInvalidUid);
+ }
+ createProxyOnce(uid, kInvalidUid); // Warning callback should have been triggered.
+ for (int i = kBpCountWarningWatermark + 2; i <= kBpCountHighWatermark; i++) {
+ createProxyOnce(kInvalidUid, kInvalidUid);
+ }
+ createProxyOnce(kInvalidUid, uid); // Limit callback should have been triggered.
+ createProxyOnce(kInvalidUid, kInvalidUid);
+ for (int i = kBpCountHighWatermark + 2; i >= kBpCountHighWatermark; i--) {
+ removeProxyOnce(kInvalidUid, kInvalidUid);
+ }
+ createProxyOnce(kInvalidUid, kInvalidUid);
+ }
+ EXPECT_EQ(BpBinder::getBinderProxyCount(), initialCount);
+}
+
class BinderLibRpcTestBase : public BinderLibTest {
public:
void SetUp() override {
@@ -1680,6 +1761,9 @@
case BINDER_LIB_TEST_GETPID:
reply->writeInt32(getpid());
return NO_ERROR;
+ case BINDER_LIB_TEST_GETUID:
+ reply->writeInt32(getuid());
+ return NO_ERROR;
case BINDER_LIB_TEST_NOP_TRANSACTION_WAIT:
usleep(5000);
[[fallthrough]];
diff --git a/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h
index 0a584bf..83d0ca7 100644
--- a/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h
+++ b/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h
@@ -95,14 +95,16 @@
},
[](FuzzedDataProvider*, const sp<BpBinder>& bpbinder,
const sp<IBinder::DeathRecipient>&) -> void {
- binder_proxy_limit_callback cb = binder_proxy_limit_callback();
- bpbinder->setLimitCallback(cb);
+ binder_proxy_limit_callback cbl = binder_proxy_limit_callback();
+ binder_proxy_warning_callback cbw = binder_proxy_warning_callback();
+ bpbinder->setBinderProxyCountEventCallback(cbl, cbw);
},
[](FuzzedDataProvider* fdp, const sp<BpBinder>& bpbinder,
const sp<IBinder::DeathRecipient>&) -> void {
int high = fdp->ConsumeIntegral<int>();
int low = fdp->ConsumeIntegral<int>();
- bpbinder->setBinderProxyCountWatermarks(high, low);
+ int warning = fdp->ConsumeIntegral<int>();
+ bpbinder->setBinderProxyCountWatermarks(high, low, warning);
}};
} // namespace android
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 70cb36b..b70e80e 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -241,7 +241,6 @@
"IProducerListener.cpp",
"ISurfaceComposer.cpp",
"ITransactionCompletedListener.cpp",
- "LayerDebugInfo.cpp",
"LayerMetadata.cpp",
"LayerStatePermissions.cpp",
"LayerState.cpp",
diff --git a/libs/gui/LayerDebugInfo.cpp b/libs/gui/LayerDebugInfo.cpp
deleted file mode 100644
index 15b2221..0000000
--- a/libs/gui/LayerDebugInfo.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2017 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/LayerDebugInfo.h>
-
-#include <android-base/stringprintf.h>
-
-#include <ui/DebugUtils.h>
-
-#include <binder/Parcel.h>
-
-using namespace android;
-using android::base::StringAppendF;
-
-#define RETURN_ON_ERROR(X) do {status_t res = (X); if (res != NO_ERROR) return res;} while(false)
-
-namespace android::gui {
-
-status_t LayerDebugInfo::writeToParcel(Parcel* parcel) const {
- RETURN_ON_ERROR(parcel->writeCString(mName.c_str()));
- RETURN_ON_ERROR(parcel->writeCString(mParentName.c_str()));
- RETURN_ON_ERROR(parcel->writeCString(mType.c_str()));
- RETURN_ON_ERROR(parcel->write(mTransparentRegion));
- RETURN_ON_ERROR(parcel->write(mVisibleRegion));
- RETURN_ON_ERROR(parcel->write(mSurfaceDamageRegion));
- RETURN_ON_ERROR(parcel->writeUint32(mLayerStack));
- RETURN_ON_ERROR(parcel->writeFloat(mX));
- RETURN_ON_ERROR(parcel->writeFloat(mY));
- RETURN_ON_ERROR(parcel->writeUint32(mZ));
- RETURN_ON_ERROR(parcel->writeInt32(mWidth));
- RETURN_ON_ERROR(parcel->writeInt32(mHeight));
- RETURN_ON_ERROR(parcel->write(mCrop));
- RETURN_ON_ERROR(parcel->writeFloat(mColor.r));
- RETURN_ON_ERROR(parcel->writeFloat(mColor.g));
- RETURN_ON_ERROR(parcel->writeFloat(mColor.b));
- RETURN_ON_ERROR(parcel->writeFloat(mColor.a));
- RETURN_ON_ERROR(parcel->writeUint32(mFlags));
- RETURN_ON_ERROR(parcel->writeInt32(mPixelFormat));
- RETURN_ON_ERROR(parcel->writeUint32(static_cast<uint32_t>(mDataSpace)));
- for (size_t index = 0; index < 4; index++) {
- RETURN_ON_ERROR(parcel->writeFloat(mMatrix[index / 2][index % 2]));
- }
- RETURN_ON_ERROR(parcel->writeInt32(mActiveBufferWidth));
- RETURN_ON_ERROR(parcel->writeInt32(mActiveBufferHeight));
- RETURN_ON_ERROR(parcel->writeInt32(mActiveBufferStride));
- RETURN_ON_ERROR(parcel->writeInt32(mActiveBufferFormat));
- RETURN_ON_ERROR(parcel->writeInt32(mNumQueuedFrames));
- RETURN_ON_ERROR(parcel->writeBool(mIsOpaque));
- RETURN_ON_ERROR(parcel->writeBool(mContentDirty));
- RETURN_ON_ERROR(parcel->write(mStretchEffect));
- return NO_ERROR;
-}
-
-status_t LayerDebugInfo::readFromParcel(const Parcel* parcel) {
- mName = parcel->readCString();
- RETURN_ON_ERROR(parcel->errorCheck());
- mParentName = parcel->readCString();
- RETURN_ON_ERROR(parcel->errorCheck());
- mType = parcel->readCString();
- RETURN_ON_ERROR(parcel->errorCheck());
- RETURN_ON_ERROR(parcel->read(mTransparentRegion));
- RETURN_ON_ERROR(parcel->read(mVisibleRegion));
- RETURN_ON_ERROR(parcel->read(mSurfaceDamageRegion));
- RETURN_ON_ERROR(parcel->readUint32(&mLayerStack));
- RETURN_ON_ERROR(parcel->readFloat(&mX));
- RETURN_ON_ERROR(parcel->readFloat(&mY));
- RETURN_ON_ERROR(parcel->readUint32(&mZ));
- RETURN_ON_ERROR(parcel->readInt32(&mWidth));
- RETURN_ON_ERROR(parcel->readInt32(&mHeight));
- RETURN_ON_ERROR(parcel->read(mCrop));
- mColor.r = parcel->readFloat();
- RETURN_ON_ERROR(parcel->errorCheck());
- mColor.g = parcel->readFloat();
- RETURN_ON_ERROR(parcel->errorCheck());
- mColor.b = parcel->readFloat();
- RETURN_ON_ERROR(parcel->errorCheck());
- mColor.a = parcel->readFloat();
- RETURN_ON_ERROR(parcel->errorCheck());
- RETURN_ON_ERROR(parcel->readUint32(&mFlags));
- RETURN_ON_ERROR(parcel->readInt32(&mPixelFormat));
- // \todo [2017-07-25 kraita]: Static casting mDataSpace pointer to an uint32 does work. Better ways?
- mDataSpace = static_cast<android_dataspace>(parcel->readUint32());
- RETURN_ON_ERROR(parcel->errorCheck());
- for (size_t index = 0; index < 4; index++) {
- RETURN_ON_ERROR(parcel->readFloat(&mMatrix[index / 2][index % 2]));
- }
- RETURN_ON_ERROR(parcel->readInt32(&mActiveBufferWidth));
- RETURN_ON_ERROR(parcel->readInt32(&mActiveBufferHeight));
- RETURN_ON_ERROR(parcel->readInt32(&mActiveBufferStride));
- RETURN_ON_ERROR(parcel->readInt32(&mActiveBufferFormat));
- RETURN_ON_ERROR(parcel->readInt32(&mNumQueuedFrames));
- RETURN_ON_ERROR(parcel->readBool(&mIsOpaque));
- RETURN_ON_ERROR(parcel->readBool(&mContentDirty));
- RETURN_ON_ERROR(parcel->read(mStretchEffect));
- return NO_ERROR;
-}
-
-std::string to_string(const LayerDebugInfo& info) {
- std::string result;
-
- StringAppendF(&result, "+ %s (%s)\n", info.mType.c_str(), info.mName.c_str());
- info.mTransparentRegion.dump(result, "TransparentRegion");
- info.mVisibleRegion.dump(result, "VisibleRegion");
- info.mSurfaceDamageRegion.dump(result, "SurfaceDamageRegion");
- if (info.mStretchEffect.hasEffect()) {
- const auto& se = info.mStretchEffect;
- StringAppendF(&result,
- " StretchEffect width = %f, height = %f vec=(%f, %f) "
- "maxAmount=(%f, %f)\n",
- se.width, se.height,
- se.vectorX, se.vectorY, se.maxAmountX, se.maxAmountY);
- }
-
- StringAppendF(&result, " layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), ",
- info.mLayerStack, info.mZ, static_cast<double>(info.mX),
- static_cast<double>(info.mY), info.mWidth, info.mHeight);
-
- StringAppendF(&result, "crop=%s, ", to_string(info.mCrop).c_str());
- StringAppendF(&result, "isOpaque=%1d, invalidate=%1d, ", info.mIsOpaque, info.mContentDirty);
- StringAppendF(&result, "dataspace=%s, ", dataspaceDetails(info.mDataSpace).c_str());
- StringAppendF(&result, "pixelformat=%s, ", decodePixelFormat(info.mPixelFormat).c_str());
- StringAppendF(&result, "color=(%.3f,%.3f,%.3f,%.3f), flags=0x%08x, ",
- static_cast<double>(info.mColor.r), static_cast<double>(info.mColor.g),
- static_cast<double>(info.mColor.b), static_cast<double>(info.mColor.a),
- info.mFlags);
- StringAppendF(&result, "tr=[%.2f, %.2f][%.2f, %.2f]", static_cast<double>(info.mMatrix[0][0]),
- static_cast<double>(info.mMatrix[0][1]), static_cast<double>(info.mMatrix[1][0]),
- static_cast<double>(info.mMatrix[1][1]));
- result.append("\n");
- StringAppendF(&result, " parent=%s\n", info.mParentName.c_str());
- StringAppendF(&result, " activeBuffer=[%4ux%4u:%4u,%s],", info.mActiveBufferWidth,
- info.mActiveBufferHeight, info.mActiveBufferStride,
- decodePixelFormat(info.mActiveBufferFormat).c_str());
- StringAppendF(&result, " queued-frames=%d", info.mNumQueuedFrames);
- result.append("\n");
- return result;
-}
-
-} // namespace android::gui
diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
index 51e0193..a2549e7 100644
--- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
+++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
@@ -43,7 +43,6 @@
import android.gui.IWindowInfosListener;
import android.gui.IWindowInfosPublisher;
import android.gui.LayerCaptureArgs;
-import android.gui.LayerDebugInfo;
import android.gui.OverlayProperties;
import android.gui.PullAtomData;
import android.gui.ScreenCaptureResults;
@@ -289,13 +288,6 @@
PullAtomData onPullAtom(int atomId);
/**
- * Gets the list of active layers in Z order for debugging purposes
- *
- * Requires the ACCESS_SURFACE_FLINGER permission.
- */
- List<LayerDebugInfo> getLayerDebugInfo();
-
- /**
* Gets the composition preference of the default data space and default pixel format,
* as well as the wide color gamut data space and wide color gamut pixel format.
* If the wide color gamut data space is V0_SRGB, then it implies that the platform
diff --git a/libs/gui/aidl/android/gui/LayerDebugInfo.aidl b/libs/gui/aidl/android/gui/LayerDebugInfo.aidl
deleted file mode 100644
index faca980..0000000
--- a/libs/gui/aidl/android/gui/LayerDebugInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.gui;
-
-parcelable LayerDebugInfo cpp_header "gui/LayerDebugInfo.h";
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index a836f46..738c73a 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -74,7 +74,6 @@
struct DisplayCaptureArgs;
struct LayerCaptureArgs;
-class LayerDebugInfo;
} // namespace gui
diff --git a/libs/gui/include/gui/LayerDebugInfo.h b/libs/gui/include/gui/LayerDebugInfo.h
deleted file mode 100644
index dbb80e5..0000000
--- a/libs/gui/include/gui/LayerDebugInfo.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2017 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 <binder/Parcelable.h>
-
-#include <ui/PixelFormat.h>
-#include <ui/Region.h>
-#include <ui/StretchEffect.h>
-
-#include <string>
-#include <math/vec4.h>
-
-namespace android::gui {
-
-/* Class for transporting debug info from SurfaceFlinger to authorized
- * recipients. The class is intended to be a data container. There are
- * no getters or setters.
- */
-class LayerDebugInfo : public Parcelable {
-public:
- LayerDebugInfo() = default;
- LayerDebugInfo(const LayerDebugInfo&) = default;
- virtual ~LayerDebugInfo() = default;
-
- virtual status_t writeToParcel(Parcel* parcel) const;
- virtual status_t readFromParcel(const Parcel* parcel);
-
- std::string mName = std::string("NOT FILLED");
- std::string mParentName = std::string("NOT FILLED");
- std::string mType = std::string("NOT FILLED");
- Region mTransparentRegion = Region::INVALID_REGION;
- Region mVisibleRegion = Region::INVALID_REGION;
- Region mSurfaceDamageRegion = Region::INVALID_REGION;
- uint32_t mLayerStack = 0;
- float mX = 0.f;
- float mY = 0.f;
- uint32_t mZ = 0 ;
- int32_t mWidth = -1;
- int32_t mHeight = -1;
- android::Rect mCrop = android::Rect::INVALID_RECT;
- half4 mColor = half4(1.0_hf, 1.0_hf, 1.0_hf, 0.0_hf);
- uint32_t mFlags = 0;
- PixelFormat mPixelFormat = PIXEL_FORMAT_NONE;
- android_dataspace mDataSpace = HAL_DATASPACE_UNKNOWN;
- // Row-major transform matrix (SurfaceControl::setMatrix())
- float mMatrix[2][2] = {{0.f, 0.f}, {0.f, 0.f}};
- int32_t mActiveBufferWidth = -1;
- int32_t mActiveBufferHeight = -1;
- int32_t mActiveBufferStride = 0;
- PixelFormat mActiveBufferFormat = PIXEL_FORMAT_NONE;
- int32_t mNumQueuedFrames = -1;
- bool mIsOpaque = false;
- bool mContentDirty = false;
- StretchEffect mStretchEffect = {};
-};
-
-std::string to_string(const LayerDebugInfo& info);
-
-} // namespace android::gui
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 577d239..93bf4fa 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -815,10 +815,6 @@
return binder::Status::ok();
}
- binder::Status getLayerDebugInfo(std::vector<gui::LayerDebugInfo>* /*outLayers*/) override {
- return binder::Status::ok();
- }
-
binder::Status getCompositionPreference(gui::CompositionPreference* /*outPref*/) override {
return binder::Status::ok();
}
diff --git a/libs/ui/include/ui/LayerStack.h b/libs/ui/include/ui/LayerStack.h
index d6ffeb7..f4c8ba2 100644
--- a/libs/ui/include/ui/LayerStack.h
+++ b/libs/ui/include/ui/LayerStack.h
@@ -55,6 +55,10 @@
return lhs.id > rhs.id;
}
+inline bool operator<(LayerStack lhs, LayerStack rhs) {
+ return lhs.id < rhs.id;
+}
+
// A LayerFilter determines if a layer is included for output to a display.
struct LayerFilter {
LayerStack layerStack;
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 25632fe..0463f28 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -4855,7 +4855,7 @@
const bool isPointerEvent =
isFromSource(event->getSource(), AINPUT_SOURCE_CLASS_POINTER);
// If a pointer event has no displayId specified, inject it to the default display.
- const uint32_t displayId = isPointerEvent && (event->getDisplayId() == ADISPLAY_ID_NONE)
+ const int32_t displayId = isPointerEvent && (event->getDisplayId() == ADISPLAY_ID_NONE)
? ADISPLAY_ID_DEFAULT
: event->getDisplayId();
int32_t flags = motionEvent.getFlags();
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index cd2120e..80eee15 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -15,7 +15,7 @@
*/
// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#include "TransactionCallbackInvoker.h"
+
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
@@ -24,8 +24,6 @@
#define LOG_TAG "Layer"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include "Layer.h"
-
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <binder/IPCThreadState.h>
@@ -40,7 +38,6 @@
#include <ftl/enum.h>
#include <ftl/fake_guard.h>
#include <gui/BufferItem.h>
-#include <gui/LayerDebugInfo.h>
#include <gui/Surface.h>
#include <gui/TraceUtils.h>
#include <math.h>
@@ -74,10 +71,12 @@
#include "FrameTracer/FrameTracer.h"
#include "FrontEnd/LayerCreationArgs.h"
#include "FrontEnd/LayerHandle.h"
+#include "Layer.h"
#include "LayerProtoHelper.h"
#include "MutexUtils.h"
#include "SurfaceFlinger.h"
#include "TimeStats/TimeStats.h"
+#include "TransactionCallbackInvoker.h"
#include "TunnelModeEnabledReporter.h"
#include "Utils/FenceUtils.h"
@@ -1566,53 +1565,6 @@
// debugging
// ----------------------------------------------------------------------------
-// TODO(marissaw): add new layer state info to layer debugging
-gui::LayerDebugInfo Layer::getLayerDebugInfo(const DisplayDevice* display) const {
- using namespace std::string_literals;
-
- gui::LayerDebugInfo info;
- const State& ds = getDrawingState();
- info.mName = getName();
- sp<Layer> parent = mDrawingParent.promote();
- info.mParentName = parent ? parent->getName() : "none"s;
- info.mType = getType();
-
- info.mVisibleRegion = getVisibleRegion(display);
- info.mSurfaceDamageRegion = surfaceDamageRegion;
- info.mLayerStack = getLayerStack().id;
- info.mX = ds.transform.tx();
- info.mY = ds.transform.ty();
- info.mZ = ds.z;
- info.mCrop = ds.crop;
- info.mColor = ds.color;
- info.mFlags = ds.flags;
- info.mPixelFormat = getPixelFormat();
- info.mDataSpace = static_cast<android_dataspace>(getDataSpace());
- info.mMatrix[0][0] = ds.transform[0][0];
- info.mMatrix[0][1] = ds.transform[0][1];
- info.mMatrix[1][0] = ds.transform[1][0];
- info.mMatrix[1][1] = ds.transform[1][1];
- {
- sp<const GraphicBuffer> buffer = getBuffer();
- if (buffer != 0) {
- info.mActiveBufferWidth = buffer->getWidth();
- info.mActiveBufferHeight = buffer->getHeight();
- info.mActiveBufferStride = buffer->getStride();
- info.mActiveBufferFormat = buffer->format;
- } else {
- info.mActiveBufferWidth = 0;
- info.mActiveBufferHeight = 0;
- info.mActiveBufferStride = 0;
- info.mActiveBufferFormat = 0;
- }
- }
- info.mNumQueuedFrames = getQueuedFrameCount();
- info.mIsOpaque = isOpaque(ds);
- info.mContentDirty = contentDirty;
- info.mStretchEffect = getStretchEffect();
- return info;
-}
-
void Layer::miniDumpHeader(std::string& result) {
result.append(kDumpTableRowLength, '-');
result.append("\n");
@@ -2937,26 +2889,13 @@
ch->previousReleaseFences.emplace_back(std::move(futureFenceResult));
ch->name = mName;
} else {
- // If we didn't get a release callback yet, e.g. some scenarios when capturing
- // screenshots asynchronously, then make sure we don't drop the fence.
- mAdditionalPreviousReleaseFences.emplace_back(std::move(futureFenceResult));
- std::vector<ftl::Future<FenceResult>> mergedFences;
- sp<Fence> prevFence = nullptr;
- // For a layer that's frequently screenshotted, try to merge fences to make sure we
- // don't grow unbounded.
- for (auto& futureReleaseFence : mAdditionalPreviousReleaseFences) {
- auto result = futureReleaseFence.wait_for(0s);
- if (result != std::future_status::ready) {
- mergedFences.emplace_back(std::move(futureReleaseFence));
- continue;
- }
- mergeFence(getDebugName(), futureReleaseFence.get().value_or(Fence::NO_FENCE),
- prevFence);
- }
- if (prevFence != nullptr) {
- mergedFences.emplace_back(ftl::yield(FenceResult(std::move(prevFence))));
- }
- mAdditionalPreviousReleaseFences.swap(mergedFences);
+ // If we didn't get a release callback yet (e.g. some scenarios when capturing
+ // screenshots asynchronously) then make sure we don't drop the fence.
+ // Older fences for the same layer stack can be dropped when a new fence arrives.
+ // An assumption here is that RenderEngine performs work sequentially, so an
+ // incoming fence will not fire before an existing fence.
+ mAdditionalPreviousReleaseFences.emplace_or_replace(layerStack,
+ std::move(futureFenceResult));
}
if (mBufferInfo.mBuffer) {
@@ -3506,10 +3445,10 @@
handle->previousFrameNumber = mDrawingState.previousFrameNumber;
if (FlagManager::getInstance().ce_fence_promise() &&
mPreviousReleaseBufferEndpoint == handle->listener) {
- // Add fences from previous screenshots now so that they can be dispatched to the
+ // Add fence from previous screenshot now so that it can be dispatched to the
// client.
- for (auto& futureReleaseFence : mAdditionalPreviousReleaseFences) {
- handle->previousReleaseFences.emplace_back(std::move(futureReleaseFence));
+ for (auto& [_, future] : mAdditionalPreviousReleaseFences) {
+ handle->previousReleaseFences.emplace_back(std::move(future));
}
mAdditionalPreviousReleaseFences.clear();
} else if (FlagManager::getInstance().screenshot_fence_preservation() &&
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index d283d6f..c094aa1 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -18,6 +18,7 @@
#include <android/gui/DropInputMode.h>
#include <android/gui/ISurfaceComposerClient.h>
+#include <ftl/small_map.h>
#include <gui/BufferQueue.h>
#include <gui/LayerState.h>
#include <gui/WindowInfo.h>
@@ -25,9 +26,11 @@
#include <math/vec4.h>
#include <sys/types.h>
#include <ui/BlurRegion.h>
+#include <ui/DisplayMap.h>
#include <ui/FloatRect.h>
#include <ui/FrameStats.h>
#include <ui/GraphicBuffer.h>
+#include <ui/LayerStack.h>
#include <ui/PixelFormat.h>
#include <ui/Region.h>
#include <ui/StretchEffect.h>
@@ -71,10 +74,6 @@
struct LayerFECompositionState;
}
-namespace gui {
-class LayerDebugInfo;
-}
-
namespace frametimeline {
class SurfaceFrame;
} // namespace frametimeline
@@ -703,8 +702,6 @@
inline const State& getDrawingState() const { return mDrawingState; }
inline State& getDrawingState() { return mDrawingState; }
- gui::LayerDebugInfo getLayerDebugInfo(const DisplayDevice*) const;
-
void miniDumpLegacy(std::string& result, const DisplayDevice&) const;
void miniDump(std::string& result, const frontend::LayerSnapshot&, const DisplayDevice&) const;
void dumpFrameStats(std::string& result) const;
@@ -958,8 +955,11 @@
// screenshots asynchronously. There may be no buffer update for the
// layer, but the layer will still be composited on the screen in every
// frame. Kepping track of these fences ensures that they are not dropped
- // and can be dispatched to the client at a later time.
- std::vector<ftl::Future<FenceResult>> mAdditionalPreviousReleaseFences;
+ // and can be dispatched to the client at a later time. Older fences are
+ // dropped when a layer stack receives a new fence.
+ // TODO(b/300533018): Track fence per multi-instance RenderEngine
+ ftl::SmallMap<ui::LayerStack, ftl::Future<FenceResult>, ui::kDisplayCapacity>
+ mAdditionalPreviousReleaseFences;
// Exposed so SurfaceFlinger can assert that it's held
const sp<SurfaceFlinger> mFlinger;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4164dc5..4474355 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -65,7 +65,6 @@
#include <gui/BufferQueue.h>
#include <gui/DebugEGLImageTracker.h>
#include <gui/IProducerListener.h>
-#include <gui/LayerDebugInfo.h>
#include <gui/LayerMetadata.h>
#include <gui/LayerState.h>
#include <gui/Surface.h>
@@ -1842,19 +1841,6 @@
return NO_ERROR;
}
-status_t SurfaceFlinger::getLayerDebugInfo(std::vector<gui::LayerDebugInfo>* outLayers) {
- outLayers->clear();
- auto future = mScheduler->schedule([=, this] {
- const auto display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
- mDrawingState.traverseInZOrder([&](Layer* layer) {
- outLayers->push_back(layer->getLayerDebugInfo(display.get()));
- });
- });
-
- future.wait();
- return NO_ERROR;
-}
-
status_t SurfaceFlinger::getCompositionPreference(
Dataspace* outDataspace, ui::PixelFormat* outPixelFormat,
Dataspace* outWideColorGamutDataspace,
@@ -2259,7 +2245,7 @@
outTransactionsAreEmpty = !needsTraversal;
const bool shouldCommit = (getTransactionFlags() & ~eTransactionFlushNeeded) || needsTraversal;
if (shouldCommit) {
- commitTransactions();
+ commitTransactionsLegacy();
}
bool mustComposite = latchBuffers() || shouldCommit;
@@ -2383,8 +2369,14 @@
mLayerHierarchyBuilder.update(mLayerLifecycleManager);
}
+ // Keep a copy of the drawing state (that is going to be overwritten
+ // by commitTransactionsLocked) outside of mStateLock so that the side
+ // effects of the State assignment don't happen with mStateLock held,
+ // which can cause deadlocks.
+ State drawingState(mDrawingState);
+ Mutex::Autolock lock(mStateLock);
bool mustComposite = false;
- mustComposite |= applyAndCommitDisplayTransactionStates(update.transactions);
+ mustComposite |= applyAndCommitDisplayTransactionStatesLocked(update.transactions);
{
ATRACE_NAME("LayerSnapshotBuilder:update");
@@ -2423,7 +2415,7 @@
bool newDataLatched = false;
if (!mLegacyFrontEndEnabled) {
ATRACE_NAME("DisplayCallbackAndStatsUpdates");
- mustComposite |= applyTransactions(update.transactions, vsyncId);
+ mustComposite |= applyTransactionsLocked(update.transactions, vsyncId);
traverseLegacyLayers([&](Layer* layer) { layer->commitTransaction(); });
const nsecs_t latchTime = systemTime();
bool unused = false;
@@ -3298,6 +3290,19 @@
void SurfaceFlinger::commitTransactions() {
ATRACE_CALL();
+ mDebugInTransaction = systemTime();
+
+ // Here we're guaranteed that some transaction flags are set
+ // so we can call commitTransactionsLocked unconditionally.
+ // We clear the flags with mStateLock held to guarantee that
+ // mCurrentState won't change until the transaction is committed.
+ mScheduler->modulateVsync({}, &VsyncModulator::onTransactionCommit);
+ commitTransactionsLocked(clearTransactionFlags(eTransactionMask));
+ mDebugInTransaction = 0;
+}
+
+void SurfaceFlinger::commitTransactionsLegacy() {
+ ATRACE_CALL();
// Keep a copy of the drawing state (that is going to be overwritten
// by commitTransactionsLocked) outside of mStateLock so that the side
@@ -5267,9 +5272,8 @@
return needsTraversal;
}
-bool SurfaceFlinger::applyAndCommitDisplayTransactionStates(
+bool SurfaceFlinger::applyAndCommitDisplayTransactionStatesLocked(
std::vector<TransactionState>& transactions) {
- Mutex::Autolock lock(mStateLock);
bool needsTraversal = false;
uint32_t transactionFlags = 0;
for (auto& transaction : transactions) {
@@ -6052,7 +6056,8 @@
if (mLegacyFrontEndEnabled) {
applyTransactions(transactions, VsyncId{0});
} else {
- applyAndCommitDisplayTransactionStates(transactions);
+ Mutex::Autolock lock(mStateLock);
+ applyAndCommitDisplayTransactionStatesLocked(transactions);
}
{
@@ -8287,7 +8292,11 @@
Mutex::Autolock lock(mStateLock);
const DisplayDevice* display = nullptr;
if (parent) {
- display = findDisplay([layerStack = parent->getLayerStack()](const auto& display) {
+ const frontend::LayerSnapshot* snapshot = mLayerLifecycleManagerEnabled
+ ? mLayerSnapshotBuilder.getSnapshot(parent->sequence)
+ : parent->getLayerSnapshot();
+ display = findDisplay([layerStack =
+ snapshot->outputFilter.layerStack](const auto& display) {
return display.getLayerStack() == layerStack;
}).get();
}
@@ -9903,22 +9912,6 @@
return binderStatusFromStatusT(status);
}
-binder::Status SurfaceComposerAIDL::getLayerDebugInfo(std::vector<gui::LayerDebugInfo>* outLayers) {
- if (!outLayers) {
- return binderStatusFromStatusT(UNEXPECTED_NULL);
- }
-
- IPCThreadState* ipc = IPCThreadState::self();
- const int pid = ipc->getCallingPid();
- const int uid = ipc->getCallingUid();
- if ((uid != AID_SHELL) && !PermissionCache::checkPermission(sDump, pid, uid)) {
- ALOGE("Layer debug info permission denied for pid=%d, uid=%d", pid, uid);
- return binderStatusFromStatusT(PERMISSION_DENIED);
- }
- status_t status = mFlinger->getLayerDebugInfo(outLayers);
- return binderStatusFromStatusT(status);
-}
-
binder::Status SurfaceComposerAIDL::getCompositionPreference(gui::CompositionPreference* outPref) {
ui::Dataspace dataspace;
ui::PixelFormat pixelFormat;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index c106abd..4a44be6 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -38,7 +38,6 @@
#include <gui/FrameTimestamps.h>
#include <gui/ISurfaceComposer.h>
#include <gui/ITransactionCompletedListener.h>
-#include <gui/LayerDebugInfo.h>
#include <gui/LayerState.h>
#include <layerproto/LayerProtoHeader.h>
#include <math/mat4.h>
@@ -599,7 +598,6 @@
status_t overrideHdrTypes(const sp<IBinder>& displayToken,
const std::vector<ui::Hdr>& hdrTypes);
status_t onPullAtom(const int32_t atomId, std::vector<uint8_t>* pulledData, bool* success);
- status_t getLayerDebugInfo(std::vector<gui::LayerDebugInfo>* outLayers);
status_t getCompositionPreference(ui::Dataspace* outDataspace, ui::PixelFormat* outPixelFormat,
ui::Dataspace* outWideColorGamutDataspace,
ui::PixelFormat* outWideColorGamutPixelFormat) const;
@@ -760,7 +758,8 @@
bool force = false)
REQUIRES(mStateLock, kMainThreadContext);
- void commitTransactions() EXCLUDES(mStateLock) REQUIRES(kMainThreadContext);
+ void commitTransactionsLegacy() EXCLUDES(mStateLock) REQUIRES(kMainThreadContext);
+ void commitTransactions() REQUIRES(kMainThreadContext, mStateLock);
void commitTransactionsLocked(uint32_t transactionFlags)
REQUIRES(mStateLock, kMainThreadContext);
void doCommitTransactions() REQUIRES(mStateLock);
@@ -810,8 +809,8 @@
bool flushTransactionQueues(VsyncId) REQUIRES(kMainThreadContext);
bool applyTransactions(std::vector<TransactionState>&, VsyncId) REQUIRES(kMainThreadContext);
- bool applyAndCommitDisplayTransactionStates(std::vector<TransactionState>& transactions)
- REQUIRES(kMainThreadContext);
+ bool applyAndCommitDisplayTransactionStatesLocked(std::vector<TransactionState>& transactions)
+ REQUIRES(kMainThreadContext, mStateLock);
// Returns true if there is at least one transaction that needs to be flushed
bool transactionFlushNeeded();
@@ -1601,7 +1600,6 @@
binder::Status overrideHdrTypes(const sp<IBinder>& display,
const std::vector<int32_t>& hdrTypes) override;
binder::Status onPullAtom(int32_t atomId, gui::PullAtomData* outPullData) override;
- binder::Status getLayerDebugInfo(std::vector<gui::LayerDebugInfo>* outLayers) override;
binder::Status getCompositionPreference(gui::CompositionPreference* outPref) override;
binder::Status getDisplayedContentSamplingAttributes(
const sp<IBinder>& display, gui::ContentSamplingAttributes* outAttrs) override;
diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp
index 9b83713..3b6a51a 100644
--- a/services/surfaceflinger/tests/Credentials_test.cpp
+++ b/services/surfaceflinger/tests/Credentials_test.cpp
@@ -21,7 +21,6 @@
#include <android/gui/ISurfaceComposer.h>
#include <gtest/gtest.h>
#include <gui/AidlStatusUtil.h>
-#include <gui/LayerDebugInfo.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <private/android_filesystem_config.h>
@@ -36,7 +35,6 @@
namespace android {
using Transaction = SurfaceComposerClient::Transaction;
-using gui::LayerDebugInfo;
using gui::aidl_utils::statusTFromBinderStatus;
using ui::ColorMode;
@@ -292,35 +290,6 @@
/**
* The following tests are for methods accessible directly through SurfaceFlinger.
*/
-TEST_F(CredentialsTest, GetLayerDebugInfo) {
- setupBackgroundSurface();
- sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
-
- // Historically, only root and shell can access the getLayerDebugInfo which
- // is called when we call dumpsys. I don't see a reason why we should change this.
- std::vector<LayerDebugInfo> outLayers;
- binder::Status status = binder::Status::ok();
- // Check with root.
- {
- UIDFaker f(AID_ROOT);
- status = sf->getLayerDebugInfo(&outLayers);
- ASSERT_EQ(NO_ERROR, statusTFromBinderStatus(status));
- }
-
- // Check as a shell.
- {
- UIDFaker f(AID_SHELL);
- status = sf->getLayerDebugInfo(&outLayers);
- ASSERT_EQ(NO_ERROR, statusTFromBinderStatus(status));
- }
-
- // Check as anyone else.
- {
- UIDFaker f(AID_BIN);
- status = sf->getLayerDebugInfo(&outLayers);
- ASSERT_EQ(PERMISSION_DENIED, statusTFromBinderStatus(status));
- }
-}
TEST_F(CredentialsTest, IsWideColorDisplayBasicCorrectness) {
const auto display = getFirstDisplayToken();