Merge "InputDispatcher: Remove gesture monitor implementation"
diff --git a/cmds/dumpsys/tests/dumpsys_test.cpp b/cmds/dumpsys/tests/dumpsys_test.cpp
index 677d6c7..49c1318 100644
--- a/cmds/dumpsys/tests/dumpsys_test.cpp
+++ b/cmds/dumpsys/tests/dumpsys_test.cpp
@@ -61,6 +61,10 @@
     MOCK_METHOD1(getDeclaredInstances, Vector<String16>(const String16&));
     MOCK_METHOD1(updatableViaApex, std::optional<String16>(const String16&));
     MOCK_METHOD1(getConnectionInfo, std::optional<ConnectionInfo>(const String16&));
+    MOCK_METHOD2(registerForNotifications, status_t(const String16&,
+                                             const sp<LocalRegistrationCallback>&));
+    MOCK_METHOD2(unregisterForNotifications, status_t(const String16&,
+                                             const sp<LocalRegistrationCallback>&));
   protected:
     MOCK_METHOD0(onAsBinder, IBinder*());
 };
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index 31dee23..5003151 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -119,6 +119,12 @@
 }
 
 prebuilt_etc {
+    name: "android.hardware.sensor.dynamic.head_tracker.prebuilt.xml",
+    src: "android.hardware.sensor.dynamic.head_tracker.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
     name: "android.hardware.sensor.gyroscope.prebuilt.xml",
     src: "android.hardware.sensor.gyroscope.xml",
     defaults: ["frameworks_native_data_etc_defaults"],
diff --git a/data/etc/android.hardware.sensor.accelerometer_limited_axes.xml b/data/etc/android.hardware.sensor.accelerometer_limited_axes.xml
new file mode 100644
index 0000000..6a43d5d
--- /dev/null
+++ b/data/etc/android.hardware.sensor.accelerometer_limited_axes.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Feature for devices with a limited axes accelerometer sensor. -->
+<permissions>
+    <feature name="android.hardware.sensor.accelerometer_limited_axes" />
+</permissions>
diff --git a/data/etc/android.hardware.sensor.accelerometer_limited_axes_uncalibrated.xml b/data/etc/android.hardware.sensor.accelerometer_limited_axes_uncalibrated.xml
new file mode 100644
index 0000000..4c6755c
--- /dev/null
+++ b/data/etc/android.hardware.sensor.accelerometer_limited_axes_uncalibrated.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Feature for devices with an uncalibrated limited axes accelerometer sensor. -->
+<permissions>
+    <feature name="android.hardware.sensor.accelerometer_limited_axes_uncalibrated" />
+</permissions>
diff --git a/data/etc/android.hardware.sensor.dynamic.head_tracker.xml b/data/etc/android.hardware.sensor.dynamic.head_tracker.xml
new file mode 100644
index 0000000..ece58c9
--- /dev/null
+++ b/data/etc/android.hardware.sensor.dynamic.head_tracker.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Feature for devices with a head tracker sensor. -->
+<permissions>
+    <feature name="android.hardware.sensor.dynamic.head_tracker" />
+</permissions>
\ No newline at end of file
diff --git a/data/etc/android.hardware.sensor.gyroscope_limited_axes.xml b/data/etc/android.hardware.sensor.gyroscope_limited_axes.xml
new file mode 100644
index 0000000..45c6547
--- /dev/null
+++ b/data/etc/android.hardware.sensor.gyroscope_limited_axes.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Feature for devices with a limited axes gyroscope. -->
+<permissions>
+    <feature name="android.hardware.sensor.gyroscope_limited_axes" />
+</permissions>
diff --git a/data/etc/android.hardware.sensor.gyroscope_limited_axes_uncalibrated.xml b/data/etc/android.hardware.sensor.gyroscope_limited_axes_uncalibrated.xml
new file mode 100644
index 0000000..2ca8364
--- /dev/null
+++ b/data/etc/android.hardware.sensor.gyroscope_limited_axes_uncalibrated.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Feature for devices with an uncalibrated limited axes gyroscope. -->
+<permissions>
+    <feature name="android.hardware.sensor.gyroscope_limited_axes_uncalibrated" />
+</permissions>
diff --git a/include/android/sensor.h b/include/android/sensor.h
index 45e8afc..7e86d3f 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -263,6 +263,44 @@
      * Measures the orientation and rotational velocity of a user's head.
      */
     ASENSOR_TYPE_HEAD_TRACKER = 37,
+    /**
+     * {@link ASENSOR_TYPE_ACCELEROMETER_LIMITED_AXES}
+     * reporting-mode: continuous
+     *
+     * The first three values are in SI units (m/s^2) and measure the acceleration of the device
+     * minus the force of gravity. The last three values indicate which acceleration axes are
+     * supported. A value of 1.0 means supported and a value of 0 means not supported.
+     */
+    ASENSOR_TYPE_ACCELEROMETER_LIMITED_AXES = 38,
+    /**
+     * {@link ASENSOR_TYPE_GYROSCOPE_LIMITED_AXES}
+     * reporting-mode: continuous
+     *
+     * The first three values are in radians/second and measure the rate of rotation around the X,
+     * Y and Z axis. The last three values indicate which rotation axes are supported. A value of
+     * 1.0 means supported and a value of 0 means not supported.
+     */
+    ASENSOR_TYPE_GYROSCOPE_LIMITED_AXES = 39,
+    /**
+     * {@link ASENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED}
+     * reporting-mode: continuous
+     *
+     * The first three values are in SI units (m/s^2) and measure the acceleration of the device
+     * minus the force of gravity. The middle three values represent the estimated bias for each
+     * axis. The last three values indicate which acceleration axes are supported. A value of 1.0
+     * means supported and a value of 0 means not supported.
+     */
+    ASENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED = 40,
+    /**
+     * {@link ASENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED}
+     * reporting-mode: continuous
+     *
+     * The first three values are in radians/second and measure the rate of rotation around the X,
+     * Y and Z axis. The middle three values represent the estimated drift around each axis in
+     * rad/s. The last three values indicate which rotation axes are supported. A value of 1.0 means
+     * supported and a value of 0 means not supported.
+     */
+    ASENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED = 41,
 };
 
 /**
@@ -479,6 +517,52 @@
     int32_t discontinuity_count;
 } AHeadTrackerEvent;
 
+typedef struct ALimitedAxesImuEvent {
+    union {
+        float calib[3];
+        struct {
+            float x;
+            float y;
+            float z;
+        };
+    };
+    union {
+        float supported[3];
+        struct {
+            float x_supported;
+            float y_supported;
+            float z_supported;
+        };
+    };
+} ALimitedAxesImuEvent;
+
+typedef struct ALimitedAxesImuUncalibratedEvent {
+    union {
+        float uncalib[3];
+        struct {
+            float x_uncalib;
+            float y_uncalib;
+            float z_uncalib;
+        };
+    };
+    union {
+        float bias[3];
+        struct {
+            float x_bias;
+            float y_bias;
+            float z_bias;
+        };
+    };
+    union {
+        float supported[3];
+        struct {
+            float x_supported;
+            float y_supported;
+            float z_supported;
+        };
+    };
+} ALimitedAxesImuUncalibratedEvent;
+
 /**
  * Information that describes a sensor event, refer to
  * <a href="/reference/android/hardware/SensorEvent">SensorEvent</a> for additional
@@ -516,6 +600,8 @@
             ADynamicSensorEvent dynamic_sensor_meta;
             AAdditionalInfoEvent additional_info;
             AHeadTrackerEvent head_tracker;
+            ALimitedAxesImuEvent limited_axes_imu;
+            ALimitedAxesImuUncalibratedEvent limited_axes_imu_uncalibrated;
         };
         union {
             uint64_t        data[8];
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index ec9d554..0970ca5 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -54,6 +54,8 @@
 constexpr const bool kEnableRpcDevServers = false;
 #endif
 
+// Log any reply transactions for which the data exceeds this size
+#define LOG_REPLIES_OVER_SIZE (300 * 1024)
 // ---------------------------------------------------------------------------
 
 IBinder::IBinder()
@@ -296,6 +298,10 @@
     // In case this is being transacted on in the same process.
     if (reply != nullptr) {
         reply->setDataPosition(0);
+        if (reply->dataSize() > LOG_REPLIES_OVER_SIZE) {
+            ALOGW("Large reply transaction of %zu bytes, interface descriptor %s, code %d",
+                  reply->dataSize(), String8(getInterfaceDescriptor()).c_str(), code);
+        }
     }
 
     return err;
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 06542f0..056ef0a 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -48,6 +48,9 @@
 // Another arbitrary value a binder count needs to drop below before another callback will be called
 uint32_t BpBinder::sBinderProxyCountLowWatermark = 2000;
 
+// Log any transactions for which the data exceeds this size
+#define LOG_TRANSACTIONS_OVER_SIZE (300 * 1024)
+
 enum {
     LIMIT_REACHED_MASK = 0x80000000,        // A flag denoting that the limit has been reached
     COUNTING_VALUE_MASK = 0x7FFFFFFF,       // A mask of the remaining bits for the count value
@@ -302,6 +305,14 @@
         } else {
             status = IPCThreadState::self()->transact(binderHandle(), code, data, reply, flags);
         }
+        if (data.dataSize() > LOG_TRANSACTIONS_OVER_SIZE) {
+            Mutex::Autolock _l(mLock);
+            ALOGW("Large outgoing transaction of %zu bytes, interface descriptor %s, code %d",
+                  data.dataSize(),
+                  mDescriptorCache.size() ? String8(mDescriptorCache).c_str()
+                                          : "<uncached descriptor>",
+                  code);
+        }
 
         if (status == DEAD_OBJECT) mAlive = 0;
 
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 81e61da..ea2f8d2 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -43,6 +43,8 @@
 
 namespace android {
 
+using AidlRegistrationCallback = IServiceManager::LocalRegistrationCallback;
+
 using AidlServiceManager = android::os::IServiceManager;
 using android::binder::Status;
 
@@ -79,7 +81,24 @@
     Vector<String16> getDeclaredInstances(const String16& interface) override;
     std::optional<String16> updatableViaApex(const String16& name) override;
     std::optional<IServiceManager::ConnectionInfo> getConnectionInfo(const String16& name) override;
+    class RegistrationWaiter : public android::os::BnServiceCallback {
+    public:
+        explicit RegistrationWaiter(const sp<AidlRegistrationCallback>& callback)
+              : mImpl(callback) {}
+        Status onRegistration(const std::string& name, const sp<IBinder>& binder) override {
+            mImpl->onServiceRegistration(String16(name.c_str()), binder);
+            return Status::ok();
+        }
 
+    private:
+        sp<AidlRegistrationCallback> mImpl;
+    };
+
+    status_t registerForNotifications(const String16& service,
+                                      const sp<AidlRegistrationCallback>& cb) override;
+
+    status_t unregisterForNotifications(const String16& service,
+                                        const sp<AidlRegistrationCallback>& cb) override;
     // for legacy ABI
     const String16& getInterfaceDescriptor() const override {
         return mTheRealServiceManager->getInterfaceDescriptor();
@@ -90,6 +109,17 @@
 
 protected:
     sp<AidlServiceManager> mTheRealServiceManager;
+    // AidlRegistrationCallback -> services that its been registered for
+    // notifications.
+    using LocalRegistrationAndWaiter =
+            std::pair<sp<LocalRegistrationCallback>, sp<RegistrationWaiter>>;
+    using ServiceCallbackMap = std::map<std::string, std::vector<LocalRegistrationAndWaiter>>;
+    ServiceCallbackMap mNameToRegistrationCallback;
+    std::mutex mNameToRegistrationLock;
+
+    void removeRegistrationCallbackLocked(const sp<AidlRegistrationCallback>& cb,
+                                          ServiceCallbackMap::iterator* it,
+                                          sp<RegistrationWaiter>* waiter);
 
     // Directly get the service in a way that, for lazy services, requests the service to be started
     // if it is not currently started. This way, calls directly to ServiceManagerShim::getService
@@ -442,6 +472,77 @@
             : std::nullopt;
 }
 
+status_t ServiceManagerShim::registerForNotifications(const String16& name,
+                                                      const sp<AidlRegistrationCallback>& cb) {
+    if (cb == nullptr) {
+        ALOGE("%s: null cb passed", __FUNCTION__);
+        return BAD_VALUE;
+    }
+    std::string nameStr = String8(name).c_str();
+    sp<RegistrationWaiter> registrationWaiter = sp<RegistrationWaiter>::make(cb);
+    std::lock_guard<std::mutex> lock(mNameToRegistrationLock);
+    if (Status status =
+                mTheRealServiceManager->registerForNotifications(nameStr, registrationWaiter);
+        !status.isOk()) {
+        ALOGW("Failed to registerForNotifications for %s: %s", nameStr.c_str(),
+              status.toString8().c_str());
+        return UNKNOWN_ERROR;
+    }
+    mNameToRegistrationCallback[nameStr].push_back(std::make_pair(cb, registrationWaiter));
+    return OK;
+}
+
+void ServiceManagerShim::removeRegistrationCallbackLocked(const sp<AidlRegistrationCallback>& cb,
+                                                          ServiceCallbackMap::iterator* it,
+                                                          sp<RegistrationWaiter>* waiter) {
+    std::vector<LocalRegistrationAndWaiter>& localRegistrationAndWaiters = (*it)->second;
+    for (auto lit = localRegistrationAndWaiters.begin();
+         lit != localRegistrationAndWaiters.end();) {
+        if (lit->first == cb) {
+            if (waiter) {
+                *waiter = lit->second;
+            }
+            lit = localRegistrationAndWaiters.erase(lit);
+        } else {
+            ++lit;
+        }
+    }
+
+    if (localRegistrationAndWaiters.empty()) {
+        mNameToRegistrationCallback.erase(*it);
+    }
+}
+
+status_t ServiceManagerShim::unregisterForNotifications(const String16& name,
+                                                        const sp<AidlRegistrationCallback>& cb) {
+    if (cb == nullptr) {
+        ALOGE("%s: null cb passed", __FUNCTION__);
+        return BAD_VALUE;
+    }
+    std::string nameStr = String8(name).c_str();
+    std::lock_guard<std::mutex> lock(mNameToRegistrationLock);
+    auto it = mNameToRegistrationCallback.find(nameStr);
+    sp<RegistrationWaiter> registrationWaiter;
+    if (it != mNameToRegistrationCallback.end()) {
+        removeRegistrationCallbackLocked(cb, &it, &registrationWaiter);
+    } else {
+        ALOGE("%s no callback registered for notifications on %s", __FUNCTION__, nameStr.c_str());
+        return BAD_VALUE;
+    }
+    if (registrationWaiter == nullptr) {
+        ALOGE("%s Callback passed wasn't used to register for notifications", __FUNCTION__);
+        return BAD_VALUE;
+    }
+    if (Status status = mTheRealServiceManager->unregisterForNotifications(String8(name).c_str(),
+                                                                           registrationWaiter);
+        !status.isOk()) {
+        ALOGW("Failed to get service manager to unregisterForNotifications for %s: %s",
+              String8(name).c_str(), status.toString8().c_str());
+        return UNKNOWN_ERROR;
+    }
+    return OK;
+}
+
 #ifndef __ANDROID__
 // ServiceManagerShim for host. Implements the old libbinder android::IServiceManager API.
 // The internal implementation of the AIDL interface android::os::IServiceManager calls into
diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h
index 240e3c2..ea40db8 100644
--- a/libs/binder/include/binder/IServiceManager.h
+++ b/libs/binder/include/binder/IServiceManager.h
@@ -115,6 +115,17 @@
         unsigned int port;
     };
     virtual std::optional<ConnectionInfo> getConnectionInfo(const String16& name) = 0;
+
+    struct LocalRegistrationCallback : public virtual RefBase {
+        virtual void onServiceRegistration(const String16& instance, const sp<IBinder>& binder) = 0;
+        virtual ~LocalRegistrationCallback() {}
+    };
+
+    virtual status_t registerForNotifications(const String16& name,
+                                              const sp<LocalRegistrationCallback>& callback) = 0;
+
+    virtual status_t unregisterForNotifications(const String16& name,
+                                                const sp<LocalRegistrationCallback>& callback) = 0;
 };
 
 sp<IServiceManager> defaultServiceManager();
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 63a4b2c..700940a 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -1220,6 +1220,19 @@
     EXPECT_THAT(server->transact(BINDER_LIB_TEST_CAN_GET_SID, data, nullptr), StatusEq(OK));
 }
 
+TEST(ServiceNotifications, Unregister) {
+    auto sm = defaultServiceManager();
+    using LocalRegistrationCallback = IServiceManager::LocalRegistrationCallback;
+    class LocalRegistrationCallbackImpl : public virtual LocalRegistrationCallback {
+        void onServiceRegistration(const String16 &, const sp<IBinder> &) override {}
+        virtual ~LocalRegistrationCallbackImpl() {}
+    };
+    sp<LocalRegistrationCallback> cb = sp<LocalRegistrationCallbackImpl>::make();
+
+    EXPECT_EQ(sm->registerForNotifications(String16("RogerRafa"), cb), OK);
+    EXPECT_EQ(sm->unregisterForNotifications(String16("RogerRafa"), cb), OK);
+}
+
 class BinderLibRpcTestBase : public BinderLibTest {
 public:
     void SetUp() override {
diff --git a/libs/fakeservicemanager/ServiceManager.cpp b/libs/fakeservicemanager/ServiceManager.cpp
index 9f0754b..61e4a98 100644
--- a/libs/fakeservicemanager/ServiceManager.cpp
+++ b/libs/fakeservicemanager/ServiceManager.cpp
@@ -84,4 +84,14 @@
     return std::nullopt;
 }
 
+status_t ServiceManager::registerForNotifications(const String16&,
+                                                  const sp<LocalRegistrationCallback>&) {
+    return INVALID_OPERATION;
+}
+
+status_t ServiceManager::unregisterForNotifications(const String16&,
+                                                const sp<LocalRegistrationCallback>&) {
+    return INVALID_OPERATION;
+}
+
 }  // namespace android
diff --git a/libs/fakeservicemanager/ServiceManager.h b/libs/fakeservicemanager/ServiceManager.h
index b1496ba..6d6e008 100644
--- a/libs/fakeservicemanager/ServiceManager.h
+++ b/libs/fakeservicemanager/ServiceManager.h
@@ -53,6 +53,11 @@
 
     std::optional<IServiceManager::ConnectionInfo> getConnectionInfo(const String16& name) override;
 
+    status_t registerForNotifications(const String16& name,
+                                      const sp<LocalRegistrationCallback>& callback) override;
+
+    status_t unregisterForNotifications(const String16& name,
+                                        const sp<LocalRegistrationCallback>& callback) override;
 private:
     std::map<String16, sp<IBinder>> mNameToService;
 };
diff --git a/libs/nativedisplay/surfacetexture/EGLConsumer.cpp b/libs/nativedisplay/surfacetexture/EGLConsumer.cpp
index 6882ea3..0128859 100644
--- a/libs/nativedisplay/surfacetexture/EGLConsumer.cpp
+++ b/libs/nativedisplay/surfacetexture/EGLConsumer.cpp
@@ -593,6 +593,10 @@
 }
 
 void EGLConsumer::onFreeBufferLocked(int slotIndex) {
+    if (mEglSlots[slotIndex].mEglImage != nullptr &&
+        mEglSlots[slotIndex].mEglImage == mCurrentTextureImage) {
+        mCurrentTextureImage.clear();
+    }
     mEglSlots[slotIndex].mEglImage.clear();
 }
 
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index 612a0aa..e197150 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -49,6 +49,50 @@
 namespace android {
 namespace renderengine {
 
+namespace {
+
+double EOTF_PQ(double channel) {
+    float m1 = (2610.0 / 4096.0) / 4.0;
+    float m2 = (2523.0 / 4096.0) * 128.0;
+    float c1 = (3424.0 / 4096.0);
+    float c2 = (2413.0 / 4096.0) * 32.0;
+    float c3 = (2392.0 / 4096.0) * 32.0;
+
+    float tmp = std::pow(std::clamp(channel, 0.0, 1.0), 1.0 / m2);
+    tmp = std::fmax(tmp - c1, 0.0) / (c2 - c3 * tmp);
+    return std::pow(tmp, 1.0 / m1);
+}
+
+vec3 EOTF_PQ(vec3 color) {
+    return vec3(EOTF_PQ(color.r), EOTF_PQ(color.g), EOTF_PQ(color.b));
+}
+
+double EOTF_HLG(double channel) {
+    const float a = 0.17883277;
+    const float b = 0.28466892;
+    const float c = 0.55991073;
+    return channel <= 0.5 ? channel * channel / 3.0 : (exp((channel - c) / a) + b) / 12.0;
+}
+
+vec3 EOTF_HLG(vec3 color) {
+    return vec3(EOTF_HLG(color.r), EOTF_HLG(color.g), EOTF_HLG(color.b));
+}
+
+double OETF_sRGB(double channel) {
+    return channel <= 0.0031308 ? channel * 12.92 : (pow(channel, 1.0 / 2.4) * 1.055) - 0.055;
+}
+
+int sign(float in) {
+    return in >= 0.0 ? 1 : -1;
+}
+
+vec3 OETF_sRGB(vec3 linear) {
+    return vec3(sign(linear.r) * OETF_sRGB(linear.r), sign(linear.g) * OETF_sRGB(linear.g),
+                sign(linear.b) * OETF_sRGB(linear.b));
+}
+
+} // namespace
+
 class RenderEngineFactory {
 public:
     virtual ~RenderEngineFactory() = default;
@@ -598,6 +642,12 @@
                                  const renderengine::ShadowSettings& shadow,
                                  const ubyte4& backgroundColor);
 
+    // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
+    // implementations are identical Also implicitly checks that the injected tonemap shader
+    // compiles
+    void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
+                 std::function<vec3(vec3, float)> scaleOotf);
+
     void initializeRenderEngine();
 
     std::unique_ptr<renderengine::RenderEngine> mRE;
@@ -1418,6 +1468,119 @@
     invokeDraw(settings, layers);
 }
 
+void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
+                               std::function<vec3(vec3, float)> scaleOotf) {
+    constexpr int32_t kGreyLevels = 256;
+
+    const auto rect = Rect(0, 0, kGreyLevels, 1);
+
+    constexpr float kMaxLuminance = 750.f;
+    constexpr float kCurrentLuminanceNits = 500.f;
+    const renderengine::DisplaySettings display{
+            .physicalDisplay = rect,
+            .clip = rect,
+            .maxLuminance = kMaxLuminance,
+            .currentLuminanceNits = kCurrentLuminanceNits,
+            .outputDataspace = ui::Dataspace::DISPLAY_P3,
+    };
+
+    auto buf = std::make_shared<
+            renderengine::impl::
+                    ExternalTexture>(new GraphicBuffer(kGreyLevels, 1, HAL_PIXEL_FORMAT_RGBA_8888,
+                                                       1,
+                                                       GRALLOC_USAGE_SW_READ_OFTEN |
+                                                               GRALLOC_USAGE_SW_WRITE_OFTEN |
+                                                               GRALLOC_USAGE_HW_RENDER |
+                                                               GRALLOC_USAGE_HW_TEXTURE,
+                                                       "input"),
+                                     *mRE,
+                                     renderengine::impl::ExternalTexture::Usage::READABLE |
+                                             renderengine::impl::ExternalTexture::Usage::WRITEABLE);
+    ASSERT_EQ(0, buf->getBuffer()->initCheck());
+    {
+        uint8_t* pixels;
+        buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+                               reinterpret_cast<void**>(&pixels));
+
+        uint8_t color = 0;
+        for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
+            uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
+            for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
+                dest[0] = color;
+                dest[1] = color;
+                dest[2] = color;
+                dest[3] = 255;
+                color++;
+                dest += 4;
+            }
+        }
+        buf->getBuffer()->unlock();
+    }
+
+    mBuffer = std::make_shared<
+            renderengine::impl::
+                    ExternalTexture>(new GraphicBuffer(kGreyLevels, 1, HAL_PIXEL_FORMAT_RGBA_8888,
+                                                       1,
+                                                       GRALLOC_USAGE_SW_READ_OFTEN |
+                                                               GRALLOC_USAGE_SW_WRITE_OFTEN |
+                                                               GRALLOC_USAGE_HW_RENDER |
+                                                               GRALLOC_USAGE_HW_TEXTURE,
+                                                       "output"),
+                                     *mRE,
+                                     renderengine::impl::ExternalTexture::Usage::READABLE |
+                                             renderengine::impl::ExternalTexture::Usage::WRITEABLE);
+    ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
+
+    const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(),
+                                            .source =
+                                                    renderengine::PixelSource{
+                                                            .buffer =
+                                                                    renderengine::Buffer{
+                                                                            .buffer =
+                                                                                    std::move(buf),
+                                                                            .usePremultipliedAlpha =
+                                                                                    true,
+                                                                    },
+                                                    },
+                                            .alpha = 1.0f,
+                                            .sourceDataspace = sourceDataspace};
+
+    std::vector<renderengine::LayerSettings> layers{layer};
+    invokeDraw(display, layers);
+
+    ColorSpace displayP3 = ColorSpace::DisplayP3();
+    ColorSpace bt2020 = ColorSpace::BT2020();
+
+    tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
+
+    auto generator = [=](Point location) {
+        const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
+        const vec3 rgb = vec3(normColor, normColor, normColor);
+
+        const vec3 linearRGB = eotf(rgb);
+
+        const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB;
+
+        const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits);
+        const double gain =
+                tonemap::getToneMapper()
+                        ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
+                                                                Dataspace>(sourceDataspace),
+                                            static_cast<aidl::android::hardware::graphics::common::
+                                                                Dataspace>(
+                                                    ui::Dataspace::DISPLAY_P3),
+                                            scaleOotf(linearRGB, kCurrentLuminanceNits), scaledXYZ,
+                                            metadata);
+        const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance;
+
+        const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255;
+        return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
+                      static_cast<uint8_t>(targetRGB.b), 255);
+    };
+
+    expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
+}
+
 INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
                          testing::Values(std::make_shared<GLESRenderEngineFactory>(),
                                          std::make_shared<GLESCMRenderEngineFactory>(),
@@ -2412,155 +2575,47 @@
     }
 }
 
-double EOTF_PQ(double channel) {
-    float m1 = (2610.0 / 4096.0) / 4.0;
-    float m2 = (2523.0 / 4096.0) * 128.0;
-    float c1 = (3424.0 / 4096.0);
-    float c2 = (2413.0 / 4096.0) * 32.0;
-    float c3 = (2392.0 / 4096.0) * 32.0;
-
-    float tmp = std::pow(std::clamp(channel, 0.0, 1.0), 1.0 / m2);
-    tmp = std::fmax(tmp - c1, 0.0) / (c2 - c3 * tmp);
-    return std::pow(tmp, 1.0 / m1);
-}
-
-vec3 EOTF_PQ(vec3 color) {
-    return vec3(EOTF_PQ(color.r), EOTF_PQ(color.g), EOTF_PQ(color.b));
-}
-
-double OETF_sRGB(double channel) {
-    return channel <= 0.0031308 ? channel * 12.92 : (pow(channel, 1.0 / 2.4) * 1.055) - 0.055;
-}
-
-int sign(float in) {
-    return in >= 0.0 ? 1 : -1;
-}
-
-vec3 OETF_sRGB(vec3 linear) {
-    return vec3(sign(linear.r) * OETF_sRGB(linear.r), sign(linear.g) * OETF_sRGB(linear.g),
-                sign(linear.b) * OETF_sRGB(linear.b));
-}
-
 TEST_P(RenderEngineTest, test_tonemapPQMatches) {
     if (!GetParam()->useColorManagement()) {
-        return;
+        GTEST_SKIP();
     }
 
     if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
-        return;
+        GTEST_SKIP();
     }
 
     initializeRenderEngine();
 
-    constexpr int32_t kGreyLevels = 256;
+    tonemap(
+            static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
+                                       HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
+            [](vec3 color) { return EOTF_PQ(color); },
+            [](vec3 color, float) {
+                static constexpr float kMaxPQLuminance = 10000.f;
+                return color * kMaxPQLuminance;
+            });
+}
 
-    const auto rect = Rect(0, 0, kGreyLevels, 1);
-    const renderengine::DisplaySettings display{
-            .physicalDisplay = rect,
-            .clip = rect,
-            .maxLuminance = 750.0f,
-            .outputDataspace = ui::Dataspace::DISPLAY_P3,
-    };
-
-    auto buf = std::make_shared<
-            renderengine::impl::
-                    ExternalTexture>(new GraphicBuffer(kGreyLevels, 1, HAL_PIXEL_FORMAT_RGBA_8888,
-                                                       1,
-                                                       GRALLOC_USAGE_SW_READ_OFTEN |
-                                                               GRALLOC_USAGE_SW_WRITE_OFTEN |
-                                                               GRALLOC_USAGE_HW_RENDER |
-                                                               GRALLOC_USAGE_HW_TEXTURE,
-                                                       "input"),
-                                     *mRE,
-                                     renderengine::impl::ExternalTexture::Usage::READABLE |
-                                             renderengine::impl::ExternalTexture::Usage::WRITEABLE);
-    ASSERT_EQ(0, buf->getBuffer()->initCheck());
-
-    {
-        uint8_t* pixels;
-        buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
-                               reinterpret_cast<void**>(&pixels));
-
-        uint8_t color = 0;
-        for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
-            uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
-            for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
-                dest[0] = color;
-                dest[1] = color;
-                dest[2] = color;
-                dest[3] = 255;
-                color++;
-                dest += 4;
-            }
-        }
-        buf->getBuffer()->unlock();
+TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
+    if (!GetParam()->useColorManagement()) {
+        GTEST_SKIP();
     }
 
-    mBuffer = std::make_shared<
-            renderengine::impl::
-                    ExternalTexture>(new GraphicBuffer(kGreyLevels, 1, HAL_PIXEL_FORMAT_RGBA_8888,
-                                                       1,
-                                                       GRALLOC_USAGE_SW_READ_OFTEN |
-                                                               GRALLOC_USAGE_SW_WRITE_OFTEN |
-                                                               GRALLOC_USAGE_HW_RENDER |
-                                                               GRALLOC_USAGE_HW_TEXTURE,
-                                                       "output"),
-                                     *mRE,
-                                     renderengine::impl::ExternalTexture::Usage::READABLE |
-                                             renderengine::impl::ExternalTexture::Usage::WRITEABLE);
-    ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
+    if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
+        GTEST_SKIP();
+    }
 
-    const renderengine::LayerSettings layer{
-            .geometry.boundaries = rect.toFloatRect(),
-            .source =
-                    renderengine::PixelSource{
-                            .buffer =
-                                    renderengine::Buffer{
-                                            .buffer = std::move(buf),
-                                            .usePremultipliedAlpha = true,
-                                    },
-                    },
-            .alpha = 1.0f,
-            .sourceDataspace = static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
-                                                          HAL_DATASPACE_TRANSFER_ST2084 |
-                                                          HAL_DATASPACE_RANGE_FULL),
-    };
+    initializeRenderEngine();
 
-    std::vector<renderengine::LayerSettings> layers{layer};
-    invokeDraw(display, layers);
-
-    ColorSpace displayP3 = ColorSpace::DisplayP3();
-    ColorSpace bt2020 = ColorSpace::BT2020();
-
-    tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
-
-    auto generator = [=](Point location) {
-        const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
-        const vec3 rgb = vec3(normColor, normColor, normColor);
-
-        const vec3 linearRGB = EOTF_PQ(rgb);
-
-        static constexpr float kMaxPQLuminance = 10000.f;
-        const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB * kMaxPQLuminance;
-        const double gain =
-                tonemap::getToneMapper()
-                        ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
-                                                                Dataspace>(
-                                                    HAL_DATASPACE_STANDARD_BT2020 |
-                                                    HAL_DATASPACE_TRANSFER_ST2084 |
-                                                    HAL_DATASPACE_RANGE_FULL),
-                                            static_cast<aidl::android::hardware::graphics::common::
-                                                                Dataspace>(
-                                                    ui::Dataspace::DISPLAY_P3),
-                                            linearRGB * 10000.0, xyz, metadata);
-        const vec3 scaledXYZ = xyz * gain / metadata.displayMaxLuminance;
-
-        const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * scaledXYZ) * 255;
-        return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
-                      static_cast<uint8_t>(targetRGB.b), 255);
-    };
-
-    expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
+    tonemap(
+            static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
+                                       HAL_DATASPACE_RANGE_FULL),
+            [](vec3 color) { return EOTF_HLG(color); },
+            [](vec3 color, float currentLuminaceNits) {
+                static constexpr float kMaxHLGLuminance = 1000.f;
+                static const float kHLGGamma = 1.2 + 0.42 * std::log10(currentLuminaceNits / 1000);
+                return color * kMaxHLGLuminance * std::pow(color.y, kHLGGamma - 1);
+            });
 }
 
 TEST_P(RenderEngineTest, r8_behaves_as_mask) {
diff --git a/libs/sensor/Sensor.cpp b/libs/sensor/Sensor.cpp
index da88e85..5b4631a 100644
--- a/libs/sensor/Sensor.cpp
+++ b/libs/sensor/Sensor.cpp
@@ -280,6 +280,22 @@
         mStringType = SENSOR_STRING_TYPE_HEAD_TRACKER;
         mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
         break;
+    case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES:
+        mStringType = SENSOR_STRING_TYPE_ACCELEROMETER_LIMITED_AXES;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
+    case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES:
+        mStringType = SENSOR_STRING_TYPE_GYROSCOPE_LIMITED_AXES;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
+    case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED:
+        mStringType = SENSOR_STRING_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
+    case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED:
+        mStringType = SENSOR_STRING_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
     default:
         // Only pipe the stringType, requiredPermission and flags for custom sensors.
         if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor.stringType) {
diff --git a/libs/shaders/shaders.cpp b/libs/shaders/shaders.cpp
index 4d88d5d..03da3ec 100644
--- a/libs/shaders/shaders.cpp
+++ b/libs/shaders/shaders.cpp
@@ -18,6 +18,7 @@
 
 #include <tonemap/tonemap.h>
 
+#include <cmath>
 #include <optional>
 
 #include <math/mat4.h>
@@ -26,12 +27,13 @@
 
 namespace android::shaders {
 
-static aidl::android::hardware::graphics::common::Dataspace toAidlDataspace(
-        ui::Dataspace dataspace) {
+namespace {
+
+aidl::android::hardware::graphics::common::Dataspace toAidlDataspace(ui::Dataspace dataspace) {
     return static_cast<aidl::android::hardware::graphics::common::Dataspace>(dataspace);
 }
 
-static void generateEOTF(ui::Dataspace dataspace, std::string& shader) {
+void generateEOTF(ui::Dataspace dataspace, std::string& shader) {
     switch (dataspace & HAL_DATASPACE_TRANSFER_MASK) {
         case HAL_DATASPACE_TRANSFER_ST2084:
             shader.append(R"(
@@ -156,7 +158,7 @@
     }
 }
 
-static void generateXYZTransforms(std::string& shader) {
+void generateXYZTransforms(std::string& shader) {
     shader.append(R"(
         uniform float4x4 in_rgbToXyz;
         uniform float4x4 in_xyzToRgb;
@@ -171,8 +173,8 @@
 }
 
 // Conversion from relative light to absolute light (maps from [0, 1] to [0, maxNits])
-static void generateLuminanceScalesForOOTF(ui::Dataspace inputDataspace,
-                                           ui::Dataspace outputDataspace, std::string& shader) {
+void generateLuminanceScalesForOOTF(ui::Dataspace inputDataspace, ui::Dataspace outputDataspace,
+                                    std::string& shader) {
     switch (inputDataspace & HAL_DATASPACE_TRANSFER_MASK) {
         case HAL_DATASPACE_TRANSFER_ST2084:
             shader.append(R"(
@@ -183,8 +185,9 @@
             break;
         case HAL_DATASPACE_TRANSFER_HLG:
             shader.append(R"(
+                    uniform float in_hlgGamma;
                     float3 ScaleLuminance(float3 xyz) {
-                        return xyz * 1000.0 * pow(xyz.y, 0.2);
+                        return xyz * 1000.0 * pow(xyz.y, in_hlgGamma - 1);
                     }
                 )");
             break;
@@ -225,8 +228,10 @@
             break;
         case HAL_DATASPACE_TRANSFER_HLG:
             shader.append(R"(
+                    uniform float in_hlgGamma;
                     float3 NormalizeLuminance(float3 xyz) {
-                        return xyz / 1000.0 * pow(xyz.y / 1000.0, -0.2 / 1.2);
+                        return xyz / 1000.0 *
+                                pow(xyz.y / 1000.0, (1 - in_hlgGamma) / (in_hlgGamma));
                     }
                 )");
             break;
@@ -240,8 +245,8 @@
     }
 }
 
-static void generateOOTF(ui::Dataspace inputDataspace, ui::Dataspace outputDataspace,
-                         std::string& shader) {
+void generateOOTF(ui::Dataspace inputDataspace, ui::Dataspace outputDataspace,
+                  std::string& shader) {
     shader.append(tonemap::getToneMapper()
                           ->generateTonemapGainShaderSkSL(toAidlDataspace(inputDataspace),
                                                           toAidlDataspace(outputDataspace))
@@ -262,7 +267,7 @@
         )");
 }
 
-static void generateOETF(ui::Dataspace dataspace, std::string& shader) {
+void generateOETF(ui::Dataspace dataspace, std::string& shader) {
     switch (dataspace & HAL_DATASPACE_TRANSFER_MASK) {
         case HAL_DATASPACE_TRANSFER_ST2084:
             shader.append(R"(
@@ -384,7 +389,7 @@
     }
 }
 
-static void generateEffectiveOOTF(bool undoPremultipliedAlpha, std::string& shader) {
+void generateEffectiveOOTF(bool undoPremultipliedAlpha, std::string& shader) {
     shader.append(R"(
         uniform shader child;
         half4 main(float2 xy) {
@@ -412,7 +417,7 @@
 }
 
 // please keep in sync with toSkColorSpace function in renderengine/skia/ColorSpaces.cpp
-static ColorSpace toColorSpace(ui::Dataspace dataspace) {
+ColorSpace toColorSpace(ui::Dataspace dataspace) {
     switch (dataspace & HAL_DATASPACE_STANDARD_MASK) {
         case HAL_DATASPACE_STANDARD_BT709:
             return ColorSpace::sRGB();
@@ -438,6 +443,21 @@
     }
 }
 
+template <typename T, std::enable_if_t<std::is_trivially_copyable<T>::value, bool> = true>
+std::vector<uint8_t> buildUniformValue(T value) {
+    std::vector<uint8_t> result;
+    result.resize(sizeof(value));
+    std::memcpy(result.data(), &value, sizeof(value));
+    return result;
+}
+
+// Refer to BT2100-2
+float computeHlgGamma(float currentDisplayBrightnessNits) {
+    return 1.2 + 0.42 * std::log10(currentDisplayBrightnessNits / 1000);
+}
+
+} // namespace
+
 std::string buildLinearEffectSkSL(const LinearEffect& linearEffect) {
     std::string shaderString;
     generateEOTF(linearEffect.fakeInputDataspace == ui::Dataspace::UNKNOWN
@@ -451,14 +471,6 @@
     return shaderString;
 }
 
-template <typename T, std::enable_if_t<std::is_trivially_copyable<T>::value, bool> = true>
-std::vector<uint8_t> buildUniformValue(T value) {
-    std::vector<uint8_t> result;
-    result.resize(sizeof(value));
-    std::memcpy(result.data(), &value, sizeof(value));
-    return result;
-}
-
 // Generates a list of uniforms to set on the LinearEffect shader above.
 std::vector<tonemap::ShaderUniform> buildLinearEffectUniforms(const LinearEffect& linearEffect,
                                                               const mat4& colorTransform,
@@ -480,8 +492,13 @@
                                     colorTransform * mat4(outputColorSpace.getXYZtoRGB()))});
     }
 
+    if ((linearEffect.inputDataspace & HAL_DATASPACE_TRANSFER_MASK) == HAL_DATASPACE_TRANSFER_HLG) {
+        uniforms.push_back(
+                {.name = "in_hlgGamma",
+                 .value = buildUniformValue<float>(computeHlgGamma(currentDisplayLuminanceNits))});
+    }
+
     tonemap::Metadata metadata{.displayMaxLuminance = maxDisplayLuminance,
-                               .currentDisplayLuminanceNits = currentDisplayLuminanceNits,
                                // If the input luminance is unknown, use display luminance (aka,
                                // no-op any luminance changes)
                                // This will be the case for eg screenshots in addition to
diff --git a/libs/tonemap/include/tonemap/tonemap.h b/libs/tonemap/include/tonemap/tonemap.h
index 6233e6c..b9abf8c 100644
--- a/libs/tonemap/include/tonemap/tonemap.h
+++ b/libs/tonemap/include/tonemap/tonemap.h
@@ -44,8 +44,6 @@
 struct Metadata {
     // The maximum luminance of the display in nits
     float displayMaxLuminance = 0.0;
-    // The current luminance of the display in nits
-    float currentDisplayLuminanceNits = 0.0;
     // The maximum luminance of the content in nits
     float contentMaxLuminance = 0.0;
 };
diff --git a/libs/tonemap/tests/tonemap_test.cpp b/libs/tonemap/tests/tonemap_test.cpp
index 7a7958f..1d46482 100644
--- a/libs/tonemap/tests/tonemap_test.cpp
+++ b/libs/tonemap/tests/tonemap_test.cpp
@@ -61,7 +61,7 @@
     EXPECT_GT(contentLumFloat, 0);
 }
 
-TEST_F(TonemapTest, generateTonemapGainShaderSkSL_containsEntryPoint) {
+TEST_F(TonemapTest, generateTonemapGainShaderSkSL_containsEntryPointForPQ) {
     const auto shader =
             tonemap::getToneMapper()
                     ->generateTonemapGainShaderSkSL(aidl::android::hardware::graphics::common::
@@ -73,4 +73,16 @@
     EXPECT_THAT(shader, HasSubstr("float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz)"));
 }
 
+TEST_F(TonemapTest, generateTonemapGainShaderSkSL_containsEntryPointForHLG) {
+    const auto shader =
+            tonemap::getToneMapper()
+                    ->generateTonemapGainShaderSkSL(aidl::android::hardware::graphics::common::
+                                                            Dataspace::BT2020_ITU_HLG,
+                                                    aidl::android::hardware::graphics::common::
+                                                            Dataspace::DISPLAY_P3);
+
+    // Other tests such as librenderengine_test will plug in the shader to check compilation.
+    EXPECT_THAT(shader, HasSubstr("float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz)"));
+}
+
 } // namespace android
diff --git a/libs/tonemap/tonemap.cpp b/libs/tonemap/tonemap.cpp
index c2372fe..bc0a884 100644
--- a/libs/tonemap/tonemap.cpp
+++ b/libs/tonemap/tonemap.cpp
@@ -407,7 +407,6 @@
             )");
         switch (sourceDataspaceInt & kTransferMask) {
             case kTransferST2084:
-            case kTransferHLG:
                 switch (destinationDataspaceInt & kTransferMask) {
                     case kTransferST2084:
                         program.append(R"(
@@ -428,39 +427,22 @@
                         break;
 
                     default:
-                        switch (sourceDataspaceInt & kTransferMask) {
-                            case kTransferST2084:
-                                program.append(R"(
-                                        float libtonemap_OETFTone(float channel) {
-                                            channel = channel / 10000.0;
-                                            float m1 = (2610.0 / 4096.0) / 4.0;
-                                            float m2 = (2523.0 / 4096.0) * 128.0;
-                                            float c1 = (3424.0 / 4096.0);
-                                            float c2 = (2413.0 / 4096.0) * 32.0;
-                                            float c3 = (2392.0 / 4096.0) * 32.0;
-
-                                            float tmp = pow(channel, float(m1));
-                                            tmp = (c1 + c2 * tmp) / (1.0 + c3 * tmp);
-                                            return pow(tmp, float(m2));
-                                        }
-                                    )");
-                                break;
-                            case kTransferHLG:
-                                program.append(R"(
-                                        float libtonemap_OETFTone(float channel) {
-                                            channel = channel / 1000.0;
-                                            const float a = 0.17883277;
-                                            const float b = 0.28466892;
-                                            const float c = 0.55991073;
-                                            return channel <= 1.0 / 12.0 ? sqrt(3.0 * channel) :
-                                                    a * log(12.0 * channel - b) + c;
-                                        }
-                                    )");
-                                break;
-                        }
                         // Here we're mapping from HDR to SDR content, so interpolate using a
                         // Hermitian polynomial onto the smaller luminance range.
                         program.append(R"(
+                                float libtonemap_OETFTone(float channel) {
+                                    channel = channel / 10000.0;
+                                    float m1 = (2610.0 / 4096.0) / 4.0;
+                                    float m2 = (2523.0 / 4096.0) * 128.0;
+                                    float c1 = (3424.0 / 4096.0);
+                                    float c2 = (2413.0 / 4096.0) * 32.0;
+                                    float c3 = (2392.0 / 4096.0) * 32.0;
+
+                                    float tmp = pow(channel, float(m1));
+                                    tmp = (c1 + c2 * tmp) / (1.0 + c3 * tmp);
+                                    return pow(tmp, float(m2));
+                                }
+
                                 float libtonemap_ToneMapTargetNits(float maxRGB) {
                                     float maxInLumi = in_libtonemap_inputMaxLuminance;
                                     float maxOutLumi = in_libtonemap_displayMaxLuminance;
@@ -508,6 +490,30 @@
                         break;
                 }
                 break;
+            case kTransferHLG:
+                switch (destinationDataspaceInt & kTransferMask) {
+                    // HLG -> HDR does not tone-map at all
+                    case kTransferST2084:
+                    case kTransferHLG:
+                        program.append(R"(
+                                    float libtonemap_ToneMapTargetNits(float maxRGB) {
+                                        return maxRGB;
+                                    }
+                                )");
+                        break;
+                    default:
+                        // libshaders follows BT2100 OOTF, but with a nominal peak display luminance
+                        // of 1000 nits. Renormalize to max display luminance if we're tone-mapping
+                        // down to SDR, as libshaders normalizes all SDR output from [0,
+                        // maxDisplayLumins] -> [0, 1]
+                        program.append(R"(
+                                    float libtonemap_ToneMapTargetNits(float maxRGB) {
+                                        return maxRGB * in_libtonemap_displayMaxLuminance / 1000.0;
+                                    }
+                                )");
+                        break;
+                }
+                break;
             default:
                 // Inverse tone-mapping and SDR-SDR mapping is not supported.
                 program.append(R"(
@@ -558,7 +564,6 @@
         double targetNits = 0.0;
         switch (sourceDataspaceInt & kTransferMask) {
             case kTransferST2084:
-            case kTransferHLG:
                 switch (destinationDataspaceInt & kTransferMask) {
                     case kTransferST2084:
                         targetNits = maxRGB;
@@ -587,19 +592,9 @@
                         double x2 = x1 + (x3 - x1) * 4.0 / 17.0;
                         double y2 = maxOutLumi * 0.9;
 
-                        double greyNorm1 = 0.0;
-                        double greyNorm2 = 0.0;
-                        double greyNorm3 = 0.0;
-
-                        if ((sourceDataspaceInt & kTransferMask) == kTransferST2084) {
-                            greyNorm1 = OETF_ST2084(x1);
-                            greyNorm2 = OETF_ST2084(x2);
-                            greyNorm3 = OETF_ST2084(x3);
-                        } else if ((sourceDataspaceInt & kTransferMask) == kTransferHLG) {
-                            greyNorm1 = OETF_HLG(x1);
-                            greyNorm2 = OETF_HLG(x2);
-                            greyNorm3 = OETF_HLG(x3);
-                        }
+                        const double greyNorm1 = OETF_ST2084(x1);
+                        const double greyNorm2 = OETF_ST2084(x2);
+                        const double greyNorm3 = OETF_ST2084(x3);
 
                         double slope2 = (y2 - y1) / (greyNorm2 - greyNorm1);
                         double slope3 = (y3 - y2) / (greyNorm3 - greyNorm2);
@@ -613,12 +608,7 @@
                             break;
                         }
 
-                        double greyNits = 0.0;
-                        if ((sourceDataspaceInt & kTransferMask) == kTransferST2084) {
-                            greyNits = OETF_ST2084(targetNits);
-                        } else if ((sourceDataspaceInt & kTransferMask) == kTransferHLG) {
-                            greyNits = OETF_HLG(targetNits);
-                        }
+                        const double greyNits = OETF_ST2084(targetNits);
 
                         if (greyNits <= greyNorm2) {
                             targetNits = (greyNits - greyNorm2) * slope2 + y2;
@@ -630,15 +620,20 @@
                         break;
                 }
                 break;
-            default:
+            case kTransferHLG:
                 switch (destinationDataspaceInt & kTransferMask) {
                     case kTransferST2084:
                     case kTransferHLG:
-                    default:
                         targetNits = maxRGB;
                         break;
+                    default:
+                        targetNits = maxRGB * metadata.displayMaxLuminance / 1000.0;
+                        break;
                 }
                 break;
+            default:
+                targetNits = maxRGB;
+                break;
         }
 
         return targetNits / maxRGB;
diff --git a/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp
index c97cc94..1a42642 100644
--- a/libs/ui/Gralloc4.cpp
+++ b/libs/ui/Gralloc4.cpp
@@ -62,6 +62,9 @@
 static constexpr Error kTransactionError = Error::NO_RESOURCES;
 static const auto kAidlAllocatorServiceName = AidlIAllocator::descriptor + std::string("/default");
 
+// TODO(b/72323293, b/72703005): Remove these invalid bits from callers
+static constexpr uint64_t kRemovedUsageBits = static_cast<uint64_t>((1 << 10) | (1 << 13));
+
 uint64_t getValidUsageBits() {
     static const uint64_t validUsageBits = []() -> uint64_t {
         uint64_t bits = 0;
@@ -71,7 +74,7 @@
         }
         return bits;
     }();
-    return validUsageBits;
+    return validUsageBits | kRemovedUsageBits;
 }
 
 uint64_t getValidUsageBits41() {
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index e2f0343..612fb84 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -17,6 +17,7 @@
 #include "../dispatcher/InputDispatcher.h"
 
 #include <android-base/properties.h>
+#include <android-base/silent_death_test.h>
 #include <android-base/stringprintf.h>
 #include <android-base/thread_annotations.h>
 #include <binder/Binder.h>
@@ -6276,10 +6277,13 @@
     int mSpyCount{0};
 };
 
+using InputDispatcherSpyWindowDeathTest = InputDispatcherSpyWindowTest;
 /**
  * Adding a spy window that is not a trusted overlay causes Dispatcher to abort.
  */
-TEST_F(InputDispatcherSpyWindowTest, UntrustedSpy_AbortsDispatcher) {
+TEST_F(InputDispatcherSpyWindowDeathTest, UntrustedSpy_AbortsDispatcher) {
+    ScopedSilentDeath _silentDeath;
+
     auto spy = createSpy(WindowInfo::Flag::NOT_TOUCH_MODAL);
     spy->setTrustedOverlay(false);
     ASSERT_DEATH(mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy}}}),
@@ -6743,7 +6747,11 @@
     }
 };
 
-TEST_F(InputDispatcherStylusInterceptorTest, UntrustedOverlay_AbortsDispatcher) {
+using InputDispatcherStylusInterceptorDeathTest = InputDispatcherStylusInterceptorTest;
+
+TEST_F(InputDispatcherStylusInterceptorDeathTest, UntrustedOverlay_AbortsDispatcher) {
+    ScopedSilentDeath _silentDeath;
+
     auto [overlay, window] = setupStylusOverlayScenario();
     overlay->setTrustedOverlay(false);
     // Configuring an untrusted overlay as a stylus interceptor should cause Dispatcher to abort.
diff --git a/services/sensorservice/AidlSensorHalWrapper.cpp b/services/sensorservice/AidlSensorHalWrapper.cpp
index cdd95ca..09aed46 100644
--- a/services/sensorservice/AidlSensorHalWrapper.cpp
+++ b/services/sensorservice/AidlSensorHalWrapper.cpp
@@ -250,6 +250,41 @@
             break;
         }
 
+        case SensorType::ACCELEROMETER_LIMITED_AXES:
+        case SensorType::GYROSCOPE_LIMITED_AXES:
+            dst->limited_axes_imu.x = src.payload.get<Event::EventPayload::limitedAxesImu>().x;
+            dst->limited_axes_imu.y = src.payload.get<Event::EventPayload::limitedAxesImu>().y;
+            dst->limited_axes_imu.z = src.payload.get<Event::EventPayload::limitedAxesImu>().z;
+            dst->limited_axes_imu.x_supported =
+                    src.payload.get<Event::EventPayload::limitedAxesImu>().xSupported;
+            dst->limited_axes_imu.y_supported =
+                    src.payload.get<Event::EventPayload::limitedAxesImu>().ySupported;
+            dst->limited_axes_imu.z_supported =
+                    src.payload.get<Event::EventPayload::limitedAxesImu>().zSupported;
+            break;
+
+        case SensorType::ACCELEROMETER_LIMITED_AXES_UNCALIBRATED:
+        case SensorType::GYROSCOPE_LIMITED_AXES_UNCALIBRATED:
+            dst->limited_axes_imu_uncalibrated.x_uncalib =
+                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().x;
+            dst->limited_axes_imu_uncalibrated.y_uncalib =
+                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().y;
+            dst->limited_axes_imu_uncalibrated.z_uncalib =
+                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().z;
+            dst->limited_axes_imu_uncalibrated.x_bias =
+                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().xBias;
+            dst->limited_axes_imu_uncalibrated.y_bias =
+                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().yBias;
+            dst->limited_axes_imu_uncalibrated.z_bias =
+                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().zBias;
+            dst->limited_axes_imu_uncalibrated.x_supported =
+                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().xSupported;
+            dst->limited_axes_imu_uncalibrated.y_supported =
+                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().ySupported;
+            dst->limited_axes_imu_uncalibrated.z_supported =
+                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().zSupported;
+            break;
+
         default: {
             CHECK_GE((int32_t)src.sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE);
 
@@ -264,7 +299,7 @@
     *dst = {
             .timestamp = src.timestamp,
             .sensorHandle = src.sensor,
-            .sensorType = (SensorType) src.type,
+            .sensorType = (SensorType)src.type,
     };
 
     switch (dst->sensorType) {
@@ -409,6 +444,35 @@
             break;
         }
 
+        case SensorType::ACCELEROMETER_LIMITED_AXES:
+        case SensorType::GYROSCOPE_LIMITED_AXES: {
+            Event::EventPayload::LimitedAxesImu limitedAxesImu;
+            limitedAxesImu.x = src.limited_axes_imu.x;
+            limitedAxesImu.y = src.limited_axes_imu.y;
+            limitedAxesImu.z = src.limited_axes_imu.z;
+            limitedAxesImu.xSupported = src.limited_axes_imu.x_supported;
+            limitedAxesImu.ySupported = src.limited_axes_imu.y_supported;
+            limitedAxesImu.zSupported = src.limited_axes_imu.z_supported;
+            dst->payload.set<Event::EventPayload::Tag::limitedAxesImu>(limitedAxesImu);
+            break;
+        }
+
+        case SensorType::ACCELEROMETER_LIMITED_AXES_UNCALIBRATED:
+        case SensorType::GYROSCOPE_LIMITED_AXES_UNCALIBRATED: {
+            Event::EventPayload::LimitedAxesImuUncal limitedAxesImuUncal;
+            limitedAxesImuUncal.x = src.limited_axes_imu_uncalibrated.x_uncalib;
+            limitedAxesImuUncal.y = src.limited_axes_imu_uncalibrated.y_uncalib;
+            limitedAxesImuUncal.z = src.limited_axes_imu_uncalibrated.z_uncalib;
+            limitedAxesImuUncal.xBias = src.limited_axes_imu_uncalibrated.x_bias;
+            limitedAxesImuUncal.yBias = src.limited_axes_imu_uncalibrated.y_bias;
+            limitedAxesImuUncal.zBias = src.limited_axes_imu_uncalibrated.z_bias;
+            limitedAxesImuUncal.xSupported = src.limited_axes_imu_uncalibrated.x_supported;
+            limitedAxesImuUncal.ySupported = src.limited_axes_imu_uncalibrated.y_supported;
+            limitedAxesImuUncal.zSupported = src.limited_axes_imu_uncalibrated.z_supported;
+            dst->payload.set<Event::EventPayload::Tag::limitedAxesImuUncal>(limitedAxesImuUncal);
+            break;
+        }
+
         default: {
             CHECK_GE((int32_t)dst->sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE);
 
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index d5b629d..3c4f8d9 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -17,6 +17,7 @@
         "Fusion.cpp",
         "GravitySensor.cpp",
         "HidlSensorHalWrapper.cpp",
+        "LimitedAxesImuSensor.cpp",
         "LinearAccelerationSensor.cpp",
         "OrientationSensor.cpp",
         "RecentEventLogger.cpp",
diff --git a/services/sensorservice/LimitedAxesImuSensor.cpp b/services/sensorservice/LimitedAxesImuSensor.cpp
new file mode 100644
index 0000000..2f91479
--- /dev/null
+++ b/services/sensorservice/LimitedAxesImuSensor.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <math.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+
+#include <hardware/sensors.h>
+
+#include "LimitedAxesImuSensor.h"
+#include "SensorDevice.h"
+#include "SensorFusion.h"
+#include "SensorServiceUtils.h"
+
+namespace android {
+
+namespace {
+const sensor_t DUMMY_SENSOR = {.name = "",
+                               .vendor = "",
+                               .stringType = "",
+                               .requiredPermission = ""};
+} // unnamed namespace
+
+LimitedAxesImuSensor::LimitedAxesImuSensor(sensor_t const* list, size_t count,
+                                           int32_t imu3dSensorType)
+      : BaseSensor(DUMMY_SENSOR) {
+    for (size_t i = 0; i < count; i++) {
+        if (list[i].type == imu3dSensorType) {
+            mImu3dSensor = Sensor(list + i);
+            break;
+        }
+    }
+
+    const int32_t imuLimitedAxesSensorType = convertImu3dToLimitedAxesSensorType(imu3dSensorType);
+
+    const sensor_t sensor = {
+            .name = convertLimitedAxesSensorTypeToName(imuLimitedAxesSensorType),
+            .vendor = "AOSP",
+            .version = 1,
+            .handle = convertLimitedAxesSensorTypeToHandle(imuLimitedAxesSensorType),
+            .type = imuLimitedAxesSensorType,
+            .maxRange = mImu3dSensor.getMaxValue(),
+            .resolution = mImu3dSensor.getResolution(),
+            .power = mImu3dSensor.getPowerUsage(),
+            .minDelay = mImu3dSensor.getMinDelay(),
+    };
+    mSensor = Sensor(&sensor);
+}
+
+bool LimitedAxesImuSensor::process(sensors_event_t* outEvent, const sensors_event_t& event) {
+    if (event.type == mImu3dSensor.getType()) {
+        *outEvent = event;
+        size_t imu3dDataSize = SensorServiceUtil::eventSizeBySensorType(mImu3dSensor.getType());
+        outEvent->data[0 + imu3dDataSize] = 1;
+        outEvent->data[1 + imu3dDataSize] = 1;
+        outEvent->data[2 + imu3dDataSize] = 1;
+        outEvent->sensor = mSensor.getHandle();
+        outEvent->type = mSensor.getType();
+        return true;
+    }
+    return false;
+}
+
+status_t LimitedAxesImuSensor::activate(void* ident, bool enabled) {
+    return mSensorDevice.activate(ident, mImu3dSensor.getHandle(), enabled);
+}
+
+status_t LimitedAxesImuSensor::setDelay(void* ident, int /*handle*/, int64_t ns) {
+    return mSensorDevice.setDelay(ident, mImu3dSensor.getHandle(), ns);
+}
+
+int32_t LimitedAxesImuSensor::convertImu3dToLimitedAxesSensorType(int32_t imu3dSensorType) {
+    switch (imu3dSensorType) {
+        case SENSOR_TYPE_ACCELEROMETER:
+            return SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES;
+        case SENSOR_TYPE_GYROSCOPE:
+            return SENSOR_TYPE_GYROSCOPE_LIMITED_AXES;
+        case SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED:
+            return SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED;
+        case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
+            return SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED;
+        default:
+            return 0;
+    }
+}
+
+int32_t LimitedAxesImuSensor::convertLimitedAxesSensorTypeToHandle(
+        int32_t imuLimitedAxesSensorType) {
+    switch (imuLimitedAxesSensorType) {
+        case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES:
+            return '_ala';
+        case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES:
+            return '_gla';
+        case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED:
+            return '_alc';
+        case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED:
+            return '_glc';
+        default:
+            return 0;
+    }
+}
+
+const char* LimitedAxesImuSensor::convertLimitedAxesSensorTypeToName(
+        int32_t imuLimitedAxesSensorType) {
+    switch (imuLimitedAxesSensorType) {
+        case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES:
+            return "Accelerometer Limited Axes Sensor";
+        case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES:
+            return "Gyroscope Limited Axes Sensor";
+        case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED:
+            return "Accelerometer Limited Axes Uncalibrated Sensor";
+        case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED:
+            return "Gyroscope Limited Axes Uncalibrated Sensor";
+        default:
+            return "";
+    }
+}
+
+}; // namespace android
diff --git a/services/sensorservice/LimitedAxesImuSensor.h b/services/sensorservice/LimitedAxesImuSensor.h
new file mode 100644
index 0000000..fd46a98
--- /dev/null
+++ b/services/sensorservice/LimitedAxesImuSensor.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <sensor/Sensor.h>
+
+#include "SensorInterface.h"
+
+namespace android {
+
+class SensorDevice;
+
+class LimitedAxesImuSensor : public BaseSensor {
+    Sensor mImu3dSensor;
+
+public:
+    LimitedAxesImuSensor(sensor_t const* list, size_t count, int32_t imuSensorType);
+    virtual bool process(sensors_event_t* outEvent, const sensors_event_t& event) override;
+    virtual status_t activate(void* ident, bool enabled) override;
+    virtual status_t setDelay(void* ident, int handle, int64_t ns) override;
+    virtual bool isVirtual() const override { return true; }
+
+private:
+    int32_t convertImu3dToLimitedAxesSensorType(int32_t imu3dSensorType);
+    int32_t convertLimitedAxesSensorTypeToHandle(int32_t imuLimitedAxesSensorType);
+    const char* convertLimitedAxesSensorTypeToName(int32_t imuLimitedAxesSensorType);
+};
+
+}; // namespace android
\ No newline at end of file
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 517d383..971491d 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -38,6 +38,7 @@
 #include "BatteryService.h"
 #include "CorrectedGyroSensor.h"
 #include "GravitySensor.h"
+#include "LimitedAxesImuSensor.h"
 #include "LinearAccelerationSensor.h"
 #include "OrientationSensor.h"
 #include "RotationVectorSensor.h"
@@ -101,6 +102,33 @@
 static const String16 sLocationHardwarePermission("android.permission.LOCATION_HARDWARE");
 static const String16 sManageSensorsPermission("android.permission.MANAGE_SENSORS");
 
+static bool isAutomotive() {
+    sp<IServiceManager> serviceManager = defaultServiceManager();
+    if (serviceManager.get() == nullptr) {
+        ALOGE("%s: unable to access native ServiceManager", __func__);
+        return false;
+    }
+
+    sp<content::pm::IPackageManagerNative> packageManager;
+    sp<IBinder> binder = serviceManager->waitForService(String16("package_native"));
+    packageManager = interface_cast<content::pm::IPackageManagerNative>(binder);
+    if (packageManager == nullptr) {
+        ALOGE("%s: unable to access native PackageManager", __func__);
+        return false;
+    }
+
+    bool isAutomotive = false;
+    binder::Status status =
+        packageManager->hasSystemFeature(String16("android.hardware.type.automotive"), 0,
+                                         &isAutomotive);
+    if (!status.isOk()) {
+        ALOGE("%s: hasSystemFeature failed: %s", __func__, status.exceptionMessage().c_str());
+        return false;
+    }
+
+    return isAutomotive;
+}
+
 SensorService::SensorService()
     : mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
       mWakeLockAcquired(false), mLastReportedProxIsActive(false) {
@@ -165,6 +193,8 @@
         ssize_t count = dev.getSensorList(&list);
         if (count > 0) {
             bool hasGyro = false, hasAccel = false, hasMag = false;
+            bool hasGyroUncalibrated = false;
+            bool hasAccelUncalibrated = false;
             uint32_t virtualSensorsNeeds =
                     (1<<SENSOR_TYPE_GRAVITY) |
                     (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
@@ -179,13 +209,18 @@
                     case SENSOR_TYPE_ACCELEROMETER:
                         hasAccel = true;
                         break;
+                    case SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED:
+                        hasAccelUncalibrated = true;
+                        break;
                     case SENSOR_TYPE_MAGNETIC_FIELD:
                         hasMag = true;
                         break;
                     case SENSOR_TYPE_GYROSCOPE:
-                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
                         hasGyro = true;
                         break;
+                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
+                        hasGyroUncalibrated = true;
+                        break;
                     case SENSOR_TYPE_GRAVITY:
                     case SENSOR_TYPE_LINEAR_ACCELERATION:
                     case SENSOR_TYPE_ROTATION_VECTOR:
@@ -216,7 +251,7 @@
             // registered)
             SensorFusion::getInstance();
 
-            if (hasGyro && hasAccel && hasMag) {
+            if ((hasGyro || hasGyroUncalibrated) && hasAccel && hasMag) {
                 // Add Android virtual sensors if they're not already
                 // available in the HAL
                 bool needRotationVector =
@@ -230,7 +265,7 @@
                 registerSensor( new GyroDriftSensor(), true, true);
             }
 
-            if (hasAccel && hasGyro) {
+            if (hasAccel && (hasGyro || hasGyroUncalibrated)) {
                 bool needGravitySensor = (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) != 0;
                 registerSensor(new GravitySensor(list, count), !needGravitySensor, true);
 
@@ -250,6 +285,30 @@
                 registerSensor(new GeoMagRotationVectorSensor(), !needGeoMagRotationVector, true);
             }
 
+            if (isAutomotive()) {
+                if (hasAccel) {
+                   registerSensor(new LimitedAxesImuSensor(list, count, SENSOR_TYPE_ACCELEROMETER),
+                                  /*isDebug=*/false, /*isVirtual=*/true);
+               }
+
+               if (hasGyro) {
+                   registerSensor(new LimitedAxesImuSensor(list, count, SENSOR_TYPE_GYROSCOPE),
+                                  /*isDebug=*/false, /*isVirtual=*/true);
+               }
+
+               if (hasAccelUncalibrated) {
+                   registerSensor(new LimitedAxesImuSensor(list, count,
+                                                           SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED),
+                                  /*isDebug=*/false, /*isVirtual=*/true);
+               }
+
+               if (hasGyroUncalibrated) {
+                   registerSensor(new LimitedAxesImuSensor(list, count,
+                                                           SENSOR_TYPE_GYROSCOPE_UNCALIBRATED),
+                                  /*isDebug=*/false, /*isVirtual=*/true);
+               }
+            }
+
             // Check if the device really supports batching by looking at the FIFO event
             // counts for each sensor.
             bool batchingSupported = false;
diff --git a/services/sensorservice/SensorServiceUtils.cpp b/services/sensorservice/SensorServiceUtils.cpp
index baa01c9..c304381 100644
--- a/services/sensorservice/SensorServiceUtils.cpp
+++ b/services/sensorservice/SensorServiceUtils.cpp
@@ -30,12 +30,18 @@
         case SENSOR_TYPE_POSE_6DOF:
             return 16;
 
+        case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED:
+        case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED:
+            return 9;
+
         case SENSOR_TYPE_ROTATION_VECTOR:
         case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
             return 5;
 
         case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
         case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
+        case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES:
+        case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES:
             return 6;
 
         case SENSOR_TYPE_GAME_ROTATION_VECTOR:
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index af0f524..d9958f3 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -118,9 +118,6 @@
 cc_defaults {
     name: "libsurfaceflinger_production_defaults",
     defaults: ["libsurfaceflinger_defaults"],
-    cflags: [
-        "-fvisibility=hidden",
-    ],
     lto: {
         thin: true,
     },
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index e797b5d..b7e2ff3 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -306,7 +306,7 @@
                 : aidl::android::hardware::graphics::composer3::Composition::DEVICE;
     }
 
-    compositionState->buffer = mBufferInfo.mBuffer->getBuffer();
+    compositionState->buffer = getBuffer();
     compositionState->bufferSlot = (mBufferInfo.mBufferSlot == BufferQueue::INVALID_BUFFER_SLOT)
             ? 0
             : mBufferInfo.mBufferSlot;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
index 16aebef..ee0c53d 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
@@ -26,8 +26,18 @@
 // Defines the interface used by the CompositionEngine to make requests
 // of the front-end layer.
 class LayerFE : public compositionengine::LayerFE {
-public:
+private:
+    // Making the constructor private as this class implements RefBase,
+    // and constructing it with a different way than sp<LayerFE>::make() causes
+    // a memory leak of the shared state.
     LayerFE();
+
+    // friends class to allow instantiation via sp<LayerFE>::make() and
+    // sp<StrictMock<LayerFE>>::make()
+    friend class sp<LayerFE>;
+    friend class testing::StrictMock<LayerFE>;
+
+public:
     virtual ~LayerFE();
 
     MOCK_CONST_METHOD0(getCompositionState, const LayerFECompositionState*());
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 1ea13a7..29c146b 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -59,9 +59,13 @@
     setName(args.name);
     bool isBootModeSupported = getCompositionEngine().getHwComposer().getBootDisplayModeSupport();
     const auto physicalId = PhysicalDisplayId::tryCast(mId);
-    if (physicalId && isBootModeSupported) {
-        mPreferredBootDisplayModeId = static_cast<int32_t>(
-                getCompositionEngine().getHwComposer().getPreferredBootDisplayMode(*physicalId));
+    if (!physicalId || !isBootModeSupported) {
+        return;
+    }
+    std::optional<hal::HWConfigId> preferredBootModeId =
+            getCompositionEngine().getHwComposer().getPreferredBootDisplayMode(*physicalId);
+    if (preferredBootModeId.has_value()) {
+        mPreferredBootDisplayModeId = static_cast<int32_t>(preferredBootModeId.value());
     }
 }
 
diff --git a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
index 325361b..de9de01 100644
--- a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
@@ -203,9 +203,9 @@
  */
 
 struct CompositionTestPreComposition : public CompositionEngineTest {
-    sp<StrictMock<mock::LayerFE>> mLayer1FE{new StrictMock<mock::LayerFE>()};
-    sp<StrictMock<mock::LayerFE>> mLayer2FE{new StrictMock<mock::LayerFE>()};
-    sp<StrictMock<mock::LayerFE>> mLayer3FE{new StrictMock<mock::LayerFE>()};
+    sp<StrictMock<mock::LayerFE>> mLayer1FE = sp<StrictMock<mock::LayerFE>>::make();
+    sp<StrictMock<mock::LayerFE>> mLayer2FE = sp<StrictMock<mock::LayerFE>>::make();
+    sp<StrictMock<mock::LayerFE>> mLayer3FE = sp<StrictMock<mock::LayerFE>>::make();
 };
 
 TEST_F(CompositionTestPreComposition, preCompositionSetsFrameTimestamp) {
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index 03c6f8d..125ce74 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -74,7 +74,7 @@
         EXPECT_CALL(*outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
     }
 
-    sp<mock::LayerFE> layerFE = new StrictMock<mock::LayerFE>();
+    sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
     StrictMock<mock::OutputLayer>* outputLayer = new StrictMock<mock::OutputLayer>();
     StrictMock<HWC2::mock::Layer> hwc2Layer;
 };
@@ -85,7 +85,7 @@
         EXPECT_CALL(*outputLayer, getHwcLayer()).WillRepeatedly(Return(nullptr));
     }
 
-    sp<mock::LayerFE> layerFE = new StrictMock<mock::LayerFE>();
+    sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
     StrictMock<mock::OutputLayer>* outputLayer = new StrictMock<mock::OutputLayer>();
 };
 
@@ -469,7 +469,7 @@
 using DisplayCreateOutputLayerTest = FullDisplayImplTestCommon;
 
 TEST_F(DisplayCreateOutputLayerTest, setsHwcLayer) {
-    sp<mock::LayerFE> layerFE = new StrictMock<mock::LayerFE>();
+    sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
     auto hwcLayer = std::make_shared<StrictMock<HWC2::mock::Layer>>();
 
     EXPECT_CALL(mHwComposer, createLayer(HalDisplayId(DEFAULT_DISPLAY_ID)))
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index bcd4dc2..660f664 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -108,7 +108,7 @@
                           hal::VsyncPeriodChangeTimeline*));
     MOCK_METHOD2(setBootDisplayMode, status_t(PhysicalDisplayId, hal::HWConfigId));
     MOCK_METHOD1(clearBootDisplayMode, status_t(PhysicalDisplayId));
-    MOCK_METHOD1(getPreferredBootDisplayMode, hal::HWConfigId(PhysicalDisplayId));
+    MOCK_METHOD1(getPreferredBootDisplayMode, std::optional<hal::HWConfigId>(PhysicalDisplayId));
     MOCK_METHOD0(getBootDisplayModeSupport, bool());
     MOCK_METHOD2(setAutoLowLatencyMode, status_t(PhysicalDisplayId, bool));
     MOCK_METHOD2(getSupportedContentTypes,
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
index 0b123b1..82dcc66 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -109,8 +109,8 @@
     }
 
     compositionengine::mock::Output mOutput;
-    sp<compositionengine::mock::LayerFE> mLayerFE{
-            new StrictMock<compositionengine::mock::LayerFE>()};
+    sp<StrictMock<compositionengine::mock::LayerFE>> mLayerFE =
+            sp<StrictMock<compositionengine::mock::LayerFE>>::make();
     OutputLayer mOutputLayer{mOutput, mLayerFE};
 
     LayerFECompositionState mLayerFEState;
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index f7d5991..e72bc9f 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -106,7 +106,7 @@
     }
 
     mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
-    sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
+    sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
     LayerFECompositionState layerFEState;
     impl::OutputLayerCompositionState outputLayerState;
 };
@@ -123,7 +123,7 @@
     }
 
     mock::OutputLayer outputLayer;
-    sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
+    sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
     LayerFECompositionState layerFEState;
     impl::OutputLayerCompositionState outputLayerState;
 };
@@ -722,9 +722,9 @@
 using OutputSetReleasedLayersTest = OutputTest;
 
 TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
-    sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
-    sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
-    sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
+    sp<StrictMock<mock::LayerFE>> layer1FE = sp<StrictMock<mock::LayerFE>>::make();
+    sp<StrictMock<mock::LayerFE>> layer2FE = sp<StrictMock<mock::LayerFE>>::make();
+    sp<StrictMock<mock::LayerFE>> layer3FE = sp<StrictMock<mock::LayerFE>>::make();
 
     Output::ReleasedLayers layers;
     layers.push_back(layer1FE);
@@ -1209,7 +1209,7 @@
 
         StrictMock<mock::OutputLayer> outputLayer;
         impl::OutputLayerCompositionState outputLayerState;
-        sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
+        sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
     };
 
     OutputCollectVisibleLayersTest() {
@@ -2987,9 +2987,9 @@
     EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
 
     // Load up the released layers with some mock instances
-    sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
-    sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
-    sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
+    sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
+    sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
+    sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
     Output::ReleasedLayers layers;
     layers.push_back(releasedLayer1);
     layers.push_back(releasedLayer2);
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp
index 84b3fc5..0b1c262 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp
@@ -107,7 +107,7 @@
         EXPECT_EQ(fields, rhs.getDifferingFields(lhs));
     }
 
-    mock::LayerFE mLayerFE;
+    sp<mock::LayerFE> mLayerFE = sp<mock::LayerFE>::make();
     mock::OutputLayer mOutputLayer;
     std::unique_ptr<LayerState> mLayerState;
 };
@@ -115,7 +115,7 @@
 TEST_F(LayerStateTest, getOutputLayer) {
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     EXPECT_EQ(&mOutputLayer, mLayerState->getOutputLayer());
@@ -124,14 +124,14 @@
 TEST_F(LayerStateTest, updateOutputLayer) {
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     EXPECT_EQ(&mOutputLayer, mLayerState->getOutputLayer());
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState->update(&newOutputLayer);
     EXPECT_EQ(&newOutputLayer, mLayerState->getOutputLayer());
@@ -140,7 +140,7 @@
 TEST_F(LayerStateTest, getId) {
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     EXPECT_EQ(sSequenceId, mLayerState->getId());
@@ -149,13 +149,13 @@
 TEST_F(LayerStateTest, updateId) {
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionState, sSequenceIdTwo);
     Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
     EXPECT_EQ(sSequenceIdTwo, mLayerState->getId());
@@ -165,12 +165,12 @@
 TEST_F(LayerStateTest, compareId) {
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionState, sSequenceIdTwo);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -185,7 +185,7 @@
 TEST_F(LayerStateTest, getName) {
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     EXPECT_EQ(sDebugName, mLayerState->getName());
@@ -194,13 +194,13 @@
 TEST_F(LayerStateTest, updateName) {
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionState, sSequenceId, sDebugNameTwo);
     Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
     EXPECT_EQ(sDebugNameTwo, mLayerState->getName());
@@ -210,12 +210,12 @@
 TEST_F(LayerStateTest, compareName) {
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionState, sSequenceId, sDebugNameTwo);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -231,7 +231,7 @@
     OutputLayerCompositionState outputLayerCompositionState;
     outputLayerCompositionState.displayFrame = sRectOne;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     EXPECT_EQ(sRectOne, mLayerState->getDisplayFrame());
@@ -241,15 +241,15 @@
     OutputLayerCompositionState outputLayerCompositionState;
     outputLayerCompositionState.displayFrame = sRectOne;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo;
     outputLayerCompositionStateTwo.displayFrame = sRectTwo;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo,
                        layerFECompositionState);
     Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
     EXPECT_EQ(sRectTwo, mLayerState->getDisplayFrame());
@@ -260,14 +260,14 @@
     OutputLayerCompositionState outputLayerCompositionState;
     outputLayerCompositionState.displayFrame = sRectOne;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo;
     outputLayerCompositionStateTwo.displayFrame = sRectTwo;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo,
                        layerFECompositionState);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -282,7 +282,7 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.compositionType = Composition::DEVICE;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     EXPECT_EQ(Composition::DEVICE, mLayerState->getCompositionType());
@@ -293,7 +293,7 @@
     outputLayerCompositionState.forceClientComposition = true;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.compositionType = Composition::DEVICE;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     EXPECT_EQ(Composition::CLIENT, mLayerState->getCompositionType());
@@ -303,15 +303,15 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.compositionType = Composition::DEVICE;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.compositionType = Composition::SOLID_COLOR;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
     EXPECT_EQ(Composition::SOLID_COLOR, mLayerState->getCompositionType());
@@ -322,14 +322,14 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.compositionType = Composition::DEVICE;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.compositionType = Composition::SOLID_COLOR;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -345,15 +345,15 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.buffer = new GraphicBuffer();
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.buffer = new GraphicBuffer();
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
     EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Buffer), updates);
@@ -363,14 +363,14 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.buffer = new GraphicBuffer();
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.buffer = new GraphicBuffer();
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -386,15 +386,15 @@
     OutputLayerCompositionState outputLayerCompositionState;
     outputLayerCompositionState.sourceCrop = sFloatRectOne;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo;
     outputLayerCompositionStateTwo.sourceCrop = sFloatRectTwo;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo,
                        layerFECompositionState);
     Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
     EXPECT_EQ(Flags<LayerStateField>(LayerStateField::SourceCrop), updates);
@@ -404,14 +404,14 @@
     OutputLayerCompositionState outputLayerCompositionState;
     outputLayerCompositionState.sourceCrop = sFloatRectOne;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo;
     outputLayerCompositionStateTwo.sourceCrop = sFloatRectTwo;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo,
                        layerFECompositionState);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -425,15 +425,15 @@
     OutputLayerCompositionState outputLayerCompositionState;
     outputLayerCompositionState.bufferTransform = Hwc2::Transform::FLIP_H;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo;
     outputLayerCompositionStateTwo.bufferTransform = Hwc2::Transform::FLIP_V;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo,
                        layerFECompositionState);
     Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
     EXPECT_EQ(Flags<LayerStateField>(LayerStateField::BufferTransform), updates);
@@ -443,14 +443,14 @@
     OutputLayerCompositionState outputLayerCompositionState;
     outputLayerCompositionState.bufferTransform = Hwc2::Transform::FLIP_H;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo;
     outputLayerCompositionStateTwo.bufferTransform = Hwc2::Transform::FLIP_V;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo,
                        layerFECompositionState);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -465,15 +465,15 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.blendMode = hal::BlendMode::COVERAGE;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.blendMode = hal::BlendMode::PREMULTIPLIED;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
     EXPECT_EQ(Flags<LayerStateField>(LayerStateField::BlendMode), updates);
@@ -483,14 +483,14 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.blendMode = hal::BlendMode::COVERAGE;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.blendMode = hal::BlendMode::PREMULTIPLIED;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -504,15 +504,15 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.alpha = sAlphaOne;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.alpha = sAlphaTwo;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
     EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Alpha), updates);
@@ -522,14 +522,14 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.alpha = sAlphaOne;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.alpha = sAlphaTwo;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -543,15 +543,15 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.metadata[sMetadataKeyOne] = sMetadataValueOne;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.metadata[sMetadataKeyTwo] = sMetadataValueTwo;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
     EXPECT_EQ(Flags<LayerStateField>(LayerStateField::LayerMetadata), updates);
@@ -561,14 +561,14 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.metadata[sMetadataKeyOne] = sMetadataValueOne;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.metadata[sMetadataKeyTwo] = sMetadataValueTwo;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -582,7 +582,7 @@
     OutputLayerCompositionState outputLayerCompositionState;
     outputLayerCompositionState.visibleRegion = sRegionOne;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     EXPECT_TRUE(mLayerState->getVisibleRegion().hasSameRects(sRegionOne));
@@ -592,15 +592,15 @@
     OutputLayerCompositionState outputLayerCompositionState;
     outputLayerCompositionState.visibleRegion = sRegionOne;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo;
     outputLayerCompositionStateTwo.visibleRegion = sRegionTwo;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo,
                        layerFECompositionState);
     Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
     EXPECT_EQ(Flags<LayerStateField>(LayerStateField::VisibleRegion), updates);
@@ -610,14 +610,14 @@
     OutputLayerCompositionState outputLayerCompositionState;
     outputLayerCompositionState.visibleRegion = sRegionOne;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo;
     outputLayerCompositionStateTwo.visibleRegion = sRegionTwo;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo,
                        layerFECompositionState);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -631,15 +631,15 @@
     OutputLayerCompositionState outputLayerCompositionState;
     outputLayerCompositionState.dataspace = ui::Dataspace::SRGB;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo;
     outputLayerCompositionStateTwo.dataspace = ui::Dataspace::DISPLAY_P3;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo,
                        layerFECompositionState);
     Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
     EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Dataspace), updates);
@@ -649,14 +649,14 @@
     OutputLayerCompositionState outputLayerCompositionState;
     outputLayerCompositionState.dataspace = ui::Dataspace::SRGB;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo;
     outputLayerCompositionStateTwo.dataspace = ui::Dataspace::DISPLAY_P3;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo,
                        layerFECompositionState);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -674,19 +674,19 @@
                               AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
                                       AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN,
                               "buffer1");
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.buffer =
             new GraphicBuffer(1, 1, PIXEL_FORMAT_RGBX_8888,
                               AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
                                       AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN,
                               "buffer2");
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
     EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Buffer) |
@@ -702,18 +702,18 @@
                               AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
                                       AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN,
                               "buffer1");
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.buffer =
             new GraphicBuffer(1, 1, PIXEL_FORMAT_RGBX_8888,
                               AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
                                       AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN,
                               "buffer2");
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -729,16 +729,16 @@
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.colorTransformIsIdentity = true;
     layerFECompositionState.colorTransform = mat4();
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.colorTransformIsIdentity = false;
     layerFECompositionStateTwo.colorTransform = sMat4One;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
     EXPECT_EQ(Flags<LayerStateField>(LayerStateField::ColorTransform), updates);
@@ -749,15 +749,15 @@
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.colorTransformIsIdentity = true;
     layerFECompositionState.colorTransform = mat4();
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.colorTransformIsIdentity = false;
     layerFECompositionStateTwo.colorTransform = sMat4One;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -771,15 +771,15 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.sidebandStream = NativeHandle::create(sFakeSidebandStreamOne, false);
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.sidebandStream = NativeHandle::create(sFakeSidebandStreamTwo, false);
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
     EXPECT_EQ(Flags<LayerStateField>(LayerStateField::SidebandStream), updates);
@@ -789,14 +789,14 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.sidebandStream = NativeHandle::create(sFakeSidebandStreamOne, false);
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.sidebandStream = NativeHandle::create(sFakeSidebandStreamTwo, false);
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -810,15 +810,15 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.color = sHalf4One;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.color = sHalf4Two;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
     EXPECT_EQ(Flags<LayerStateField>(LayerStateField::SolidColor), updates);
@@ -828,14 +828,14 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.color = sHalf4One;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.color = sHalf4Two;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -849,15 +849,15 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.backgroundBlurRadius = sBgBlurRadiusOne;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.backgroundBlurRadius = sBgBlurRadiusTwo;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
     EXPECT_EQ(Flags<LayerStateField>(LayerStateField::BackgroundBlurRadius), updates);
@@ -867,14 +867,14 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.backgroundBlurRadius = sBgBlurRadiusOne;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.backgroundBlurRadius = sBgBlurRadiusTwo;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -889,15 +889,15 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.blurRegions.push_back(sBlurRegionOne);
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.blurRegions.push_back(sBlurRegionTwo);
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
     EXPECT_EQ(Flags<LayerStateField>(LayerStateField::BlurRegions), updates);
@@ -907,14 +907,14 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.blurRegions.push_back(sBlurRegionOne);
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.blurRegions.push_back(sBlurRegionTwo);
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -927,7 +927,7 @@
 TEST_F(LayerStateTest, hasBlurBehind_noBlur_returnsFalse) {
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     EXPECT_FALSE(mLayerState->hasBlurBehind());
@@ -937,7 +937,7 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.backgroundBlurRadius = sBgBlurRadiusOne;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     EXPECT_TRUE(mLayerState->hasBlurBehind());
@@ -947,7 +947,7 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.blurRegions.push_back(sBlurRegionOne);
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     EXPECT_TRUE(mLayerState->hasBlurBehind());
@@ -956,7 +956,7 @@
 TEST_F(LayerStateTest, dumpDoesNotCrash) {
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     std::string dump;
@@ -967,7 +967,7 @@
 TEST_F(LayerStateTest, framesSinceBufferUpdate) {
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
@@ -982,14 +982,14 @@
     OutputLayerCompositionState outputLayerCompositionState;
     outputLayerCompositionState.displayFrame = sRectOne;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo;
     outputLayerCompositionStateTwo.displayFrame = sRectTwo;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo,
                        layerFECompositionState);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -1001,14 +1001,14 @@
     OutputLayerCompositionState outputLayerCompositionState;
     outputLayerCompositionState.displayFrame = sRectOne;
     LayerFECompositionState layerFECompositionState;
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo;
     outputLayerCompositionStateTwo.displayFrame = sRectTwo;
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionStateTwo,
                        layerFECompositionState);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
@@ -1020,15 +1020,15 @@
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;
     layerFECompositionState.buffer = new GraphicBuffer();
-    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
                        layerFECompositionState);
     mLayerState = std::make_unique<LayerState>(&mOutputLayer);
 
     mock::OutputLayer newOutputLayer;
-    mock::LayerFE newLayerFE;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.buffer = new GraphicBuffer();
-    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
                        layerFECompositionStateTwo);
     auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
 
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/PredictorTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/PredictorTest.cpp
index 6038268..68c72e0 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/PredictorTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/PredictorTest.cpp
@@ -73,26 +73,26 @@
 
 TEST_F(LayerStackTest, getApproximateMatch_doesNotMatchSizeDifferences) {
     mock::OutputLayer outputLayerOne;
-    mock::LayerFE layerFEOne;
+    sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateOne;
     LayerFECompositionState layerFECompositionStateOne;
-    setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne,
+    setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
                        layerFECompositionStateOne);
     LayerState layerStateOne(&outputLayerOne);
 
     mock::OutputLayer outputLayerTwo;
-    mock::LayerFE layerFETwo;
+    sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo;
     LayerFECompositionState layerFECompositionStateTwo;
-    setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo,
+    setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
                        layerFECompositionStateTwo);
     LayerState layerStateTwo(&outputLayerTwo);
 
     mock::OutputLayer outputLayerThree;
-    mock::LayerFE layerFEThree;
+    sp<mock::LayerFE> layerFEThree = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateThree;
     LayerFECompositionState layerFECompositionStateThree;
-    setupMocksForLayer(outputLayerThree, layerFEThree, outputLayerCompositionStateThree,
+    setupMocksForLayer(outputLayerThree, *layerFEThree, outputLayerCompositionStateThree,
                        layerFECompositionStateThree);
     LayerState layerStateThree(&outputLayerThree);
 
@@ -104,20 +104,20 @@
 
 TEST_F(LayerStackTest, getApproximateMatch_doesNotMatchDifferentCompositionTypes) {
     mock::OutputLayer outputLayerOne;
-    mock::LayerFE layerFEOne;
+    sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateOne;
     LayerFECompositionState layerFECompositionStateOne;
     layerFECompositionStateOne.compositionType = Composition::DEVICE;
-    setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne,
+    setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
                        layerFECompositionStateOne);
     LayerState layerStateOne(&outputLayerOne);
 
     mock::OutputLayer outputLayerTwo;
-    mock::LayerFE layerFETwo;
+    sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo;
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.compositionType = Composition::SOLID_COLOR;
-    setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo,
+    setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
                        layerFECompositionStateTwo);
     LayerState layerStateTwo(&outputLayerTwo);
 
@@ -128,22 +128,22 @@
 
 TEST_F(LayerStackTest, getApproximateMatch_matchesSingleDifferenceInSingleLayer) {
     mock::OutputLayer outputLayerOne;
-    mock::LayerFE layerFEOne;
+    sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateOne{
             .sourceCrop = sFloatRectOne,
     };
     LayerFECompositionState layerFECompositionStateOne;
-    setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne,
+    setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
                        layerFECompositionStateOne);
     LayerState layerStateOne(&outputLayerOne);
 
     mock::OutputLayer outputLayerTwo;
-    mock::LayerFE layerFETwo;
+    sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo{
             .sourceCrop = sFloatRectTwo,
     };
     LayerFECompositionState layerFECompositionStateTwo;
-    setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo,
+    setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
                        layerFECompositionStateTwo);
     LayerState layerStateTwo(&outputLayerTwo);
 
@@ -159,22 +159,22 @@
 
 TEST_F(LayerStackTest, getApproximateMatch_matchesSingleDifferenceInMultiLayerStack) {
     mock::OutputLayer outputLayerOne;
-    mock::LayerFE layerFEOne;
+    sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateOne{
             .sourceCrop = sFloatRectOne,
     };
     LayerFECompositionState layerFECompositionStateOne;
-    setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne,
+    setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
                        layerFECompositionStateOne);
     LayerState layerStateOne(&outputLayerOne);
 
     mock::OutputLayer outputLayerTwo;
-    mock::LayerFE layerFETwo;
+    sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo{
             .sourceCrop = sFloatRectTwo,
     };
     LayerFECompositionState layerFECompositionStateTwo;
-    setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo,
+    setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
                        layerFECompositionStateTwo);
     LayerState layerStateTwo(&outputLayerTwo);
 
@@ -190,7 +190,7 @@
 
 TEST_F(LayerStackTest, getApproximateMatch_doesNotMatchManyDifferences) {
     mock::OutputLayer outputLayerOne;
-    mock::LayerFE layerFEOne;
+    sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateOne{
             .visibleRegion = sRegionOne,
             .displayFrame = sRectOne,
@@ -201,12 +201,12 @@
     layerFECompositionStateOne.alpha = sAlphaOne;
     layerFECompositionStateOne.colorTransformIsIdentity = true;
     layerFECompositionStateOne.blendMode = hal::BlendMode::NONE;
-    setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne,
+    setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
                        layerFECompositionStateOne);
     LayerState layerStateOne(&outputLayerOne);
 
     mock::OutputLayer outputLayerTwo;
-    mock::LayerFE layerFETwo;
+    sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo{
             .visibleRegion = sRegionTwo,
             .displayFrame = sRectTwo,
@@ -218,7 +218,7 @@
     layerFECompositionStateTwo.colorTransformIsIdentity = false;
     layerFECompositionStateTwo.colorTransform = sMat4One;
     layerFECompositionStateTwo.blendMode = hal::BlendMode::PREMULTIPLIED;
-    setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo,
+    setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
                        layerFECompositionStateTwo);
     LayerState layerStateTwo(&outputLayerTwo);
 
@@ -230,20 +230,20 @@
 TEST_F(LayerStackTest, getApproximateMatch_exactMatchesSameBuffer) {
     sp<GraphicBuffer> buffer = new GraphicBuffer();
     mock::OutputLayer outputLayerOne;
-    mock::LayerFE layerFEOne;
+    sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateOne;
     LayerFECompositionState layerFECompositionStateOne;
     layerFECompositionStateOne.buffer = buffer;
-    setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne,
+    setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
                        layerFECompositionStateOne);
     LayerState layerStateOne(&outputLayerOne);
 
     mock::OutputLayer outputLayerTwo;
-    mock::LayerFE layerFETwo;
+    sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo;
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.buffer = buffer;
-    setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo,
+    setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
                        layerFECompositionStateTwo);
     LayerState layerStateTwo(&outputLayerTwo);
 
@@ -259,7 +259,7 @@
 
 TEST_F(LayerStackTest, getApproximateMatch_alwaysMatchesClientComposition) {
     mock::OutputLayer outputLayerOne;
-    mock::LayerFE layerFEOne;
+    sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateOne{
             .visibleRegion = sRegionOne,
             .forceClientComposition = true,
@@ -271,12 +271,12 @@
     layerFECompositionStateOne.buffer = new GraphicBuffer();
     layerFECompositionStateOne.alpha = sAlphaOne;
     layerFECompositionStateOne.colorTransformIsIdentity = true;
-    setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne,
+    setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
                        layerFECompositionStateOne);
     LayerState layerStateOne(&outputLayerOne);
 
     mock::OutputLayer outputLayerTwo;
-    mock::LayerFE layerFETwo;
+    sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo{
             .visibleRegion = sRegionTwo,
             .forceClientComposition = true,
@@ -289,7 +289,7 @@
     layerFECompositionStateTwo.alpha = sAlphaTwo;
     layerFECompositionStateTwo.colorTransformIsIdentity = false;
     layerFECompositionStateTwo.colorTransform = sMat4One;
-    setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo,
+    setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
                        layerFECompositionStateTwo);
     LayerState layerStateTwo(&outputLayerTwo);
 
@@ -305,24 +305,24 @@
 
 TEST_F(LayerStackTest, getApproximateMatch_doesNotMatchMultipleApproximations) {
     mock::OutputLayer outputLayerOne;
-    mock::LayerFE layerFEOne;
+    sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateOne{
             .sourceCrop = sFloatRectOne,
     };
     LayerFECompositionState layerFECompositionStateOne;
     layerFECompositionStateOne.buffer = new GraphicBuffer();
-    setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne,
+    setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
                        layerFECompositionStateOne);
     LayerState layerStateOne(&outputLayerOne);
 
     mock::OutputLayer outputLayerTwo;
-    mock::LayerFE layerFETwo;
+    sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo{
             .sourceCrop = sFloatRectTwo,
     };
     LayerFECompositionState layerFECompositionStateTwo;
     layerFECompositionStateTwo.buffer = new GraphicBuffer();
-    setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo,
+    setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
                        layerFECompositionStateTwo);
     LayerState layerStateTwo(&outputLayerTwo);
 
@@ -348,22 +348,22 @@
 
 TEST_F(LayerStackTest, reorderingChangesNonBufferHash) {
     mock::OutputLayer outputLayerOne;
-    mock::LayerFE layerFEOne;
+    sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateOne{
             .sourceCrop = sFloatRectOne,
     };
     LayerFECompositionState layerFECompositionStateOne;
-    setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne,
+    setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
                        layerFECompositionStateOne);
     LayerState layerStateOne(&outputLayerOne);
 
     mock::OutputLayer outputLayerTwo;
-    mock::LayerFE layerFETwo;
+    sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo{
             .sourceCrop = sFloatRectTwo,
     };
     LayerFECompositionState layerFECompositionStateTwo;
-    setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo,
+    setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
                        layerFECompositionStateTwo);
     LayerState layerStateTwo(&outputLayerTwo);
 
@@ -443,11 +443,11 @@
 
 TEST_F(PredictorTest, getPredictedPlan_recordCandidateAndRetrieveExactMatch) {
     mock::OutputLayer outputLayerOne;
-    mock::LayerFE layerFEOne;
+    sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateOne;
     LayerFECompositionState layerFECompositionStateOne;
     layerFECompositionStateOne.compositionType = Composition::DEVICE;
-    setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne,
+    setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
                        layerFECompositionStateOne);
     LayerState layerStateOne(&outputLayerOne);
 
@@ -468,22 +468,22 @@
 
 TEST_F(PredictorTest, getPredictedPlan_recordCandidateAndRetrieveApproximateMatch) {
     mock::OutputLayer outputLayerOne;
-    mock::LayerFE layerFEOne;
+    sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateOne{
             .sourceCrop = sFloatRectOne,
     };
     LayerFECompositionState layerFECompositionStateOne;
-    setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne,
+    setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
                        layerFECompositionStateOne);
     LayerState layerStateOne(&outputLayerOne);
 
     mock::OutputLayer outputLayerTwo;
-    mock::LayerFE layerFETwo;
+    sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo{
             .sourceCrop = sFloatRectTwo,
     };
     LayerFECompositionState layerFECompositionStateTwo;
-    setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo,
+    setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
                        layerFECompositionStateTwo);
     LayerState layerStateTwo(&outputLayerTwo);
 
@@ -505,22 +505,22 @@
 
 TEST_F(PredictorTest, recordMissedPlan_skipsApproximateMatch) {
     mock::OutputLayer outputLayerOne;
-    mock::LayerFE layerFEOne;
+    sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateOne{
             .sourceCrop = sFloatRectOne,
     };
     LayerFECompositionState layerFECompositionStateOne;
-    setupMocksForLayer(outputLayerOne, layerFEOne, outputLayerCompositionStateOne,
+    setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
                        layerFECompositionStateOne);
     LayerState layerStateOne(&outputLayerOne);
 
     mock::OutputLayer outputLayerTwo;
-    mock::LayerFE layerFETwo;
+    sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
     OutputLayerCompositionState outputLayerCompositionStateTwo{
             .sourceCrop = sFloatRectTwo,
     };
     LayerFECompositionState layerFECompositionStateTwo;
-    setupMocksForLayer(outputLayerTwo, layerFETwo, outputLayerCompositionStateTwo,
+    setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
                        layerFECompositionStateTwo);
     LayerState layerStateTwo(&outputLayerTwo);
 
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 9174ec7..2696bd8 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -772,18 +772,16 @@
     return NO_ERROR;
 }
 
-hal::HWConfigId HWComposer::getPreferredBootDisplayMode(PhysicalDisplayId displayId) {
-    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
-    hal::HWConfigId displayModeId = -1;
+std::optional<hal::HWConfigId> HWComposer::getPreferredBootDisplayMode(
+        PhysicalDisplayId displayId) {
+    RETURN_IF_INVALID_DISPLAY(displayId, std::nullopt);
+    hal::HWConfigId displayModeId;
     const auto error =
             mDisplayData[displayId].hwcDisplay->getPreferredBootDisplayConfig(&displayModeId);
-    if (error == hal::Error::UNSUPPORTED) {
-        RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
+    if (error != hal::Error::NONE) {
+        LOG_DISPLAY_ERROR(displayId, to_string(error).c_str());
+        return std::nullopt;
     }
-    if (error == hal::Error::BAD_PARAMETER) {
-        RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
-    }
-    RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
     return displayModeId;
 }
 
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 3e68028..29335d5 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -260,7 +260,7 @@
     virtual bool getBootDisplayModeSupport() = 0;
     virtual status_t setBootDisplayMode(PhysicalDisplayId, hal::HWConfigId) = 0;
     virtual status_t clearBootDisplayMode(PhysicalDisplayId) = 0;
-    virtual hal::HWConfigId getPreferredBootDisplayMode(PhysicalDisplayId) = 0;
+    virtual std::optional<hal::HWConfigId> getPreferredBootDisplayMode(PhysicalDisplayId) = 0;
 };
 
 namespace impl {
@@ -391,7 +391,7 @@
     bool getBootDisplayModeSupport() override;
     status_t setBootDisplayMode(PhysicalDisplayId, hal::HWConfigId) override;
     status_t clearBootDisplayMode(PhysicalDisplayId) override;
-    hal::HWConfigId getPreferredBootDisplayMode(PhysicalDisplayId) override;
+    std::optional<hal::HWConfigId> getPreferredBootDisplayMode(PhysicalDisplayId) override;
 
     // for debugging ----------------------------------------------------------
     void dump(std::string& out) const override;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 61da45d..3459a8f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2523,6 +2523,7 @@
     mTimeStats->recordDisplayEventConnectionCount(sfConnections + appConnections);
 
     if (isDisplayConnected && !display->isPoweredOn()) {
+        getRenderEngine().cleanupPostRender();
         return;
     }