Merge "Create wrappers for Vibrator HALs"
diff --git a/libs/binder/ActivityManager.cpp b/libs/binder/ActivityManager.cpp
index 5e4c98f..d005058 100644
--- a/libs/binder/ActivityManager.cpp
+++ b/libs/binder/ActivityManager.cpp
@@ -98,6 +98,15 @@
     return PROCESS_STATE_UNKNOWN;
 }
 
+bool ActivityManager::setSchedPolicyCgroup(const int32_t tid, const int32_t group)
+{
+    sp<IActivityManager> service = getService();
+    if (service != nullptr) {
+        return service->setSchedPolicyCgroup(tid, group);
+    }
+    return false;
+}
+
 status_t ActivityManager::linkToDeath(const sp<IBinder::DeathRecipient>& recipient) {
     sp<IActivityManager> service = getService();
     if (service != nullptr) {
diff --git a/libs/binder/IActivityManager.cpp b/libs/binder/IActivityManager.cpp
index 1eb5363..a3021122 100644
--- a/libs/binder/IActivityManager.cpp
+++ b/libs/binder/IActivityManager.cpp
@@ -104,6 +104,17 @@
         }
         return reply.readInt32();
     }
+
+    virtual bool setSchedPolicyCgroup(const int32_t tid, const int32_t group)
+    {
+         Parcel data, reply;
+         data.writeInterfaceToken(IActivityManager::getInterfaceDescriptor());
+         data.writeInt32(tid);
+         data.writeInt32(group);
+         remote()->transact(SET_SCHED_POLICY_CGROUP_TRANSACTION, data, &reply);
+         if (reply.readExceptionCode() != 0) return false;
+         return reply.readBool();
+    }
 };
 
 // ------------------------------------------------------------------------------------
diff --git a/libs/binder/include/binder/ActivityManager.h b/libs/binder/include/binder/ActivityManager.h
index 9108e31..7043b17 100644
--- a/libs/binder/include/binder/ActivityManager.h
+++ b/libs/binder/include/binder/ActivityManager.h
@@ -77,7 +77,7 @@
     void unregisterUidObserver(const sp<IUidObserver>& observer);
     bool isUidActive(const uid_t uid, const String16& callingPackage);
     int getUidProcessState(const uid_t uid, const String16& callingPackage);
-
+    bool setSchedPolicyCgroup(const int32_t tid, const int32_t group);
 
   status_t linkToDeath(const sp<IBinder::DeathRecipient>& recipient);
     status_t unlinkToDeath(const sp<IBinder::DeathRecipient>& recipient);
diff --git a/libs/binder/include/binder/IActivityManager.h b/libs/binder/include/binder/IActivityManager.h
index e0248f6..fe58a41 100644
--- a/libs/binder/include/binder/IActivityManager.h
+++ b/libs/binder/include/binder/IActivityManager.h
@@ -39,13 +39,15 @@
     virtual void unregisterUidObserver(const sp<IUidObserver>& observer) = 0;
     virtual bool isUidActive(const uid_t uid, const String16& callingPackage) = 0;
     virtual int32_t getUidProcessState(const uid_t uid, const String16& callingPackage) = 0;
+    virtual bool setSchedPolicyCgroup(const int32_t tid, const int32_t group) = 0;
 
     enum {
         OPEN_CONTENT_URI_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
         REGISTER_UID_OBSERVER_TRANSACTION,
         UNREGISTER_UID_OBSERVER_TRANSACTION,
         IS_UID_ACTIVE_TRANSACTION,
-        GET_UID_PROCESS_STATE_TRANSACTION
+        GET_UID_PROCESS_STATE_TRANSACTION,
+        SET_SCHED_POLICY_CGROUP_TRANSACTION
     };
 };
 
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
index 8d80833..5023b6b 100644
--- a/libs/gui/BufferQueueCore.cpp
+++ b/libs/gui/BufferQueueCore.cpp
@@ -75,10 +75,12 @@
     if (NULL != fp) {
         const size_t size = 64;
         char proc_name[size];
-        fgets(proc_name, size, fp);
+        char* result = fgets(proc_name, size, fp);
         fclose(fp);
-        name = proc_name;
-        return NO_ERROR;
+        if (result != nullptr) {
+            name = proc_name;
+            return NO_ERROR;
+        }
     }
     return INVALID_OPERATION;
 }
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index 3997134..e8d3684 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -100,6 +100,7 @@
         "libgraphicsenv",
         "libnativewindow",
         "libbacktrace",
+        "libbase",
     ],
     target: {
         vendor: {
diff --git a/opengl/libs/EGL/BlobCache.cpp b/opengl/libs/EGL/BlobCache.cpp
index 74c4d7d..74fb019 100644
--- a/opengl/libs/EGL/BlobCache.cpp
+++ b/opengl/libs/EGL/BlobCache.cpp
@@ -21,7 +21,7 @@
 #include <errno.h>
 #include <inttypes.h>
 
-#include <cutils/properties.h>
+#include <android-base/properties.h>
 #include <log/log.h>
 #include <chrono>
 
@@ -165,7 +165,8 @@
 }
 
 size_t BlobCache::getFlattenedSize() const {
-    size_t size = align4(sizeof(Header) + PROPERTY_VALUE_MAX);
+    auto buildId = base::GetProperty("ro.build.id", "");
+    size_t size = align4(sizeof(Header) + buildId.size());
     for (const CacheEntry& e :  mCacheEntries) {
         std::shared_ptr<Blob> const& keyBlob = e.getKey();
         std::shared_ptr<Blob> const& valueBlob = e.getValue();
@@ -185,9 +186,9 @@
     header->mBlobCacheVersion = blobCacheVersion;
     header->mDeviceVersion = blobCacheDeviceVersion;
     header->mNumEntries = mCacheEntries.size();
-    char buildId[PROPERTY_VALUE_MAX];
-    header->mBuildIdLength = property_get("ro.build.id", buildId, "");
-    memcpy(header->mBuildId, buildId, header->mBuildIdLength);
+    auto buildId = base::GetProperty("ro.build.id", "");
+    header->mBuildIdLength = buildId.size();
+    memcpy(header->mBuildId, buildId.c_str(), header->mBuildIdLength);
 
     // Write cache entries
     uint8_t* byteBuffer = reinterpret_cast<uint8_t*>(buffer);
@@ -238,12 +239,11 @@
         ALOGE("unflatten: bad magic number: %" PRIu32, header->mMagicNumber);
         return -EINVAL;
     }
-    char buildId[PROPERTY_VALUE_MAX];
-    int len = property_get("ro.build.id", buildId, "");
+    auto buildId = base::GetProperty("ro.build.id", "");
     if (header->mBlobCacheVersion != blobCacheVersion ||
-            header->mDeviceVersion != blobCacheDeviceVersion ||
-            len != header->mBuildIdLength ||
-            strncmp(buildId, header->mBuildId, len)) {
+        header->mDeviceVersion != blobCacheDeviceVersion ||
+        buildId.size() != header->mBuildIdLength ||
+        strncmp(buildId.c_str(), header->mBuildId, buildId.size())) {
         // We treat version mismatches as an empty cache.
         return 0;
     }
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 391a410..fc066a5 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -24,8 +24,8 @@
 #include <dirent.h>
 #include <dlfcn.h>
 
+#include <android-base/properties.h>
 #include <android/dlext.h>
-#include <cutils/properties.h>
 #include <log/log.h>
 #include <utils/Timers.h>
 
@@ -241,12 +241,12 @@
         // i.e.:
         //      libGLES_${prop}.so, or:
         //      libEGL_${prop}.so, libGLESv1_CM_${prop}.so, libGLESv2_${prop}.so
-        char prop[PROPERTY_VALUE_MAX + 1];
         for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
-            if (property_get(key, prop, nullptr) <= 0) {
+            auto prop = base::GetProperty(key, "");
+            if (prop.empty()) {
                 continue;
             }
-            hnd = attempt_to_load_system_driver(cnx, prop, true);
+            hnd = attempt_to_load_system_driver(cnx, prop.c_str(), true);
             if (hnd) {
                 break;
             } else if (strcmp(key, DRIVER_SUFFIX_PROPERTY) == 0) {
@@ -510,9 +510,9 @@
         .library_namespace = ns,
     };
     void* so = nullptr;
-    char prop[PROPERTY_VALUE_MAX + 1];
     for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
-        if (property_get(key, prop, nullptr) <= 0) {
+        auto prop = base::GetProperty(key, "");
+        if (prop.empty()) {
             continue;
         }
         std::string name = std::string("lib") + kind + "_" + prop + ".so";
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index d5d57d7..43f7a07 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -18,7 +18,7 @@
 
 #include <EGL/egl.h>
 
-#include <cutils/properties.h>
+#include <android-base/properties.h>
 
 #include <log/log.h>
 
@@ -58,9 +58,7 @@
         } else {
             LOG_ALWAYS_FATAL(error);
         }
-        char value[PROPERTY_VALUE_MAX];
-        property_get("debug.egl.callstack", value, "0");
-        if (atoi(value)) {
+        if (base::GetBoolProperty("debug.egl.callstack", false)) {
             CallStack::log(LOG_TAG);
         }
     }
@@ -224,9 +222,7 @@
     pthread_mutex_unlock(&sLogPrintMutex);
     if (printLog) {
         ALOGE("called unimplemented OpenGL ES API");
-        char value[PROPERTY_VALUE_MAX];
-        property_get("debug.egl.callstack", value, "0");
-        if (atoi(value)) {
+        if (base::GetBoolProperty("debug.egl.callstack", false)) {
             CallStack::log(LOG_TAG);
         }
     }
diff --git a/opengl/libs/EGL/egl_angle_platform.cpp b/opengl/libs/EGL/egl_angle_platform.cpp
index 00caff2..97dc0f1 100644
--- a/opengl/libs/EGL/egl_angle_platform.cpp
+++ b/opengl/libs/EGL/egl_angle_platform.cpp
@@ -16,7 +16,6 @@
 
 #if defined(__ANDROID__)
 
-#include <cutils/properties.h>
 #include "Loader.h"
 #include "egl_angle_platform.h"
 
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 6af7cd2..3b1cf71 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -24,7 +24,6 @@
 #include <EGL/eglext_angle.h>
 #include <private/EGL/display.h>
 
-#include <cutils/properties.h>
 #include "Loader.h"
 #include "egl_angle_platform.h"
 #include "egl_cache.h"
@@ -32,6 +31,7 @@
 #include "egl_tls.h"
 
 #include <SurfaceFlingerProperties.h>
+#include <android-base/properties.h>
 #include <android/dlext.h>
 #include <dlfcn.h>
 #include <graphicsenv/GraphicsEnv.h>
@@ -73,7 +73,7 @@
 }
 
 bool needsAndroidPEglMitigation() {
-    static const int32_t vndk_version = property_get_int32("ro.vndk.version", -1);
+    static const int32_t vndk_version = base::GetIntProperty("ro.vndk.version", -1);
     return vndk_version <= 28;
 }
 
@@ -151,10 +151,8 @@
         attrs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
         attrs.push_back(EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE);
 
-        char prop[PROPERTY_VALUE_MAX];
-        property_get("debug.angle.validation", prop, "0");
         attrs.push_back(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE);
-        attrs.push_back(atoi(prop));
+        attrs.push_back(base::GetBoolProperty("debug.angle.validation", false));
 
         attrs.push_back(EGL_NONE);
 
@@ -372,16 +370,8 @@
 
         egl_cache_t::get()->initialize(this);
 
-        char value[PROPERTY_VALUE_MAX];
-        property_get("debug.egl.finish", value, "0");
-        if (atoi(value)) {
-            finishOnSwap = true;
-        }
-
-        property_get("debug.egl.traceGpuCompletion", value, "0");
-        if (atoi(value)) {
-            traceGpuCompletion = true;
-        }
+        finishOnSwap = base::GetBoolProperty("debug.egl.finish", false);
+        traceGpuCompletion = base::GetBoolProperty("debug.egl.traceGpuCompletion", false);
 
         // TODO: If device doesn't provide 1.4 or 1.5 then we'll be
         // changing the behavior from the past where we always advertise
diff --git a/opengl/libs/EGL/egl_layers.cpp b/opengl/libs/EGL/egl_layers.cpp
index 44a1c0b..ea86c9a 100644
--- a/opengl/libs/EGL/egl_layers.cpp
+++ b/opengl/libs/EGL/egl_layers.cpp
@@ -18,9 +18,9 @@
 
 #include <EGL/egl.h>
 #include <android-base/file.h>
+#include <android-base/properties.h>
 #include <android-base/strings.h>
 #include <android/dlext.h>
-#include <cutils/properties.h>
 #include <dlfcn.h>
 #include <graphicsenv/GraphicsEnv.h>
 #include <log/log.h>
@@ -157,9 +157,7 @@
 
     if (debug_layers.empty()) {
         // Only check system properties if Java settings are empty
-        char prop[PROPERTY_VALUE_MAX];
-        property_get("debug.gles.layers", prop, "");
-        debug_layers = prop;
+        debug_layers = base::GetProperty("debug.gles.layers", "");
     }
 
     return debug_layers;
diff --git a/opengl/libs/EGL/egl_platform_entries.cpp b/opengl/libs/EGL/egl_platform_entries.cpp
index c976c60..99283be 100644
--- a/opengl/libs/EGL/egl_platform_entries.cpp
+++ b/opengl/libs/EGL/egl_platform_entries.cpp
@@ -27,13 +27,13 @@
 #include <EGL/eglext.h>
 #include <EGL/eglext_angle.h>
 
-#include <android/hardware_buffer.h>
+#include <android-base/properties.h>
 #include <android-base/strings.h>
+#include <android/hardware_buffer.h>
 #include <graphicsenv/GraphicsEnv.h>
 #include <private/android/AHardwareBufferHelpers.h>
 
 #include <cutils/compiler.h>
-#include <cutils/properties.h>
 #include <log/log.h>
 
 #include <condition_variable>
@@ -381,10 +381,7 @@
     egl_connection_t* const cnx = &gEGLImpl;
     if (cnx->dso) {
         if (attrib_list) {
-            char value[PROPERTY_VALUE_MAX];
-            property_get("debug.egl.force_msaa", value, "false");
-
-            if (!strcmp(value, "true")) {
+            if (base::GetBoolProperty("debug.egl.force_msaa", false)) {
                 size_t attribCount = 0;
                 EGLint attrib = attrib_list[0];
 
diff --git a/opengl/libs/EGL/egl_tls.cpp b/opengl/libs/EGL/egl_tls.cpp
index aaecb62..8d118e0 100644
--- a/opengl/libs/EGL/egl_tls.cpp
+++ b/opengl/libs/EGL/egl_tls.cpp
@@ -18,7 +18,7 @@
 
 #include <stdlib.h>
 
-#include <cutils/properties.h>
+#include <android-base/properties.h>
 #include <log/log.h>
 #include "CallStack.h"
 #include "egl_platform_entries.h"
@@ -96,9 +96,7 @@
         if (!quiet) {
             ALOGE("%s:%d error %x (%s)",
                     caller, line, error, egl_strerror(error));
-            char value[PROPERTY_VALUE_MAX];
-            property_get("debug.egl.callstack", value, "0");
-            if (atoi(value)) {
+            if (base::GetBoolProperty("debug.egl.callstack", false)) {
                 CallStack::log(LOG_TAG);
             }
         }
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index 264d287..a1514af 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -1318,7 +1318,7 @@
     // joystick and gamepad buttons which are handled like keyboards for the most part.
     bool haveKeyboardKeys =
             containsNonZeroByte(device->keyBitmask, 0, sizeof_bit_array(BTN_MISC)) ||
-            containsNonZeroByte(device->keyBitmask, sizeof_bit_array(KEY_OK),
+            containsNonZeroByte(device->keyBitmask, sizeof_bit_array(BTN_WHEEL),
                                 sizeof_bit_array(KEY_MAX + 1));
     bool haveGamepadButtons = containsNonZeroByte(device->keyBitmask, sizeof_bit_array(BTN_MISC),
                                                   sizeof_bit_array(BTN_MOUSE)) ||
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
index 7be4a58..e009221 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
@@ -233,7 +233,7 @@
 }
 
 bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
-    return scanCode < BTN_MOUSE || scanCode >= KEY_OK ||
+    return scanCode < BTN_MOUSE || scanCode >= BTN_WHEEL ||
             (scanCode >= BTN_MISC && scanCode < BTN_MOUSE) ||
             (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI);
 }
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 109edfe..c457a15 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -1848,6 +1848,28 @@
     ASSERT_LE(prevTimestamp, keyArgs.eventTime);
 }
 
+/**
+ * The Steam controller sends BTN_GEAR_DOWN and BTN_GEAR_UP for the two "paddle" buttons
+ * on the back. In this test, we make sure that BTN_GEAR_DOWN / BTN_WHEEL and BTN_GEAR_UP
+ * are passed to the listener.
+ */
+static_assert(BTN_GEAR_DOWN == BTN_WHEEL);
+TEST_F(InputReaderIntegrationTest, SendsGearDownAndUpToInputListener) {
+    std::unique_ptr<UinputSteamController> controller = createUinputDevice<UinputSteamController>();
+    ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
+    NotifyKeyArgs keyArgs;
+
+    controller->pressAndReleaseKey(BTN_GEAR_DOWN);
+    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_DOWN
+    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_UP
+    ASSERT_EQ(BTN_GEAR_DOWN, keyArgs.scanCode);
+
+    controller->pressAndReleaseKey(BTN_GEAR_UP);
+    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_DOWN
+    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_UP
+    ASSERT_EQ(BTN_GEAR_UP, keyArgs.scanCode);
+}
+
 // --- TouchProcessTest ---
 class TouchIntegrationTest : public InputReaderIntegrationTest {
 protected:
diff --git a/services/inputflinger/tests/UinputDevice.cpp b/services/inputflinger/tests/UinputDevice.cpp
index 10e7293..0659511 100644
--- a/services/inputflinger/tests/UinputDevice.cpp
+++ b/services/inputflinger/tests/UinputDevice.cpp
@@ -125,6 +125,9 @@
     pressAndReleaseKey(KEY_HOME);
 }
 
+// --- UinputSteamController
+UinputSteamController::UinputSteamController() : UinputKeyboard({BTN_GEAR_DOWN, BTN_GEAR_UP}) {}
+
 // --- UinputTouchScreen ---
 UinputTouchScreen::UinputTouchScreen(const Rect* size)
       : UinputDevice(UinputTouchScreen::DEVICE_NAME), mSize(*size) {}
diff --git a/services/inputflinger/tests/UinputDevice.h b/services/inputflinger/tests/UinputDevice.h
index ec3cd9f..22d1f63 100644
--- a/services/inputflinger/tests/UinputDevice.h
+++ b/services/inputflinger/tests/UinputDevice.h
@@ -108,6 +108,16 @@
     UinputHomeKey();
 };
 
+// A joystick device that sends a BTN_GEAR_DOWN / BTN_WHEEL key.
+class UinputSteamController : public UinputKeyboard {
+public:
+    template <class D, class... Ts>
+    friend std::unique_ptr<D> createUinputDevice(Ts... args);
+
+private:
+    UinputSteamController();
+};
+
 // --- UinputTouchScreen ---
 // A touch screen device with specific size.
 class UinputTouchScreen : public UinputDevice {
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 81f2dd1..1faf775 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -149,9 +149,9 @@
         // a modification of the axes of rotation. To account for this we
         // need to reorient the inverse rotation in terms of the current
         // axes of rotation.
-        bool is_h_flipped = (invTransform & HAL_TRANSFORM_FLIP_H) != 0;
-        bool is_v_flipped = (invTransform & HAL_TRANSFORM_FLIP_V) != 0;
-        if (is_h_flipped == is_v_flipped) {
+        bool isHFlipped = (invTransform & HAL_TRANSFORM_FLIP_H) != 0;
+        bool isVFlipped = (invTransform & HAL_TRANSFORM_FLIP_V) != 0;
+        if (isHFlipped == isVFlipped) {
             invTransform ^= HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_FLIP_H;
         }
         std::swap(winWidth, winHeight);
@@ -160,18 +160,18 @@
             activeCrop.transform(invTransform, bufferSize.getWidth(), bufferSize.getHeight());
 
     // below, crop is intersected with winCrop expressed in crop's coordinate space
-    float xScale = crop.getWidth() / float(winWidth);
-    float yScale = crop.getHeight() / float(winHeight);
+    const float xScale = crop.getWidth() / float(winWidth);
+    const float yScale = crop.getHeight() / float(winHeight);
 
-    float insetL = winCrop.left * xScale;
-    float insetT = winCrop.top * yScale;
-    float insetR = (winWidth - winCrop.right) * xScale;
-    float insetB = (winHeight - winCrop.bottom) * yScale;
+    const float insetLeft = winCrop.left * xScale;
+    const float insetTop = winCrop.top * yScale;
+    const float insetRight = (winWidth - winCrop.right) * xScale;
+    const float insetBottom = (winHeight - winCrop.bottom) * yScale;
 
-    crop.left += insetL;
-    crop.top += insetT;
-    crop.right -= insetR;
-    crop.bottom -= insetB;
+    crop.left += insetLeft;
+    crop.top += insetTop;
+    crop.right -= insetRight;
+    crop.bottom -= insetBottom;
 
     return crop;
 }
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 2cebecb..1efb7a0 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -162,19 +162,19 @@
     mOrientation = orientation;
 
     const Rect& displayBounds = getCompositionDisplay()->getState().bounds;
-    const int w = displayBounds.width();
-    const int h = displayBounds.height();
+    const int displayWidth = displayBounds.width();
+    const int displayHeight = displayBounds.height();
 
-    ui::Transform R;
+    ui::Transform rotation;
     if (const auto flags = ui::Transform::toRotationFlags(orientation);
         flags != ui::Transform::ROT_INVALID) {
-        R.set(flags, w, h);
+        rotation.set(flags, displayWidth, displayHeight);
     }
 
     if (!frame.isValid()) {
         // the destination frame can be invalid if it has never been set,
         // in that case we assume the whole display frame.
-        frame = Rect(w, h);
+        frame = Rect(displayWidth, displayHeight);
     }
 
     if (viewport.isEmpty()) {
@@ -182,45 +182,45 @@
         // we assume the whole display size.
         // it's also invalid to have an empty viewport, so we handle that
         // case in the same way.
-        viewport = Rect(w, h);
-        if (R.getOrientation() & ui::Transform::ROT_90) {
+        viewport = Rect(displayWidth, displayHeight);
+        if (rotation.getOrientation() & ui::Transform::ROT_90) {
             // viewport is always specified in the logical orientation
             // of the display (ie: post-rotation).
             std::swap(viewport.right, viewport.bottom);
         }
     }
 
-    ui::Transform TL, TP, S;
-    float src_width  = viewport.width();
-    float src_height = viewport.height();
-    float dst_width  = frame.width();
-    float dst_height = frame.height();
-    if (src_width != dst_width || src_height != dst_height) {
-        float sx = dst_width  / src_width;
-        float sy = dst_height / src_height;
-        S.set(sx, 0, 0, sy);
+    ui::Transform logicalTranslation, physicalTranslation, scale;
+    const float sourceWidth = viewport.width();
+    const float sourceHeight = viewport.height();
+    const float destWidth = frame.width();
+    const float destHeight = frame.height();
+    if (sourceWidth != destWidth || sourceHeight != destHeight) {
+        const float scaleX = destWidth / sourceWidth;
+        const float scaleY = destHeight / sourceHeight;
+        scale.set(scaleX, 0, 0, scaleY);
     }
 
-    float src_x = viewport.left;
-    float src_y = viewport.top;
-    float dst_x = frame.left;
-    float dst_y = frame.top;
-    TL.set(-src_x, -src_y);
-    TP.set(dst_x, dst_y);
+    const float sourceX = viewport.left;
+    const float sourceY = viewport.top;
+    const float destX = frame.left;
+    const float destY = frame.top;
+    logicalTranslation.set(-sourceX, -sourceY);
+    physicalTranslation.set(destX, destY);
 
     // need to take care of primary display rotation for globalTransform
     // for case if the panel is not installed aligned with device orientation
     if (isPrimary()) {
         if (const auto flags = ui::Transform::toRotationFlags(orientation + mPhysicalOrientation);
             flags != ui::Transform::ROT_INVALID) {
-            R.set(flags, w, h);
+            rotation.set(flags, displayWidth, displayHeight);
         }
     }
 
     // The viewport and frame are both in the logical orientation.
     // Apply the logical translation, scale to physical size, apply the
     // physical translation and finally rotate to the physical orientation.
-    ui::Transform globalTransform = R * TP * S * TL;
+    ui::Transform globalTransform = rotation * physicalTranslation * scale * logicalTranslation;
 
     const uint8_t type = globalTransform.getType();
     const bool needsFiltering =
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index d73fd8b..f87c1f8 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -66,15 +66,15 @@
     // TODO (140302863) remove this and use the vsync_reactor system.
     if (property_get_bool("debug.sf.vsync_reactor", true)) {
         // TODO (144707443) tune Predictor tunables.
-        static constexpr int default_rate = 60;
-        static constexpr auto initial_period =
-                std::chrono::duration<nsecs_t, std::ratio<1, default_rate>>(1);
+        static constexpr int defaultRate = 60;
+        static constexpr auto initialPeriod =
+                std::chrono::duration<nsecs_t, std::ratio<1, defaultRate>>(1);
         static constexpr size_t vsyncTimestampHistorySize = 20;
         static constexpr size_t minimumSamplesForPrediction = 6;
         static constexpr uint32_t discardOutlierPercent = 20;
         auto tracker = std::make_unique<
                 scheduler::VSyncPredictor>(std::chrono::duration_cast<std::chrono::nanoseconds>(
-                                                   initial_period)
+                                                   initialPeriod)
                                                    .count(),
                                            vsyncTimestampHistorySize, minimumSamplesForPrediction,
                                            discardOutlierPercent);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4549ab3..191c81e 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -125,6 +125,19 @@
 #include "android-base/parseint.h"
 #include "android-base/stringprintf.h"
 
+#define MAIN_THREAD ACQUIRE(mStateLock) RELEASE(mStateLock)
+
+#define ON_MAIN_THREAD(expr)                                       \
+    [&] {                                                          \
+        LOG_FATAL_IF(std::this_thread::get_id() != mMainThreadId); \
+        UnnecessaryLock lock(mStateLock);                          \
+        return (expr);                                             \
+    }()
+
+#undef NO_THREAD_SAFETY_ANALYSIS
+#define NO_THREAD_SAFETY_ANALYSIS \
+    _Pragma("GCC error \"Prefer MAIN_THREAD macros or {Conditional,Timed,Unnecessary}Lock.\"")
+
 namespace android {
 
 using namespace std::string_literals;
@@ -173,12 +186,12 @@
 #pragma clang diagnostic pop
 
 template <typename Mutex>
-struct ConditionalLockGuard {
-    ConditionalLockGuard(Mutex& mutex, bool lock) : mutex(mutex), lock(lock) {
+struct SCOPED_CAPABILITY ConditionalLockGuard {
+    ConditionalLockGuard(Mutex& mutex, bool lock) ACQUIRE(mutex) : mutex(mutex), lock(lock) {
         if (lock) mutex.lock();
     }
 
-    ~ConditionalLockGuard() {
+    ~ConditionalLockGuard() RELEASE() {
         if (lock) mutex.unlock();
     }
 
@@ -188,6 +201,27 @@
 
 using ConditionalLock = ConditionalLockGuard<Mutex>;
 
+struct SCOPED_CAPABILITY TimedLock {
+    TimedLock(Mutex& mutex, nsecs_t timeout, const char* whence) ACQUIRE(mutex)
+          : mutex(mutex), status(mutex.timedLock(timeout)) {
+        ALOGE_IF(!locked(), "%s timed out locking: %s (%d)", whence, strerror(-status), status);
+    }
+
+    ~TimedLock() RELEASE() {
+        if (locked()) mutex.unlock();
+    }
+
+    bool locked() const { return status == NO_ERROR; }
+
+    Mutex& mutex;
+    const status_t status;
+};
+
+struct SCOPED_CAPABILITY UnnecessaryLock {
+    explicit UnnecessaryLock(Mutex& mutex) ACQUIRE(mutex) {}
+    ~UnnecessaryLock() RELEASE() {}
+};
+
 // TODO(b/141333600): Consolidate with HWC2::Display::Config::Builder::getDefaultDensity.
 constexpr float FALLBACK_DENSITY = ACONFIGURATION_DENSITY_TV;
 
@@ -995,7 +1029,7 @@
     }
 
     auto future = schedule([=]() -> status_t {
-        const auto display = getDisplayDeviceLocked(displayToken);
+        const auto display = ON_MAIN_THREAD(getDisplayDeviceLocked(displayToken));
         if (!display) {
             ALOGE("Attempt to set allowed display configs for invalid display token %p",
                   displayToken.get());
@@ -1180,7 +1214,7 @@
 }
 
 status_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& displayToken, ColorMode mode) {
-    schedule([=] {
+    schedule([=]() MAIN_THREAD {
         Vector<ColorMode> modes;
         getDisplayColorModes(displayToken, &modes);
         bool exists = std::find(std::begin(modes), std::end(modes), mode) != std::end(modes);
@@ -1226,7 +1260,7 @@
 }
 
 void SurfaceFlinger::setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on) {
-    static_cast<void>(schedule([=] {
+    static_cast<void>(schedule([=]() MAIN_THREAD {
         if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
             getHwComposer().setAutoLowLatencyMode(*displayId, on);
         } else {
@@ -1257,7 +1291,7 @@
 }
 
 void SurfaceFlinger::setGameContentType(const sp<IBinder>& displayToken, bool on) {
-    static_cast<void>(schedule([=] {
+    static_cast<void>(schedule([=]() MAIN_THREAD {
         if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
             const auto type = on ? hal::ContentType::GAME : hal::ContentType::NONE;
             getHwComposer().setContentType(*displayId, type);
@@ -1323,7 +1357,7 @@
 status_t SurfaceFlinger::setDisplayContentSamplingEnabled(const sp<IBinder>& displayToken,
                                                           bool enable, uint8_t componentMask,
                                                           uint64_t maxFrames) {
-    return schedule([=]() -> status_t {
+    return schedule([=]() MAIN_THREAD -> status_t {
                if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
                    return getHwComposer().setDisplayContentSamplingEnabled(*displayId, enable,
                                                                            componentMask,
@@ -1392,13 +1426,9 @@
     return mScheduler->injectVSync(when, calculateExpectedPresentTime(when)) ? NO_ERROR : BAD_VALUE;
 }
 
-status_t SurfaceFlinger::getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) const
-        NO_THREAD_SAFETY_ANALYSIS {
-    // Try to acquire a lock for 1s, fail gracefully
-    const status_t err = mStateLock.timedLock(s2ns(1));
-    const bool locked = (err == NO_ERROR);
-    if (!locked) {
-        ALOGE("LayerDebugInfo: SurfaceFlinger unresponsive (%s [%d]) - exit", strerror(-err), err);
+status_t SurfaceFlinger::getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) const {
+    TimedLock lock(mStateLock, s2ns(1), __FUNCTION__);
+    if (!lock.locked()) {
         return TIMED_OUT;
     }
 
@@ -1407,7 +1437,6 @@
     mCurrentState.traverseInZOrder(
             [&](Layer* layer) { outLayers->push_back(layer->getLayerDebugInfo(display.get())); });
 
-    mStateLock.unlock();
     return NO_ERROR;
 }
 
@@ -1464,7 +1493,7 @@
         return BAD_VALUE;
     }
 
-    return promise::chain(schedule([=] {
+    return promise::chain(schedule([=]() MAIN_THREAD {
                if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
                    return getHwComposer().setDisplayBrightness(*displayId, brightness);
                } else {
@@ -1577,7 +1606,7 @@
 }
 
 void SurfaceFlinger::onHotplugReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId,
-                                       hal::Connection connection) NO_THREAD_SAFETY_ANALYSIS {
+                                       hal::Connection connection) {
     ALOGV("%s(%d, %" PRIu64 ", %s)", __FUNCTION__, sequenceId, hwcDisplayId,
           connection == hal::Connection::CONNECTED ? "connected" : "disconnected");
 
@@ -1630,8 +1659,7 @@
 
     // Enable / Disable HWVsync from the main thread to avoid race conditions with
     // display power state.
-    static_cast<void>(
-            schedule([=]() NO_THREAD_SAFETY_ANALYSIS { setPrimaryVsyncEnabledInternal(enabled); }));
+    static_cast<void>(schedule([=]() MAIN_THREAD { setPrimaryVsyncEnabledInternal(enabled); }));
 }
 
 void SurfaceFlinger::setPrimaryVsyncEnabledInternal(bool enabled) {
@@ -1647,7 +1675,6 @@
     }
 }
 
-// Note: it is assumed the caller holds |mStateLock| when this is called
 void SurfaceFlinger::resetDisplayState() {
     mScheduler->disableHardwareVsync(true);
     // Clear the drawing state so that the logic inside of
@@ -1740,7 +1767,7 @@
     setTransactionFlags(eDisplayTransactionNeeded);
 }
 
-sp<Fence> SurfaceFlinger::previousFrameFence() NO_THREAD_SAFETY_ANALYSIS {
+sp<Fence> SurfaceFlinger::previousFrameFence() {
     // We are storing the last 2 present fences. If sf's phase offset is to be
     // woken up before the actual vsync but targeting the next vsync, we need to check
     // fence N-2
@@ -1748,7 +1775,7 @@
                                                 : mPreviousPresentFences[1];
 }
 
-bool SurfaceFlinger::previousFramePending(int graceTimeMs) NO_THREAD_SAFETY_ANALYSIS {
+bool SurfaceFlinger::previousFramePending(int graceTimeMs) {
     ATRACE_CALL();
     const sp<Fence>& fence = previousFrameFence();
 
@@ -1762,7 +1789,7 @@
     return status == -ETIME;
 }
 
-nsecs_t SurfaceFlinger::previousFramePresentTime() NO_THREAD_SAFETY_ANALYSIS {
+nsecs_t SurfaceFlinger::previousFramePresentTime() {
     const sp<Fence>& fence = previousFrameFence();
 
     if (fence == Fence::NO_FENCE) {
@@ -1780,8 +1807,7 @@
     return mVSyncModulator->getOffsets().sf > 0 ? presentTime : presentTime + stats.vsyncPeriod;
 }
 
-void SurfaceFlinger::onMessageReceived(int32_t what,
-                                       nsecs_t expectedVSyncTime) NO_THREAD_SAFETY_ANALYSIS {
+void SurfaceFlinger::onMessageReceived(int32_t what, nsecs_t expectedVSyncTime) {
     ATRACE_CALL();
     switch (what) {
         case MessageQueue::INVALIDATE: {
@@ -1795,7 +1821,7 @@
     }
 }
 
-void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) NO_THREAD_SAFETY_ANALYSIS {
+void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) {
     ATRACE_CALL();
 
     const nsecs_t frameStart = systemTime();
@@ -1868,7 +1894,7 @@
         // We received the present fence from the HWC, so we assume it successfully updated
         // the config, hence we update SF.
         mSetActiveConfigPending = false;
-        setActiveConfigInternal();
+        ON_MAIN_THREAD(setActiveConfigInternal());
     }
 
     if (framePending && mPropagateBackpressure) {
@@ -1887,12 +1913,12 @@
             std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count();
     // If we're in a user build then don't push any atoms
     if (!mIsUserBuild && mMissedFrameJankCount > 0) {
-        const auto displayDevice = getDefaultDisplayDeviceLocked();
+        const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
         // Only report jank when the display is on, as displays in DOZE
         // power mode may operate at a different frame rate than is
         // reported in their config, which causes noticeable (but less
         // severe) jank.
-        if (displayDevice && displayDevice->getPowerMode() == hal::PowerMode::ON) {
+        if (display && display->getPowerMode() == hal::PowerMode::ON) {
             const nsecs_t currentTime = systemTime();
             const nsecs_t jankDuration = currentTime - mMissedFrameJankStart;
             if (jankDuration > kMinJankyDuration && jankDuration < kMaxJankyDuration) {
@@ -1949,7 +1975,7 @@
         mScheduler->chooseRefreshRateForContent();
     }
 
-    performSetActiveConfig();
+    ON_MAIN_THREAD(performSetActiveConfig());
 
     updateCursorAsync();
     updateInputFlinger();
@@ -1998,8 +2024,9 @@
     mRefreshPending = false;
 
     compositionengine::CompositionRefreshArgs refreshArgs;
-    refreshArgs.outputs.reserve(mDisplays.size());
-    for (const auto& [_, display] : mDisplays) {
+    const auto& displays = ON_MAIN_THREAD(mDisplays);
+    refreshArgs.outputs.reserve(displays.size());
+    for (const auto& [_, display] : displays) {
         refreshArgs.outputs.push_back(display->getCompositionDisplay());
     }
     mDrawingState.traverseInZOrder([&refreshArgs](Layer* layer) {
@@ -2054,21 +2081,18 @@
 
     const bool prevFrameHadDeviceComposition = mHadDeviceComposition;
 
-    mHadClientComposition =
-            std::any_of(mDisplays.cbegin(), mDisplays.cend(), [](const auto& tokenDisplayPair) {
-                auto& displayDevice = tokenDisplayPair.second;
-                return displayDevice->getCompositionDisplay()->getState().usesClientComposition &&
-                        !displayDevice->getCompositionDisplay()->getState().reusedClientComposition;
-            });
-    mHadDeviceComposition =
-            std::any_of(mDisplays.cbegin(), mDisplays.cend(), [](const auto& tokenDisplayPair) {
-                auto& displayDevice = tokenDisplayPair.second;
-                return displayDevice->getCompositionDisplay()->getState().usesDeviceComposition;
-            });
+    mHadClientComposition = std::any_of(displays.cbegin(), displays.cend(), [](const auto& pair) {
+        const auto& state = pair.second->getCompositionDisplay()->getState();
+        return state.usesClientComposition && !state.reusedClientComposition;
+    });
+    mHadDeviceComposition = std::any_of(displays.cbegin(), displays.cend(), [](const auto& pair) {
+        const auto& state = pair.second->getCompositionDisplay()->getState();
+        return state.usesDeviceComposition;
+    });
     mReusedClientComposition =
-            std::any_of(mDisplays.cbegin(), mDisplays.cend(), [](const auto& tokenDisplayPair) {
-                auto& displayDevice = tokenDisplayPair.second;
-                return displayDevice->getCompositionDisplay()->getState().reusedClientComposition;
+            std::any_of(displays.cbegin(), displays.cend(), [](const auto& pair) {
+                const auto& state = pair.second->getCompositionDisplay()->getState();
+                return state.reusedClientComposition;
             });
 
     // Only report a strategy change if we move in and out of composition with hw overlays
@@ -2174,14 +2198,14 @@
     for (auto& layer : mLayersWithQueuedFrames) {
         layer->releasePendingBuffer(dequeueReadyTime);
     }
-    // |mStateLock| not needed as we are on the main thread
-    const auto displayDevice = getDefaultDisplayDeviceLocked();
+
+    const auto* display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked()).get();
 
     getBE().mGlCompositionDoneTimeline.updateSignalTimes();
     std::shared_ptr<FenceTime> glCompositionDoneFenceTime;
-    if (displayDevice && displayDevice->getCompositionDisplay()->getState().usesClientComposition) {
+    if (display && display->getCompositionDisplay()->getState().usesClientComposition) {
         glCompositionDoneFenceTime =
-                std::make_shared<FenceTime>(displayDevice->getCompositionDisplay()
+                std::make_shared<FenceTime>(display->getCompositionDisplay()
                                                     ->getRenderSurface()
                                                     ->getClientTargetAcquireFence());
         getBE().mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime);
@@ -2191,9 +2215,8 @@
 
     getBE().mDisplayTimeline.updateSignalTimes();
     mPreviousPresentFences[1] = mPreviousPresentFences[0];
-    mPreviousPresentFences[0] = displayDevice
-            ? getHwComposer().getPresentFence(*displayDevice->getId())
-            : Fence::NO_FENCE;
+    mPreviousPresentFences[0] =
+            display ? getHwComposer().getPresentFence(*display->getId()) : Fence::NO_FENCE;
     auto presentFenceTime = std::make_shared<FenceTime>(mPreviousPresentFences[0]);
     getBE().mDisplayTimeline.push(presentFenceTime);
 
@@ -2212,9 +2235,8 @@
     }
 
     mDrawingState.traverse([&](Layer* layer) {
-        const bool frameLatched =
-                layer->onPostComposition(displayDevice.get(), glCompositionDoneFenceTime,
-                                         presentFenceTime, compositorTiming);
+        const bool frameLatched = layer->onPostComposition(display, glCompositionDoneFenceTime,
+                                                           presentFenceTime, compositorTiming);
         if (frameLatched) {
             recordBufferingStats(layer->getName(), layer->getOccupancyHistory(false));
         }
@@ -2223,14 +2245,15 @@
     mTransactionCompletedThread.addPresentFence(mPreviousPresentFences[0]);
     mTransactionCompletedThread.sendCallbacks();
 
-    if (displayDevice && displayDevice->isPrimary() &&
-        displayDevice->getPowerMode() == hal::PowerMode::ON && presentFenceTime->isValid()) {
+    if (display && display->isPrimary() && display->getPowerMode() == hal::PowerMode::ON &&
+        presentFenceTime->isValid()) {
         mScheduler->addPresentFence(presentFenceTime);
     }
 
+    const bool isDisplayConnected = display && getHwComposer().isConnected(*display->getId());
+
     if (!hasSyncFramework) {
-        if (displayDevice && getHwComposer().isConnected(*displayDevice->getId()) &&
-            displayDevice->isPoweredOn()) {
+        if (isDisplayConnected && display->isPoweredOn()) {
             mScheduler->enableHardwareVsync();
         }
     }
@@ -2241,11 +2264,10 @@
         if (presentFenceTime->isValid()) {
             mAnimFrameTracker.setActualPresentFence(
                     std::move(presentFenceTime));
-        } else if (displayDevice && getHwComposer().isConnected(*displayDevice->getId())) {
+        } else if (isDisplayConnected) {
             // The HWC doesn't support present fences, so use the refresh
             // timestamp instead.
-            const nsecs_t presentTime =
-                    getHwComposer().getRefreshTimestamp(*displayDevice->getId());
+            const nsecs_t presentTime = getHwComposer().getRefreshTimestamp(*display->getId());
             mAnimFrameTracker.setActualPresentTime(presentTime);
         }
         mAnimFrameTracker.advanceFrame();
@@ -2266,8 +2288,7 @@
     const size_t appConnections = mScheduler->getEventThreadConnectionCount(mAppConnectionHandle);
     mTimeStats->recordDisplayEventConnectionCount(sfConnections + appConnections);
 
-    if (displayDevice && getHwComposer().isConnected(*displayDevice->getId()) &&
-        !displayDevice->isPoweredOn()) {
+    if (isDisplayConnected && !display->isPoweredOn()) {
         return;
     }
 
@@ -2323,7 +2344,7 @@
 }
 
 void SurfaceFlinger::computeLayerBounds() {
-    for (const auto& pair : mDisplays) {
+    for (const auto& pair : ON_MAIN_THREAD(mDisplays)) {
         const auto& displayDevice = pair.second;
         const auto display = displayDevice->getCompositionDisplay();
         for (const auto& layer : mDrawingState.layersSortedByZ) {
@@ -2338,10 +2359,8 @@
     }
 }
 
-void SurfaceFlinger::postFrame()
-{
-    // |mStateLock| not needed as we are on the main thread
-    const auto display = getDefaultDisplayDeviceLocked();
+void SurfaceFlinger::postFrame() {
+    const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
     if (display && getHwComposer().isConnected(*display->getId())) {
         uint32_t flipCount = display->getPageFlipCount();
         if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
@@ -2772,7 +2791,7 @@
         sp<const DisplayDevice> hintDisplay;
         uint32_t currentlayerStack = 0;
         bool first = true;
-        mCurrentState.traverse([&](Layer* layer) {
+        mCurrentState.traverse([&](Layer* layer) REQUIRES(mStateLock) {
             // NOTE: we rely on the fact that layers are sorted by
             // layerStack first (so we don't have to traverse the list
             // of displays for every layer).
@@ -2885,10 +2904,9 @@
     mPendingInputWindowCommands.clear();
 }
 
-void SurfaceFlinger::updateCursorAsync()
-{
+void SurfaceFlinger::updateCursorAsync() {
     compositionengine::CompositionRefreshArgs refreshArgs;
-    for (const auto& [_, display] : mDisplays) {
+    for (const auto& [_, display] : ON_MAIN_THREAD(mDisplays)) {
         if (display->getId()) {
             refreshArgs.outputs.push_back(display->getCompositionDisplay());
         }
@@ -2898,7 +2916,7 @@
 }
 
 void SurfaceFlinger::changeRefreshRate(const RefreshRate& refreshRate,
-                                       Scheduler::ConfigEvent event) NO_THREAD_SAFETY_ANALYSIS {
+                                       Scheduler::ConfigEvent event) {
     // If this is called from the main thread mStateLock must be locked before
     // Currently the only way to call this function from the main thread is from
     // Sheduler::chooseRefreshRateForContent
@@ -3024,7 +3042,7 @@
 }
 
 void SurfaceFlinger::invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty) {
-    for (const auto& [token, displayDevice] : mDisplays) {
+    for (const auto& [token, displayDevice] : ON_MAIN_THREAD(mDisplays)) {
         auto display = displayDevice->getCompositionDisplay();
         if (display->belongsInOutput(layer->getLayerStack(), layer->getPrimaryDisplayOnly())) {
             display->editState().dirtyRegion.orSelf(dirty);
@@ -4125,7 +4143,7 @@
 
 void SurfaceFlinger::initializeDisplays() {
     // Async since we may be called from the main thread.
-    static_cast<void>(schedule([this]() NO_THREAD_SAFETY_ANALYSIS { onInitializeDisplays(); }));
+    static_cast<void>(schedule([this]() MAIN_THREAD { onInitializeDisplays(); }));
 }
 
 void SurfaceFlinger::setVsyncEnabledInHWC(DisplayId displayId, hal::Vsync enabled) {
@@ -4216,7 +4234,7 @@
 }
 
 void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
-    schedule([=]() NO_THREAD_SAFETY_ANALYSIS {
+    schedule([=]() MAIN_THREAD {
         const auto display = getDisplayDeviceLocked(displayToken);
         if (!display) {
             ALOGE("Attempt to set power mode %d for invalid display token %p", mode,
@@ -4229,8 +4247,7 @@
     }).wait();
 }
 
-status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args,
-                                bool asProto) NO_THREAD_SAFETY_ANALYSIS {
+status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, bool asProto) {
     std::string result;
 
     IPCThreadState* ipc = IPCThreadState::self();
@@ -4242,18 +4259,6 @@
         StringAppendF(&result, "Permission Denial: can't dump SurfaceFlinger from pid=%d, uid=%d\n",
                       pid, uid);
     } else {
-        // Try to get the main lock, but give up after one second
-        // (this would indicate SF is stuck, but we want to be able to
-        // print something in dumpsys).
-        status_t err = mStateLock.timedLock(s2ns(1));
-        bool locked = (err == NO_ERROR);
-        if (!locked) {
-            StringAppendF(&result,
-                          "SurfaceFlinger appears to be unresponsive (%s [%d]), dumping anyways "
-                          "(no locks held)\n",
-                          strerror(-err), err);
-        }
-
         static const std::unordered_map<std::string, Dumper> dumpers = {
                 {"--display-id"s, dumper(&SurfaceFlinger::dumpDisplayIdentificationData)},
                 {"--dispsync"s,
@@ -4271,18 +4276,23 @@
 
         const auto flag = args.empty() ? ""s : std::string(String8(args[0]));
 
-        const auto it = dumpers.find(flag);
-        if (it != dumpers.end()) {
-            (it->second)(args, asProto, result);
-        } else if (!asProto) {
-            dumpAllLocked(args, result);
+        bool dumpLayers = true;
+        {
+            TimedLock lock(mStateLock, s2ns(1), __FUNCTION__);
+            if (!lock.locked()) {
+                StringAppendF(&result, "Dumping without lock after timeout: %s (%d)\n",
+                              strerror(-lock.status), lock.status);
+            }
+
+            if (const auto it = dumpers.find(flag); it != dumpers.end()) {
+                (it->second)(args, asProto, result);
+                dumpLayers = false;
+            } else if (!asProto) {
+                dumpAllLocked(args, result);
+            }
         }
 
-        if (locked) {
-            mStateLock.unlock();
-        }
-
-        if (it == dumpers.end()) {
+        if (dumpLayers) {
             const LayersProto layersProto = dumpProtoFromMainThread();
             if (asProto) {
                 result.append(layersProto.SerializeAsString());
@@ -4556,7 +4566,7 @@
 
 LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const {
     // If context is SurfaceTracing thread, mTracingLock blocks display transactions on main thread.
-    const auto display = getDefaultDisplayDeviceLocked();
+    const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
 
     LayersProto layersProto;
     for (const sp<Layer>& layer : mDrawingState.layersSortedByZ) {
@@ -5392,7 +5402,7 @@
     return NO_ERROR;
 }
 
-const sp<DisplayDevice> SurfaceFlinger::getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) {
+sp<DisplayDevice> SurfaceFlinger::getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) {
     const sp<IBinder> displayToken = getPhysicalDisplayTokenLocked(DisplayId{displayOrLayerStack});
     if (displayToken) {
         return getDisplayDeviceLocked(displayToken);
@@ -5402,7 +5412,7 @@
     return getDisplayByLayerStack(displayOrLayerStack);
 }
 
-const sp<DisplayDevice> SurfaceFlinger::getDisplayByLayerStack(uint64_t layerStack) {
+sp<DisplayDevice> SurfaceFlinger::getDisplayByLayerStack(uint64_t layerStack) {
     for (const auto& [token, display] : mDisplays) {
         if (display->getLayerStack() == layerStack) {
             return display;
@@ -5978,7 +5988,7 @@
     }
 
     auto future = schedule([=]() -> status_t {
-        const auto display = getDisplayDeviceLocked(displayToken);
+        const auto display = ON_MAIN_THREAD(getDisplayDeviceLocked(displayToken));
         if (!display) {
             ALOGE("Attempt to set desired display configs for invalid display token %p",
                   displayToken.get());
@@ -6133,7 +6143,7 @@
         return BAD_VALUE;
     }
 
-    static_cast<void>(schedule([=]() NO_THREAD_SAFETY_ANALYSIS {
+    static_cast<void>(schedule([=] {
         Mutex::Autolock lock(mStateLock);
         if (authenticateSurfaceTextureLocked(surface)) {
             sp<Layer> layer = (static_cast<MonitoredProducer*>(surface.get()))->getLayer();
@@ -6162,8 +6172,7 @@
         sp<IBinder> token;
 
         if (mFrameRateFlexibilityTokenCount == 0) {
-            // |mStateLock| not needed as we are on the main thread
-            const auto display = getDefaultDisplayDeviceLocked();
+            const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
 
             // This is a little racy, but not in a way that hurts anything. As we grab the
             // defaultConfig from the display manager policy, we could be setting a new display
@@ -6213,8 +6222,7 @@
         mFrameRateFlexibilityTokenCount--;
         ALOGD("Frame rate flexibility token released. count=%d", mFrameRateFlexibilityTokenCount);
         if (mFrameRateFlexibilityTokenCount == 0) {
-            // |mStateLock| not needed as we are on the main thread
-            const auto display = getDefaultDisplayDeviceLocked();
+            const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
             constexpr bool kOverridePolicy = true;
             status_t result = setDesiredDisplayConfigSpecsInternal(display, {}, kOverridePolicy);
             LOG_ALWAYS_FATAL_IF(result < 0, "Failed releasing frame rate flexibility token");
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 481f350..d9b40f4 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -289,12 +289,6 @@
     // The CompositionEngine encapsulates all composition related interfaces and actions.
     compositionengine::CompositionEngine& getCompositionEngine() const;
 
-    // returns the default Display
-    sp<const DisplayDevice> getDefaultDisplayDevice() {
-        Mutex::Autolock _l(mStateLock);
-        return getDefaultDisplayDeviceLocked();
-    }
-
     // Obtains a name from the texture pool, or, if the pool is empty, posts a
     // synchronous message to the main thread to obtain one on the fly
     uint32_t getNewTexture();
@@ -307,7 +301,7 @@
     void setPrimaryVsyncEnabled(bool enabled);
 
     // main thread function to enable/disable h/w composer event
-    void setPrimaryVsyncEnabledInternal(bool enabled);
+    void setPrimaryVsyncEnabledInternal(bool enabled) REQUIRES(mStateLock);
     void setVsyncEnabledInHWC(DisplayId displayId, hal::Vsync enabled);
 
     // called on the main thread by MessageQueue when an internal message
@@ -722,8 +716,8 @@
     status_t captureScreenCommon(RenderArea& renderArea, TraverseLayersFunction traverseLayers,
                                  const sp<GraphicBuffer>& buffer, bool useIdentityTransform,
                                  bool regionSampling, bool& outCapturedSecureLayers);
-    const sp<DisplayDevice> getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack);
-    const sp<DisplayDevice> getDisplayByLayerStack(uint64_t layerStack);
+    sp<DisplayDevice> getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) REQUIRES(mStateLock);
+    sp<DisplayDevice> getDisplayByLayerStack(uint64_t layerStack) REQUIRES(mStateLock);
     status_t captureScreenImplLocked(const RenderArea& renderArea,
                                      TraverseLayersFunction traverseLayers,
                                      const sp<GraphicBuffer>& buffer, bool useIdentityTransform,
@@ -751,29 +745,31 @@
     // called when starting, or restarting after system_server death
     void initializeDisplays();
 
-    // NOTE: can only be called from the main thread or with mStateLock held
-    sp<const DisplayDevice> getDisplayDeviceLocked(const wp<IBinder>& displayToken) const {
+    sp<const DisplayDevice> getDisplayDeviceLocked(const wp<IBinder>& displayToken) const
+            REQUIRES(mStateLock) {
         return const_cast<SurfaceFlinger*>(this)->getDisplayDeviceLocked(displayToken);
     }
 
-    // NOTE: can only be called from the main thread or with mStateLock held
-    sp<DisplayDevice> getDisplayDeviceLocked(const wp<IBinder>& displayToken) {
+    sp<DisplayDevice> getDisplayDeviceLocked(const wp<IBinder>& displayToken) REQUIRES(mStateLock) {
         const auto it = mDisplays.find(displayToken);
         return it == mDisplays.end() ? nullptr : it->second;
     }
 
-    sp<const DisplayDevice> getDefaultDisplayDeviceLocked() const {
+    sp<const DisplayDevice> getDefaultDisplayDeviceLocked() const REQUIRES(mStateLock) {
         return const_cast<SurfaceFlinger*>(this)->getDefaultDisplayDeviceLocked();
     }
 
-    sp<DisplayDevice> getDefaultDisplayDeviceLocked() {
+    sp<DisplayDevice> getDefaultDisplayDeviceLocked() REQUIRES(mStateLock) {
         if (const auto token = getInternalDisplayTokenLocked()) {
             return getDisplayDeviceLocked(token);
         }
         return nullptr;
     }
 
-    std::optional<DeviceProductInfo> getDeviceProductInfoLocked(DisplayId) const;
+    sp<const DisplayDevice> getDefaultDisplayDevice() EXCLUDES(mStateLock) {
+        Mutex::Autolock lock(mStateLock);
+        return getDefaultDisplayDeviceLocked();
+    }
 
     // mark a region of a layer stack dirty. this updates the dirty
     // region of all screens presenting this layer stack.
@@ -827,10 +823,11 @@
             std::shared_ptr<compositionengine::Display> compositionDisplay,
             const DisplayDeviceState& state,
             const sp<compositionengine::DisplaySurface>& displaySurface,
-            const sp<IGraphicBufferProducer>& producer);
+            const sp<IGraphicBufferProducer>& producer) REQUIRES(mStateLock);
     void processDisplayChangesLocked() REQUIRES(mStateLock);
-    void processDisplayAdded(const wp<IBinder>& displayToken, const DisplayDeviceState& state);
-    void processDisplayRemoved(const wp<IBinder>& displayToken);
+    void processDisplayAdded(const wp<IBinder>& displayToken, const DisplayDeviceState&)
+            REQUIRES(mStateLock);
+    void processDisplayRemoved(const wp<IBinder>& displayToken) REQUIRES(mStateLock);
     void processDisplayChanged(const wp<IBinder>& displayToken,
                                const DisplayDeviceState& currentState,
                                const DisplayDeviceState& drawingState) REQUIRES(mStateLock);
@@ -873,12 +870,13 @@
     /*
      * Display identification
      */
-    sp<IBinder> getPhysicalDisplayTokenLocked(DisplayId displayId) const {
+    sp<IBinder> getPhysicalDisplayTokenLocked(DisplayId displayId) const REQUIRES(mStateLock) {
         const auto it = mPhysicalDisplayTokens.find(displayId);
         return it != mPhysicalDisplayTokens.end() ? it->second : nullptr;
     }
 
-    std::optional<DisplayId> getPhysicalDisplayIdLocked(const sp<IBinder>& displayToken) const {
+    std::optional<DisplayId> getPhysicalDisplayIdLocked(const sp<IBinder>& displayToken) const
+            REQUIRES(mStateLock) {
         for (const auto& [id, token] : mPhysicalDisplayTokens) {
             if (token == displayToken) {
                 return id;
@@ -888,12 +886,12 @@
     }
 
     // TODO(b/74619554): Remove special cases for primary display.
-    sp<IBinder> getInternalDisplayTokenLocked() const {
+    sp<IBinder> getInternalDisplayTokenLocked() const REQUIRES(mStateLock) {
         const auto displayId = getInternalDisplayIdLocked();
         return displayId ? getPhysicalDisplayTokenLocked(*displayId) : nullptr;
     }
 
-    std::optional<DisplayId> getInternalDisplayIdLocked() const {
+    std::optional<DisplayId> getInternalDisplayIdLocked() const REQUIRES(mStateLock) {
         const auto hwcDisplayId = getHwComposer().getInternalHwcDisplayId();
         return hwcDisplayId ? getHwComposer().toPhysicalDisplayId(*hwcDisplayId) : std::nullopt;
     }
@@ -945,9 +943,9 @@
     void recordBufferingStats(const std::string& layerName,
                               std::vector<OccupancyTracker::Segment>&& history);
     void dumpBufferingStats(std::string& result) const;
-    void dumpDisplayIdentificationData(std::string& result) const;
+    void dumpDisplayIdentificationData(std::string& result) const REQUIRES(mStateLock);
     void dumpRawDisplayIdentificationData(const DumpArgs&, std::string& result) const;
-    void dumpWideColorInfo(std::string& result) const;
+    void dumpWideColorInfo(std::string& result) const REQUIRES(mStateLock);
     LayersProto dumpDrawingStateProto(uint32_t traceFlags) const;
     void dumpOffscreenLayersProto(LayersProto& layersProto,
                                   uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const;
@@ -974,7 +972,7 @@
     /* ------------------------------------------------------------------------
      * VrFlinger
      */
-    void resetDisplayState();
+    void resetDisplayState() REQUIRES(mStateLock);
 
     // Check to see if we should handoff to vr flinger.
     void updateVrFlinger();
@@ -1057,16 +1055,14 @@
         hal::HWDisplayId hwcDisplayId;
         hal::Connection connection = hal::Connection::INVALID;
     };
-    // protected by mStateLock
-    std::vector<HotplugEvent> mPendingHotplugEvents;
+    std::vector<HotplugEvent> mPendingHotplugEvents GUARDED_BY(mStateLock);
 
     // this may only be written from the main thread with mStateLock held
     // it may be read from other threads with mStateLock held
-    std::map<wp<IBinder>, sp<DisplayDevice>> mDisplays;
-    std::unordered_map<DisplayId, sp<IBinder>> mPhysicalDisplayTokens;
+    std::map<wp<IBinder>, sp<DisplayDevice>> mDisplays GUARDED_BY(mStateLock);
+    std::unordered_map<DisplayId, sp<IBinder>> mPhysicalDisplayTokens GUARDED_BY(mStateLock);
 
-    // protected by mStateLock
-    std::unordered_map<BBinder*, wp<Layer>> mLayersByLocalBinderToken;
+    std::unordered_map<BBinder*, wp<Layer>> mLayersByLocalBinderToken GUARDED_BY(mStateLock);
 
     // don't use a lock for these, we don't care
     int mDebugRegion = 0;
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 82e68dd..4652da0 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -289,14 +289,14 @@
         return mFlinger->destroyDisplay(displayToken);
     }
 
-    auto resetDisplayState() { return mFlinger->resetDisplayState(); }
+    auto resetDisplayState() NO_THREAD_SAFETY_ANALYSIS { return mFlinger->resetDisplayState(); }
 
     auto setupNewDisplayDeviceInternal(
             const wp<IBinder>& displayToken,
             std::shared_ptr<compositionengine::Display> compositionDisplay,
             const DisplayDeviceState& state,
             const sp<compositionengine::DisplaySurface>& dispSurface,
-            const sp<IGraphicBufferProducer>& producer) {
+            const sp<IGraphicBufferProducer>& producer) NO_THREAD_SAFETY_ANALYSIS {
         return mFlinger->setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state,
                                                        dispSurface, producer);
     }