Merge "Harder failures for lazy service clients."
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 5e87faf..1c4c980 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -374,6 +374,14 @@
         bool skip_compilation = vold_decrypt == "trigger_restart_min_framework" ||
                                 vold_decrypt == "1";
 
+        std::string updatable_bcp_packages =
+            MapPropertyToArg("dalvik.vm.dex2oat-updatable-bcp-packages-file",
+                             "--updatable-bcp-packages-file=%s");
+        if (updatable_bcp_packages.empty()) {
+          // Make dex2oat fail by providing non-existent file name.
+          updatable_bcp_packages = "--updatable-bcp-packages-file=/nonx/updatable-bcp-packages.txt";
+        }
+
         std::string resolve_startup_string_arg =
                 MapPropertyToArg("persist.device_config.runtime.dex2oat_resolve_startup_strings",
                                  "--resolve-startup-const-strings=%s");
@@ -520,6 +528,7 @@
         AddRuntimeArg(dex2oat_Xms_arg);
         AddRuntimeArg(dex2oat_Xmx_arg);
 
+        AddArg(updatable_bcp_packages);
         AddArg(resolve_startup_string_arg);
         AddArg(image_block_size_arg);
         AddArg(dex2oat_compiler_filter_arg);
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 3ee8187..c7b7551 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -40,7 +40,7 @@
     },
 
     srcs: ["binderDriverInterfaceTest.cpp"],
-    test_suites: ["device-tests", "vts-core"],
+    test_suites: ["device-tests", "vts"],
 }
 
 cc_test {
@@ -69,7 +69,7 @@
         "libbinder",
         "libutils",
     ],
-    test_suites: ["device-tests", "vts-core"],
+    test_suites: ["device-tests", "vts"],
     require_root: true,
 }
 
@@ -131,7 +131,7 @@
         "liblog",
         "libutils",
     ],
-    test_suites: ["device-tests", "vts-core"],
+    test_suites: ["device-tests", "vts"],
     require_root: true,
 }
 
diff --git a/services/inputflinger/InputClassifier.cpp b/services/inputflinger/InputClassifier.cpp
index ef1a224..6e51fb2 100644
--- a/services/inputflinger/InputClassifier.cpp
+++ b/services/inputflinger/InputClassifier.cpp
@@ -46,8 +46,6 @@
 
 namespace android {
 
-static constexpr bool DEBUG = false;
-
 // Category (=namespace) name for the input settings that are applied at boot time
 static const char* INPUT_NATIVE_BOOT = "input_native_boot";
 // Feature flag name for the deep press feature
@@ -141,53 +139,46 @@
 
 // --- MotionClassifier ---
 
-MotionClassifier::MotionClassifier(sp<android::hardware::hidl_death_recipient> deathRecipient) :
-        mDeathRecipient(deathRecipient), mEvents(MAX_EVENTS) {
-    mHalThread = std::thread(&MotionClassifier::callInputClassifierHal, this);
-#if defined(__linux__)
-    // Set the thread name for debugging
-    pthread_setname_np(mHalThread.native_handle(), "InputClassifier");
-#endif
-}
-
-/**
- * This function may block for some time to initialize the HAL, so it should only be called
- * from the "InputClassifier HAL" thread.
- */
-bool MotionClassifier::init() {
-    ensureHalThread(__func__);
-    sp<android::hardware::input::classifier::V1_0::IInputClassifier> service =
-            classifier::V1_0::IInputClassifier::getService();
-    if (!service) {
-        // Not really an error, maybe the device does not have this HAL,
-        // but somehow the feature flag is flipped
-        ALOGI("Could not obtain InputClassifier HAL");
-        return false;
-    }
-
-    sp<android::hardware::hidl_death_recipient> recipient = mDeathRecipient.promote();
-    if (recipient != nullptr) {
-        const bool linked = service->linkToDeath(recipient, 0 /* cookie */).withDefault(false);
-        if (!linked) {
-            ALOGE("Could not link MotionClassifier to the HAL death");
-            return false;
-        }
-    }
-
+MotionClassifier::MotionClassifier(
+        sp<android::hardware::input::classifier::V1_0::IInputClassifier> service)
+      : mEvents(MAX_EVENTS), mService(service) {
     // Under normal operation, we do not need to reset the HAL here. But in the case where system
     // crashed, but HAL didn't, we may be connecting to an existing HAL process that might already
     // have received events in the past. That means, that HAL could be in an inconsistent state
     // once it receives events from the newly created MotionClassifier.
     mEvents.push(ClassifierEvent::createHalResetEvent());
 
-    {
-        std::scoped_lock lock(mLock);
-        if (mService) {
-            ALOGE("MotionClassifier::%s should only be called once", __func__);
-        }
-        mService = service;
+    mHalThread = std::thread(&MotionClassifier::processEvents, this);
+#if defined(__linux__)
+    // Set the thread name for debugging
+    pthread_setname_np(mHalThread.native_handle(), "InputClassifier");
+#endif
+}
+
+std::unique_ptr<MotionClassifierInterface> MotionClassifier::create(
+        sp<android::hardware::hidl_death_recipient> deathRecipient) {
+    if (!deepPressEnabled()) {
+        // If feature is not enabled, MotionClassifier should stay null to avoid unnecessary work.
+        // When MotionClassifier is null, InputClassifier will forward all events
+        // to the next InputListener, unmodified.
+        return nullptr;
     }
-    return true;
+    sp<android::hardware::input::classifier::V1_0::IInputClassifier> service =
+            classifier::V1_0::IInputClassifier::getService();
+    if (!service) {
+        // Not really an error, maybe the device does not have this HAL,
+        // but somehow the feature flag is flipped
+        ALOGI("Could not obtain InputClassifier HAL");
+        return nullptr;
+    }
+
+    const bool linked = service->linkToDeath(deathRecipient, 0 /* cookie */).withDefault(false);
+    if (!linked) {
+        ALOGE("Could not link death recipient to the HAL death");
+        return nullptr;
+    }
+    // Using 'new' to access a non-public constructor
+    return std::unique_ptr<MotionClassifier>(new MotionClassifier(service));
 }
 
 MotionClassifier::~MotionClassifier() {
@@ -195,14 +186,6 @@
     mHalThread.join();
 }
 
-void MotionClassifier::ensureHalThread(const char* function) {
-    if (DEBUG) {
-        if (std::this_thread::get_id() != mHalThread.get_id()) {
-            LOG_FATAL("Function %s should only be called from InputClassifier thread", function);
-        }
-    }
-}
-
 /**
  * Obtain the classification from the HAL for a given MotionEvent.
  * Should only be called from the InputClassifier thread (mHalThread).
@@ -213,23 +196,7 @@
  * To remove any possibility of negatively affecting the touch latency, the HAL
  * is called from a dedicated thread.
  */
-void MotionClassifier::callInputClassifierHal() {
-    ensureHalThread(__func__);
-    const bool initialized = init();
-    if (!initialized) {
-        // MotionClassifier no longer useful.
-        // Deliver death notification from a separate thread
-        // because ~MotionClassifier may be invoked, which calls mHalThread.join()
-        std::thread([deathRecipient = mDeathRecipient](){
-                sp<android::hardware::hidl_death_recipient> recipient = deathRecipient.promote();
-                if (recipient != nullptr) {
-                    recipient->serviceDied(0 /*cookie*/, nullptr);
-                }
-        }).detach();
-        return;
-    }
-    // From this point on, mService is guaranteed to be non-null.
-
+void MotionClassifier::processEvents() {
     while (true) {
         ClassifierEvent event = mEvents.pop();
         bool halResponseOk = true;
@@ -383,24 +350,30 @@
     }
 }
 
+// --- HalDeathRecipient
+
+InputClassifier::HalDeathRecipient::HalDeathRecipient(InputClassifier& parent) : mParent(parent) {}
+
+void InputClassifier::HalDeathRecipient::serviceDied(
+        uint64_t cookie, const wp<android::hidl::base::V1_0::IBase>& who) {
+    sp<android::hidl::base::V1_0::IBase> service = who.promote();
+    if (service) {
+        service->unlinkToDeath(this);
+    }
+    mParent.setMotionClassifier(nullptr);
+}
 
 // --- InputClassifier ---
 
-InputClassifier::InputClassifier(const sp<InputListenerInterface>& listener) :
-        mListener(listener) {
-    // The rest of the initialization is done in onFirstRef, because we need to obtain
-    // an sp to 'this' in order to register for HAL death notifications
-}
-
-void InputClassifier::onFirstRef() {
-    if (!deepPressEnabled()) {
-        // If feature is not enabled, MotionClassifier should stay null to avoid unnecessary work.
-        // When MotionClassifier is null, InputClassifier will forward all events
-        // to the next InputListener, unmodified.
-        return;
-    }
-    std::scoped_lock lock(mLock);
-    mMotionClassifier = std::make_unique<MotionClassifier>(this);
+InputClassifier::InputClassifier(const sp<InputListenerInterface>& listener)
+      : mListener(listener), mHalDeathRecipient(new HalDeathRecipient(*this)) {
+    mInitializeMotionClassifierThread = std::thread(
+            [this] { setMotionClassifier(MotionClassifier::create(mHalDeathRecipient)); });
+#if defined(__linux__)
+    // Set the thread name for debugging
+    pthread_setname_np(mInitializeMotionClassifierThread.native_handle(),
+                       "Create MotionClassifier");
+#endif
 }
 
 void InputClassifier::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
@@ -441,15 +414,10 @@
     mListener->notifyDeviceReset(args);
 }
 
-void InputClassifier::serviceDied(uint64_t /*cookie*/,
-        const wp<android::hidl::base::V1_0::IBase>& who) {
+void InputClassifier::setMotionClassifier(
+        std::unique_ptr<MotionClassifierInterface> motionClassifier) {
     std::scoped_lock lock(mLock);
-    ALOGE("InputClassifier HAL has died. Setting mMotionClassifier to null");
-    mMotionClassifier = nullptr;
-    sp<android::hidl::base::V1_0::IBase> service = who.promote();
-    if (service) {
-        service->unlinkToDeath(this);
-    }
+    mMotionClassifier = std::move(motionClassifier);
 }
 
 void InputClassifier::dump(std::string& dump) {
@@ -465,4 +433,8 @@
     dump += "\n";
 }
 
+InputClassifier::~InputClassifier() {
+    mInitializeMotionClassifierThread.join();
+}
+
 } // namespace android
diff --git a/services/inputflinger/InputClassifier.h b/services/inputflinger/InputClassifier.h
index 47e20db..b1769b9 100644
--- a/services/inputflinger/InputClassifier.h
+++ b/services/inputflinger/InputClassifier.h
@@ -19,8 +19,8 @@
 
 #include <android-base/thread_annotations.h>
 #include <utils/RefBase.h>
-#include <unordered_map>
 #include <thread>
+#include <unordered_map>
 
 #include "BlockingQueue.h"
 #include "InputListener.h"
@@ -113,23 +113,23 @@
  */
 class MotionClassifier final : public MotionClassifierInterface {
 public:
-    /**
-     * The deathRecipient will be subscribed to the HAL death. If the death recipient
-     * owns MotionClassifier and receives HAL death, it should delete its copy of it.
-     * The callback serviceDied will also be sent if the MotionClassifier itself fails
-     * to initialize. If the MotionClassifier fails to initialize, it is not useful, and
-     * should be deleted.
-     * If no death recipient is supplied, then the registration step will be skipped, so there will
-     * be no listeners registered for the HAL death. This is useful for testing
-     * MotionClassifier in isolation.
+    /*
+     * Create an instance of MotionClassifier.
+     * The death recipient, if provided, will be subscribed to the HAL death.
+     * The death recipient could be used to destroy MotionClassifier.
+     *
+     * This function should be called asynchronously, because getService takes a long time.
      */
-    explicit MotionClassifier(sp<android::hardware::hidl_death_recipient> deathRecipient = nullptr);
+    static std::unique_ptr<MotionClassifierInterface> create(
+            sp<android::hardware::hidl_death_recipient> deathRecipient);
+
     ~MotionClassifier();
 
     /**
      * Classifies events asynchronously; that is, it doesn't block events on a classification,
-     * but instead sends them over to the classifier HAL and after a classification is
-     * determined, it then marks the next event it sees in the stream with it.
+     * but instead sends them over to the classifier HAL. After a classification of a specific
+     * event is determined, MotionClassifier then marks the next event in the stream with this
+     * classification.
      *
      * Therefore, it is acceptable to have the classifications be delayed by 1-2 events
      * in a particular gesture.
@@ -141,15 +141,9 @@
     virtual void dump(std::string& dump) override;
 
 private:
-    /**
-     * Initialize MotionClassifier.
-     * Return true if initializaion is successful.
-     */
-    bool init();
-    /**
-     * Entity that will be notified of the HAL death (most likely InputClassifier).
-     */
-    wp<android::hardware::hidl_death_recipient> mDeathRecipient;
+    friend class MotionClassifierTest; // to create MotionClassifier with a test HAL implementation
+    explicit MotionClassifier(
+            sp<android::hardware::input::classifier::V1_0::IInputClassifier> service);
 
     // The events that need to be sent to the HAL.
     BlockingQueue<ClassifierEvent> mEvents;
@@ -164,14 +158,9 @@
      */
     std::thread mHalThread;
     /**
-     * Print an error message if the caller is not on the InputClassifier thread.
-     * Caller must supply the name of the calling function as __func__
+     * Process events and call the InputClassifier HAL
      */
-    void ensureHalThread(const char* function);
-    /**
-     * Call the InputClassifier HAL
-     */
-    void callInputClassifierHal();
+    void processEvents();
     /**
      * Access to the InputClassifier HAL. May be null if init() hasn't completed yet.
      * When init() successfully completes, mService is guaranteed to remain non-null and to not
@@ -223,19 +212,15 @@
     const char* getServiceStatus() REQUIRES(mLock);
 };
 
-
 /**
  * Implementation of the InputClassifierInterface.
  * Represents a separate stage of input processing. All of the input events go through this stage.
  * Acts as a passthrough for all input events except for motion events.
  * The events of motion type are sent to MotionClassifier.
  */
-class InputClassifier : public InputClassifierInterface,
-        public android::hardware::hidl_death_recipient {
+class InputClassifier : public InputClassifierInterface {
 public:
     explicit InputClassifier(const sp<InputListenerInterface>& listener);
-    // Some of the constructor logic is finished in onFirstRef
-    virtual void onFirstRef() override;
 
     virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) override;
     virtual void notifyKey(const NotifyKeyArgs* args) override;
@@ -243,17 +228,44 @@
     virtual void notifySwitch(const NotifySwitchArgs* args) override;
     virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) override;
 
-    virtual void serviceDied(uint64_t cookie,
-            const wp<android::hidl::base::V1_0::IBase>& who) override;
-
     virtual void dump(std::string& dump) override;
 
+    ~InputClassifier();
+
 private:
     // Protect access to mMotionClassifier, since it may become null via a hidl callback
     std::mutex mLock;
-    std::unique_ptr<MotionClassifierInterface> mMotionClassifier GUARDED_BY(mLock);
     // The next stage to pass input events to
     sp<InputListenerInterface> mListener;
+
+    std::unique_ptr<MotionClassifierInterface> mMotionClassifier GUARDED_BY(mLock);
+    std::thread mInitializeMotionClassifierThread;
+    /**
+     * Set the value of mMotionClassifier.
+     * This is called from 2 different threads:
+     * 1) mInitializeMotionClassifierThread, when we have constructed a MotionClassifier
+     * 2) A binder thread of the HalDeathRecipient, which is created when HAL dies. This would cause
+     *    mMotionClassifier to become nullptr.
+     */
+    void setMotionClassifier(std::unique_ptr<MotionClassifierInterface> motionClassifier);
+
+    /**
+     * The deathRecipient will call setMotionClassifier(null) when the HAL dies.
+     */
+    class HalDeathRecipient : public android::hardware::hidl_death_recipient {
+    public:
+        explicit HalDeathRecipient(InputClassifier& parent);
+        virtual void serviceDied(uint64_t cookie,
+                                 const wp<android::hidl::base::V1_0::IBase>& who) override;
+
+    private:
+        InputClassifier& mParent;
+    };
+    // We retain a reference to death recipient, because the death recipient will be calling
+    // ~MotionClassifier if the HAL dies.
+    // If we don't retain a reference, and MotionClassifier is the only owner of the death
+    // recipient, the serviceDied call will cause death recipient to call its own destructor.
+    sp<HalDeathRecipient> mHalDeathRecipient;
 };
 
 } // namespace android
diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp
index c4f8626..21ed7ce 100644
--- a/services/inputflinger/tests/Android.bp
+++ b/services/inputflinger/tests/Android.bp
@@ -25,6 +25,7 @@
         "libutils",
         "libhardware",
         "libhardware_legacy",
+        "libhidlbase",
         "libui",
         "libinput",
         "libinputflinger",
diff --git a/services/inputflinger/tests/InputClassifier_test.cpp b/services/inputflinger/tests/InputClassifier_test.cpp
index 7cc17a2..9121d7e 100644
--- a/services/inputflinger/tests/InputClassifier_test.cpp
+++ b/services/inputflinger/tests/InputClassifier_test.cpp
@@ -22,6 +22,9 @@
 #include <android/hardware/input/classifier/1.0/IInputClassifier.h>
 
 using namespace android::hardware::input;
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::input::common::V1_0::Classification;
 
 namespace android {
 
@@ -129,6 +132,27 @@
     ASSERT_EQ(args, outArgs);
 }
 
+/**
+ * A minimal implementation of IInputClassifier.
+ */
+struct TestHal : public android::hardware::input::classifier::V1_0::IInputClassifier {
+    Return<Classification> classify(
+            const android::hardware::input::common::V1_0::MotionEvent& event) override {
+        return Classification::NONE;
+    };
+    Return<void> reset() override { return Void(); };
+    Return<void> resetDevice(int32_t deviceId) override { return Void(); };
+};
+
+/**
+ * An entity that will be subscribed to the HAL death.
+ */
+class TestDeathRecipient : public android::hardware::hidl_death_recipient {
+public:
+    virtual void serviceDied(uint64_t cookie,
+                             const wp<android::hidl::base::V1_0::IBase>& who) override{};
+};
+
 // --- MotionClassifierTest ---
 
 class MotionClassifierTest : public testing::Test {
@@ -136,7 +160,14 @@
     std::unique_ptr<MotionClassifierInterface> mMotionClassifier;
 
     virtual void SetUp() override {
-        mMotionClassifier = std::make_unique<MotionClassifier>();
+        mMotionClassifier = MotionClassifier::create(new TestDeathRecipient());
+        if (mMotionClassifier == nullptr) {
+            // If the device running this test does not have IInputClassifier service,
+            // use the test HAL instead.
+            // Using 'new' to access non-public constructor
+            mMotionClassifier =
+                    std::unique_ptr<MotionClassifier>(new MotionClassifier(new TestHal()));
+        }
     }
 };
 
diff --git a/services/sensorservice/hidl/Android.bp b/services/sensorservice/hidl/Android.bp
index d0c83d6..0e1af59 100644
--- a/services/sensorservice/hidl/Android.bp
+++ b/services/sensorservice/hidl/Android.bp
@@ -10,6 +10,7 @@
         "-Wall",
         "-Werror",
     ],
+    header_libs: ["jni_headers"],
     shared_libs: [
         "libbase",
         "libhidlbase",
@@ -24,6 +25,7 @@
     export_include_dirs: [
         "include/"
     ],
+    export_header_lib_headers: ["jni_headers"],
     local_include_dirs: [
         "include/sensorservicehidl/"
     ]
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index f51fbb4..4517eff 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -250,7 +250,14 @@
     // pixel format is HDR Y410 masquerading as RGBA_1010102
     return (mCurrentDataSpace == ui::Dataspace::BT2020_ITU_PQ &&
             getDrawingApi() == NATIVE_WINDOW_API_MEDIA &&
-            mActiveBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102);
+            getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102);
+}
+
+PixelFormat BufferLayer::getPixelFormat() const {
+    if (!mActiveBuffer) {
+        return PIXEL_FORMAT_NONE;
+    }
+    return mActiveBuffer->format;
 }
 
 void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice,
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index 46a62ed..6828938 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -127,7 +127,6 @@
     virtual Region getDrawingSurfaceDamage() const = 0;
     virtual const HdrMetadata& getDrawingHdrMetadata() const = 0;
     virtual int getDrawingApi() const = 0;
-    virtual PixelFormat getPixelFormat() const = 0;
 
     virtual uint64_t getFrameNumber() const = 0;
 
@@ -191,6 +190,8 @@
     std::shared_ptr<compositionengine::Layer> mCompositionLayer;
 
     FloatRect computeSourceBounds(const FloatRect& parentBounds) const override;
+
+    PixelFormat getPixelFormat() const;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index cbb9d65..dd79d82 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -192,10 +192,6 @@
     return mConsumer->getCurrentApi();
 }
 
-PixelFormat BufferQueueLayer::getPixelFormat() const {
-    return mFormat;
-}
-
 uint64_t BufferQueueLayer::getFrameNumber() const {
     Mutex::Autolock lock(mQueueItemLock);
     uint64_t frameNumber = mQueueItems[0].mFrameNumber;
@@ -561,8 +557,6 @@
         return BAD_VALUE;
     }
 
-    mFormat = format;
-
     setDefaultBufferSize(w, h);
     mConsumer->setDefaultBufferFormat(format);
     mConsumer->setConsumerUsageBits(getEffectiveUsage(0));
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index 7def33a..2675643 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -75,7 +75,6 @@
     Region getDrawingSurfaceDamage() const override;
     const HdrMetadata& getDrawingHdrMetadata() const override;
     int getDrawingApi() const override;
-    PixelFormat getPixelFormat() const override;
 
     uint64_t getFrameNumber() const override;
 
@@ -119,8 +118,6 @@
     sp<BufferLayerConsumer> mConsumer;
     sp<IGraphicBufferProducer> mProducer;
 
-    PixelFormat mFormat{PIXEL_FORMAT_NONE};
-
     // Only accessed on the main thread.
     uint64_t mPreviousFrameNumber{0};
     bool mUpdateTexImageFailed{false};
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 63a07c3..de5d622 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -449,13 +449,6 @@
     return getDrawingState().api;
 }
 
-PixelFormat BufferStateLayer::getPixelFormat() const {
-    if (!mActiveBuffer) {
-        return PIXEL_FORMAT_NONE;
-    }
-    return mActiveBuffer->format;
-}
-
 uint64_t BufferStateLayer::getFrameNumber() const {
     return mFrameNumber;
 }
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 97e24cb..2b52102 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -116,7 +116,6 @@
     Region getDrawingSurfaceDamage() const override;
     const HdrMetadata& getDrawingHdrMetadata() const override;
     int getDrawingApi() const override;
-    PixelFormat getPixelFormat() const override;
 
     uint64_t getFrameNumber() const override;
 
diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
index d3381e5..973d20c 100644
--- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp
+++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
@@ -302,7 +302,7 @@
     StringAppendF(&result, "isProtected=%1d, ", isProtected);
     StringAppendF(&result, "isOpaque=%1d, invalidate=%1d, ", isOpaque, invalidate);
     StringAppendF(&result, "dataspace=%s, ", dataspace.c_str());
-    StringAppendF(&result, "defaultPixelFormat=%s, ", pixelFormat.c_str());
+    StringAppendF(&result, "pixelFormat=%s, ", pixelFormat.c_str());
     StringAppendF(&result, "color=(%.3f,%.3f,%.3f,%.3f), flags=0x%08x, ",
                   static_cast<double>(color.r), static_cast<double>(color.g),
                   static_cast<double>(color.b), static_cast<double>(color.a), flags);
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index c93e15e..71016db 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -356,9 +356,9 @@
 
     virtual sp<SurfaceControl> createLayer(const sp<SurfaceComposerClient>& client,
                                            const char* name, uint32_t width, uint32_t height,
-                                           uint32_t flags = 0, SurfaceControl* parent = nullptr) {
-        auto layer =
-                createSurface(client, name, width, height, PIXEL_FORMAT_RGBA_8888, flags, parent);
+                                           uint32_t flags = 0, SurfaceControl* parent = nullptr,
+                                           PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
+        auto layer = createSurface(client, name, width, height, format, flags, parent);
 
         Transaction t;
         t.setLayerStack(layer, mDisplayLayerStack).setLayer(layer, mLayerZBase);
@@ -382,8 +382,9 @@
     }
 
     virtual sp<SurfaceControl> createLayer(const char* name, uint32_t width, uint32_t height,
-                                           uint32_t flags = 0, SurfaceControl* parent = nullptr) {
-        return createLayer(mClient, name, width, height, flags, parent);
+                                           uint32_t flags = 0, SurfaceControl* parent = nullptr,
+                                           PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
+        return createLayer(mClient, name, width, height, flags, parent, format);
     }
 
     sp<SurfaceControl> createColorLayer(const char* name, const Color& color,
@@ -644,12 +645,14 @@
     LayerTypeTransactionHarness(uint32_t layerType) : mLayerType(layerType) {}
 
     sp<SurfaceControl> createLayer(const char* name, uint32_t width, uint32_t height,
-                                   uint32_t flags = 0, SurfaceControl* parent = nullptr) {
+                                   uint32_t flags = 0, SurfaceControl* parent = nullptr,
+                                   PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
         // if the flags already have a layer type specified, return an error
         if (flags & ISurfaceComposerClient::eFXSurfaceMask) {
             return nullptr;
         }
-        return LayerTransactionTest::createLayer(name, width, height, flags | mLayerType, parent);
+        return LayerTransactionTest::createLayer(name, width, height, flags | mLayerType, parent,
+                                                 format);
     }
 
     void fillLayerColor(const sp<SurfaceControl>& layer, const Color& color, int32_t bufferWidth,
@@ -1946,6 +1949,65 @@
     }
 }
 
+TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBufferFormat) {
+    int32_t width = 100;
+    int32_t height = 100;
+    Rect crop = Rect(0, 0, width, height);
+
+    sp<SurfaceControl> behindLayer = createColorLayer("Behind layer", Color::RED);
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(
+            layer = createLayer("test", width, height, 0, nullptr, PIXEL_FORMAT_RGBX_8888));
+
+    Transaction()
+            .setLayer(layer, INT32_MAX - 1)
+            .show(layer)
+            .setLayerStack(behindLayer, mDisplayLayerStack)
+            .setCrop_legacy(behindLayer, crop)
+            .setLayer(behindLayer, INT32_MAX - 2)
+            .show(behindLayer)
+            .apply();
+
+    sp<Surface> surface = layer->getSurface();
+
+    sp<GraphicBuffer> buffer =
+            new GraphicBuffer(width, height, PIXEL_FORMAT_RGBX_8888, 1,
+                              BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
+                                      BufferUsage::COMPOSER_OVERLAY,
+                              "test");
+    ASSERT_NO_FATAL_FAILURE(fillGraphicBufferColor(buffer, crop, Color::TRANSPARENT));
+
+    if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) {
+        Surface::attachAndQueueBufferWithDataspace(surface.get(), buffer, ui::Dataspace::V0_SRGB);
+    } else {
+        Transaction().setBuffer(layer, buffer).apply();
+    }
+
+    {
+        SCOPED_TRACE("Buffer Opaque Format");
+        auto shot = screenshot();
+        shot->expectColor(crop, Color::BLACK);
+    }
+
+    buffer = new GraphicBuffer(width, height, PIXEL_FORMAT_RGBA_8888, 1,
+                               BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
+                                       BufferUsage::COMPOSER_OVERLAY,
+                               "test");
+    ASSERT_NO_FATAL_FAILURE(fillGraphicBufferColor(buffer, crop, Color::TRANSPARENT));
+
+    if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) {
+        Surface::attachAndQueueBufferWithDataspace(surface.get(), buffer, ui::Dataspace::V0_SRGB);
+    } else {
+        Transaction().setBuffer(layer, buffer).apply();
+    }
+
+    {
+        SCOPED_TRACE("Buffer Transparent Format");
+        auto shot = screenshot();
+        shot->expectColor(crop, Color::RED);
+    }
+}
+
 TEST_P(LayerRenderTypeTransactionTest, SetMatrixBasic_BufferQueue) {
     sp<SurfaceControl> layer;
     ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));