Merge "Measure total time in state"
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index a1ee285..9c5b883 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -227,7 +227,6 @@
 static const std::string DUMP_HALS_TASK = "DUMP HALS";
 static const std::string DUMP_BOARD_TASK = "dumpstate_board()";
 static const std::string DUMP_CHECKINS_TASK = "DUMP CHECKINS";
-static const std::string DUMP_APP_INFOS_TASK = "DUMP APP INFOS";
 
 namespace android {
 namespace os {
@@ -1576,7 +1575,6 @@
         ds.dump_pool_->enqueueTask(DUMP_INCIDENT_REPORT_TASK, &DumpIncidentReport);
         ds.dump_pool_->enqueueTaskWithFd(DUMP_BOARD_TASK, &Dumpstate::DumpstateBoard, &ds, _1);
         ds.dump_pool_->enqueueTaskWithFd(DUMP_CHECKINS_TASK, &DumpCheckins, _1);
-        ds.dump_pool_->enqueueTaskWithFd(DUMP_APP_INFOS_TASK, &DumpAppInfos, _1);
     }
 
     // Dump various things. Note that anything that takes "long" (i.e. several seconds) should
@@ -1729,11 +1727,7 @@
         RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK_AND_LOG(DUMP_CHECKINS_TASK, DumpCheckins);
     }
 
-    if (ds.dump_pool_) {
-        WAIT_TASK_WITH_CONSENT_CHECK(DUMP_APP_INFOS_TASK, ds.dump_pool_);
-    } else {
-        RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK_AND_LOG(DUMP_APP_INFOS_TASK, DumpAppInfos);
-    }
+    RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK(DumpAppInfos);
 
     printf("========================================================\n");
     printf("== Dropbox crashes\n");
diff --git a/cmds/dumpsys/dumpsys.cpp b/cmds/dumpsys/dumpsys.cpp
index 1327cfd..a017246 100644
--- a/cmds/dumpsys/dumpsys.cpp
+++ b/cmds/dumpsys/dumpsys.cpp
@@ -427,7 +427,7 @@
                  << strerror(errno) << std::endl;
             status = -errno;
             break;
-        } else if (rc == 0) {
+        } else if (rc == 0 || time_left_ms() == 0) {
             status = TIMED_OUT;
             break;
         }
diff --git a/libs/adbd_auth/adbd_auth.cpp b/libs/adbd_auth/adbd_auth.cpp
index dae6eeb..15bd5c3 100644
--- a/libs/adbd_auth/adbd_auth.cpp
+++ b/libs/adbd_auth/adbd_auth.cpp
@@ -282,9 +282,8 @@
             LOG(FATAL) << "adbd_auth: unhandled packet type?";
         }
 
-        output_queue_.pop_front();
-
         ssize_t rc = writev(framework_fd_.get(), iovs, iovcnt);
+        output_queue_.pop_front();
         if (rc == -1 && errno != EAGAIN && errno != EWOULDBLOCK) {
             PLOG(ERROR) << "adbd_auth: failed to write to framework fd";
             ReplaceFrameworkFd(unique_fd());
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 9bba369..8087443 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -1477,6 +1477,31 @@
     goto data_sorted;
 }
 
+status_t Parcel::readVectorSizeWithCoarseBoundCheck(int32_t *size) const {
+    int32_t requestedSize;
+    const status_t status = readInt32(&requestedSize);
+    if (status != NO_ERROR) return status;
+
+    // We permit negative sizes, which indicate presence of a nullable vector,
+    // i.e. a vector embedded in std::optional, std::unique_ptr, or std::shared_ptr.
+    if (requestedSize > 0) {
+        // Check if there are fewer bytes than vector elements.
+        // A lower bound is 1 byte per element, satisfied by some enum and int8_t and uint8_t.
+        const size_t availableBytes = dataAvail();
+        if (static_cast<size_t>(requestedSize) > availableBytes) {
+            // We have a size that is greater than the number of bytes available.
+            // On bounds failure we do not 'rewind' position by 4 bytes of the size already read.
+            ALOGW("%s: rejecting out of bounds vector size (requestedSize):%d "
+                    "Parcel{dataAvail:%zu mDataSize:%zu mDataPos:%zu mDataCapacity:%zu}",
+                    __func__, requestedSize, availableBytes, mDataSize, mDataPos, mDataCapacity);
+            return BAD_VALUE;
+        }
+    }
+
+    *size = requestedSize;
+    return NO_ERROR;
+}
+
 status_t Parcel::read(void* outData, size_t len) const
 {
     if (len > INT32_MAX) {
@@ -1699,7 +1724,7 @@
 status_t Parcel::readBoolVector(std::optional<std::vector<bool>>* val) const {
     const int32_t start = dataPosition();
     int32_t size;
-    status_t status = readInt32(&size);
+    status_t status = readVectorSizeWithCoarseBoundCheck(&size);
     val->reset();
 
     if (status != OK || size < 0) {
@@ -1721,7 +1746,7 @@
 status_t Parcel::readBoolVector(std::unique_ptr<std::vector<bool>>* val) const {
     const int32_t start = dataPosition();
     int32_t size;
-    status_t status = readInt32(&size);
+    status_t status = readVectorSizeWithCoarseBoundCheck(&size);
     val->reset();
 
     if (status != OK || size < 0) {
@@ -1742,7 +1767,7 @@
 
 status_t Parcel::readBoolVector(std::vector<bool>* val) const {
     int32_t size;
-    status_t status = readInt32(&size);
+    status_t status = readVectorSizeWithCoarseBoundCheck(&size);
 
     if (status != OK) {
         return status;
diff --git a/libs/binder/ParcelableHolder.cpp b/libs/binder/ParcelableHolder.cpp
index b2b8671..2e86b74 100644
--- a/libs/binder/ParcelableHolder.cpp
+++ b/libs/binder/ParcelableHolder.cpp
@@ -37,7 +37,7 @@
         size_t sizePos = p->dataPosition();
         RETURN_ON_FAILURE(p->writeInt32(0));
         size_t dataStartPos = p->dataPosition();
-        RETURN_ON_FAILURE(p->writeUtf8AsUtf16(this->mParcelableName));
+        RETURN_ON_FAILURE(p->writeString16(this->mParcelableName));
         this->mParcelable->writeToParcel(p);
         size_t dataSize = p->dataPosition() - dataStartPos;
 
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index b49951b..54c49e4 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -517,6 +517,11 @@
     void                initState();
     void                scanForFds() const;
     status_t            validateReadData(size_t len) const;
+
+    // Reads an int32 size and does a coarse bounds check against the number
+    // of available bytes in the Parcel.
+    status_t            readVectorSizeWithCoarseBoundCheck(int32_t *size) const;
+
     void                updateWorkSourceRequestHeaderPosition() const;
 
     status_t            finishFlattenBinder(const sp<IBinder>& binder);
@@ -787,6 +792,7 @@
 template<typename T>
 status_t Parcel::resizeOutVector(std::vector<T>* val) const {
     int32_t size;
+    // used for allocating 'out' vector args, do not use readVectorSizeWithCoarseBoundCheck() here
     status_t err = readInt32(&size);
     if (err != NO_ERROR) {
         return err;
@@ -802,6 +808,7 @@
 template<typename T>
 status_t Parcel::resizeOutVector(std::optional<std::vector<T>>* val) const {
     int32_t size;
+    // used for allocating 'out' vector args, do not use readVectorSizeWithCoarseBoundCheck() here
     status_t err = readInt32(&size);
     if (err != NO_ERROR) {
         return err;
@@ -818,6 +825,7 @@
 template<typename T>
 status_t Parcel::resizeOutVector(std::unique_ptr<std::vector<T>>* val) const {
     int32_t size;
+    // used for allocating 'out' vector args, do not use readVectorSizeWithCoarseBoundCheck() here
     status_t err = readInt32(&size);
     if (err != NO_ERROR) {
         return err;
@@ -834,7 +842,7 @@
 template<typename T>
 status_t Parcel::reserveOutVector(std::vector<T>* val, size_t* size) const {
     int32_t read_size;
-    status_t err = readInt32(&read_size);
+    status_t err = readVectorSizeWithCoarseBoundCheck(&read_size);
     if (err != NO_ERROR) {
         return err;
     }
@@ -850,7 +858,7 @@
 template<typename T>
 status_t Parcel::reserveOutVector(std::optional<std::vector<T>>* val, size_t* size) const {
     int32_t read_size;
-    status_t err = readInt32(&read_size);
+    status_t err = readVectorSizeWithCoarseBoundCheck(&read_size);
     if (err != NO_ERROR) {
         return err;
     }
@@ -870,7 +878,7 @@
 status_t Parcel::reserveOutVector(std::unique_ptr<std::vector<T>>* val,
                                   size_t* size) const {
     int32_t read_size;
-    status_t err = readInt32(&read_size);
+    status_t err = readVectorSizeWithCoarseBoundCheck(&read_size);
     if (err != NO_ERROR) {
         return err;
     }
@@ -923,7 +931,7 @@
         std::vector<T>* val,
         status_t(Parcel::*read_func)(U*) const) const {
     int32_t size;
-    status_t status = this->readInt32(&size);
+    status_t status = this->readVectorSizeWithCoarseBoundCheck(&size);
 
     if (status != OK) {
         return status;
@@ -965,7 +973,7 @@
                                          status_t(Parcel::*read_func)(T*) const) const {
     const size_t start = dataPosition();
     int32_t size;
-    status_t status = readInt32(&size);
+    status_t status = readVectorSizeWithCoarseBoundCheck(&size);
     val->reset();
 
     if (status != OK || size < 0) {
@@ -989,7 +997,7 @@
                                          status_t(Parcel::*read_func)(T*) const) const {
     const size_t start = dataPosition();
     int32_t size;
-    status_t status = readInt32(&size);
+    status_t status = readVectorSizeWithCoarseBoundCheck(&size);
     val->reset();
 
     if (status != OK || size < 0) {
@@ -1093,7 +1101,7 @@
 status_t Parcel::readParcelableVector(std::optional<std::vector<std::optional<T>>>* val) const {
     const size_t start = dataPosition();
     int32_t size;
-    status_t status = readInt32(&size);
+    status_t status = readVectorSizeWithCoarseBoundCheck(&size);
     val->reset();
 
     if (status != OK || size < 0) {
@@ -1117,7 +1125,7 @@
 status_t Parcel::readParcelableVector(std::unique_ptr<std::vector<std::unique_ptr<T>>>* val) const {
     const size_t start = dataPosition();
     int32_t size;
-    status_t status = readInt32(&size);
+    status_t status = readVectorSizeWithCoarseBoundCheck(&size);
     val->reset();
 
     if (status != OK || size < 0) {
diff --git a/libs/binder/include/binder/ParcelableHolder.h b/libs/binder/include/binder/ParcelableHolder.h
index 7024a4b..9e4475c 100644
--- a/libs/binder/include/binder/ParcelableHolder.h
+++ b/libs/binder/include/binder/ParcelableHolder.h
@@ -18,6 +18,7 @@
 
 #include <binder/Parcel.h>
 #include <binder/Parcelable.h>
+#include <utils/String16.h>
 #include <mutex>
 #include <optional>
 #include <tuple>
@@ -52,53 +53,59 @@
     }
 
     template <typename T>
-    bool setParcelable(T&& p) {
+    status_t setParcelable(T&& p) {
         using Tt = typename std::decay<T>::type;
         return setParcelable<Tt>(std::make_shared<Tt>(std::forward<T>(p)));
     }
 
     template <typename T>
-    bool setParcelable(std::shared_ptr<T> p) {
+    status_t setParcelable(std::shared_ptr<T> p) {
         static_assert(std::is_base_of<Parcelable, T>::value, "T must be derived from Parcelable");
         if (p && this->getStability() > p->getStability()) {
-            return false;
+            return android::BAD_VALUE;
         }
         this->mParcelable = p;
         this->mParcelableName = T::getParcelableDescriptor();
         this->mParcelPtr = nullptr;
-        return true;
+        return android::OK;
     }
 
     template <typename T>
-    std::shared_ptr<T> getParcelable() const {
+    status_t getParcelable(std::shared_ptr<T>* ret) const {
         static_assert(std::is_base_of<Parcelable, T>::value, "T must be derived from Parcelable");
-        const std::string& parcelableDesc = T::getParcelableDescriptor();
+        const String16& parcelableDesc = T::getParcelableDescriptor();
         if (!this->mParcelPtr) {
             if (!this->mParcelable || !this->mParcelableName) {
                 ALOGD("empty ParcelableHolder");
-                return nullptr;
+                *ret = nullptr;
+                return android::OK;
             } else if (parcelableDesc != *mParcelableName) {
                 ALOGD("extension class name mismatch expected:%s actual:%s",
-                      mParcelableName->c_str(), parcelableDesc.c_str());
-                return nullptr;
+                      String8(*mParcelableName).c_str(), String8(parcelableDesc).c_str());
+                *ret = nullptr;
+                return android::BAD_VALUE;
             }
-            return std::shared_ptr<T>(mParcelable, reinterpret_cast<T*>(mParcelable.get()));
+            *ret = std::shared_ptr<T>(mParcelable, reinterpret_cast<T*>(mParcelable.get()));
+            return android::OK;
         }
         this->mParcelPtr->setDataPosition(0);
-        status_t status = this->mParcelPtr->readUtf8FromUtf16(&this->mParcelableName);
+        status_t status = this->mParcelPtr->readString16(&this->mParcelableName);
         if (status != android::OK || parcelableDesc != this->mParcelableName) {
             this->mParcelableName = std::nullopt;
-            return nullptr;
+            *ret = nullptr;
+            return status;
         }
         this->mParcelable = std::make_shared<T>();
         status = mParcelable.get()->readFromParcel(this->mParcelPtr.get());
         if (status != android::OK) {
             this->mParcelableName = std::nullopt;
             this->mParcelable = nullptr;
-            return nullptr;
+            *ret = nullptr;
+            return status;
         }
         this->mParcelPtr = nullptr;
-        return std::shared_ptr<T>(mParcelable, reinterpret_cast<T*>(mParcelable.get()));
+        *ret = std::shared_ptr<T>(mParcelable, reinterpret_cast<T*>(mParcelable.get()));
+        return android::OK;
     }
 
     Stability getStability() const override { return mStability; }
@@ -124,7 +131,7 @@
 
 private:
     mutable std::shared_ptr<Parcelable> mParcelable;
-    mutable std::optional<std::string> mParcelableName;
+    mutable std::optional<String16> mParcelableName;
     mutable std::unique_ptr<Parcel> mParcelPtr;
     Stability mStability;
 };
diff --git a/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h b/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
index e1d6c34..6636a41 100644
--- a/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
@@ -82,34 +82,37 @@
     }
 
     template <typename T>
-    bool setParcelable(const T& p) {
+    binder_status_t setParcelable(const T& p) {
         if (this->mStability > T::_aidl_stability) {
-            return false;
+            return STATUS_BAD_VALUE;
         }
         AParcel_reset(mParcel.get());
         AParcel_writeString(mParcel.get(), T::descriptor, strlen(T::descriptor));
         p.writeToParcel(mParcel.get());
-        return true;
+        return STATUS_OK;
     }
 
     template <typename T>
-    std::unique_ptr<T> getParcelable() const {
+    binder_status_t getParcelable(std::optional<T>* ret) const {
         const std::string parcelableDesc(T::descriptor);
         AParcel_setDataPosition(mParcel.get(), 0);
         if (AParcel_getDataSize(mParcel.get()) == 0) {
-            return nullptr;
+            *ret = std::nullopt;
+            return STATUS_OK;
         }
         std::string parcelableDescInParcel;
         binder_status_t status = AParcel_readString(mParcel.get(), &parcelableDescInParcel);
         if (status != STATUS_OK || parcelableDesc != parcelableDescInParcel) {
-            return nullptr;
+            *ret = std::nullopt;
+            return status;
         }
-        std::unique_ptr<T> ret = std::make_unique<T>();
-        status = ret->readFromParcel(this->mParcel.get());
+        *ret = std::make_optional<T>();
+        status = (*ret)->readFromParcel(this->mParcel.get());
         if (status != STATUS_OK) {
-            return nullptr;
+            *ret = std::nullopt;
+            return status;
         }
-        return std::move(ret);
+        return STATUS_OK;
     }
 
     void reset() { AParcel_reset(mParcel.get()); }
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 4a4510e..18ade37 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -32,9 +32,10 @@
 
 cc_library_shared {
     name: "libgui",
-    vendor_available: false,
+    vendor_available: true,
     vndk: {
         enabled: true,
+        private: true,
     },
     double_loadable: true,
 
diff --git a/services/gpuservice/tests/unittests/GpuMemTest.cpp b/services/gpuservice/tests/unittests/GpuMemTest.cpp
index c5f8859..e916221 100644
--- a/services/gpuservice/tests/unittests/GpuMemTest.cpp
+++ b/services/gpuservice/tests/unittests/GpuMemTest.cpp
@@ -59,7 +59,6 @@
     }
 
     void SetUp() override {
-        SKIP_IF_BPF_NOT_SUPPORTED;
         bpf::setrlimitForTest();
 
         mGpuMem = std::make_unique<GpuMem>();
@@ -87,8 +86,6 @@
 };
 
 TEST_F(GpuMemTest, validGpuMemTotalBpfPaths) {
-    SKIP_IF_BPF_NOT_SUPPORTED;
-
     EXPECT_EQ(mTestableGpuMem.getGpuMemTraceGroup(), "gpu_mem");
     EXPECT_EQ(mTestableGpuMem.getGpuMemTotalTracepoint(), "gpu_mem_total");
     EXPECT_EQ(mTestableGpuMem.getGpuMemTotalProgPath(),
@@ -97,20 +94,16 @@
 }
 
 TEST_F(GpuMemTest, bpfInitializationFailed) {
-    SKIP_IF_BPF_NOT_SUPPORTED;
-
     EXPECT_EQ(dumpsys(), "Failed to initialize GPU memory eBPF\n");
 }
 
 TEST_F(GpuMemTest, gpuMemTotalMapEmpty) {
-    SKIP_IF_BPF_NOT_SUPPORTED;
     mTestableGpuMem.setGpuMemTotalMap(mTestMap);
 
     EXPECT_EQ(dumpsys(), "GPU memory total usage map is empty\n");
 }
 
 TEST_F(GpuMemTest, globalMemTotal) {
-    SKIP_IF_BPF_NOT_SUPPORTED;
     ASSERT_RESULT_OK(mTestMap.writeValue(TEST_GLOBAL_KEY, TEST_GLOBAL_VAL, BPF_ANY));
     mTestableGpuMem.setGpuMemTotalMap(mTestMap);
 
@@ -118,7 +111,6 @@
 }
 
 TEST_F(GpuMemTest, missingGlobalMemTotal) {
-    SKIP_IF_BPF_NOT_SUPPORTED;
     ASSERT_RESULT_OK(mTestMap.writeValue(TEST_PROC_KEY_1, TEST_PROC_VAL_1, BPF_ANY));
     mTestableGpuMem.setGpuMemTotalMap(mTestMap);
 
@@ -126,7 +118,6 @@
 }
 
 TEST_F(GpuMemTest, procMemTotal) {
-    SKIP_IF_BPF_NOT_SUPPORTED;
     ASSERT_RESULT_OK(mTestMap.writeValue(TEST_PROC_KEY_1, TEST_PROC_VAL_1, BPF_ANY));
     ASSERT_RESULT_OK(mTestMap.writeValue(TEST_PROC_KEY_2, TEST_PROC_VAL_2, BPF_ANY));
     mTestableGpuMem.setGpuMemTotalMap(mTestMap);
@@ -146,7 +137,6 @@
 }
 
 TEST_F(GpuMemTest, traverseGpuMemTotals) {
-    SKIP_IF_BPF_NOT_SUPPORTED;
     ASSERT_RESULT_OK(mTestMap.writeValue(TEST_GLOBAL_KEY, TEST_GLOBAL_VAL, BPF_ANY));
     ASSERT_RESULT_OK(mTestMap.writeValue(TEST_PROC_KEY_1, TEST_PROC_VAL_1, BPF_ANY));
     ASSERT_RESULT_OK(mTestMap.writeValue(TEST_PROC_KEY_2, TEST_PROC_VAL_2, BPF_ANY));
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index d14a301..3cccaf9 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <log/log.h>
 #include <sys/socket.h>
 #include <utils/threads.h>
 
@@ -53,20 +54,13 @@
 SensorService::SensorEventConnection::~SensorEventConnection() {
     ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
     destroy();
-}
-
-void SensorService::SensorEventConnection::destroy() {
-    Mutex::Autolock _l(mDestroyLock);
-
-    // destroy once only
-    if (mDestroyed) {
-        return;
-    }
-
     mService->cleanupConnection(this);
     if (mEventCache != nullptr) {
         delete[] mEventCache;
     }
+}
+
+void SensorService::SensorEventConnection::destroy() {
     mDestroyed = true;
 }
 
@@ -679,6 +673,11 @@
         int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
         int reservedFlags)
 {
+    if (mDestroyed) {
+        android_errorWriteLog(0x534e4554, "168211968");
+        return DEAD_OBJECT;
+    }
+
     status_t err;
     if (enabled) {
         err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
@@ -693,10 +692,19 @@
 status_t SensorService::SensorEventConnection::setEventRate(
         int handle, nsecs_t samplingPeriodNs)
 {
+    if (mDestroyed) {
+        android_errorWriteLog(0x534e4554, "168211968");
+        return DEAD_OBJECT;
+    }
+
     return mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName);
 }
 
 status_t  SensorService::SensorEventConnection::flush() {
+    if (mDestroyed) {
+        return DEAD_OBJECT;
+    }
+
     return  mService->flushSensor(this, mOpPackageName);
 }
 
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index 8f2d5db..9487a39 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_SENSOR_EVENT_CONNECTION_H
 #define ANDROID_SENSOR_EVENT_CONNECTION_H
 
+#include <atomic>
 #include <stdint.h>
 #include <sys/types.h>
 #include <unordered_map>
@@ -182,8 +183,8 @@
     int mTotalAcksNeeded, mTotalAcksReceived;
 #endif
 
-    mutable Mutex mDestroyLock;
-    bool mDestroyed;
+    // Used to track if this object was inappropriately used after destroy().
+    std::atomic_bool mDestroyed;
 
     // Store a mapping of sensor handles to required AppOp for a sensor. This map only contains a
     // valid mapping for sensors that require a permission in order to reduce the lookup time.
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 34dc536..d3247e1 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -835,6 +835,8 @@
             needsProtected == renderEngine.isProtected()) {
             mRenderSurface->setProtected(needsProtected);
         }
+    } else if (!outputState.isSecure && renderEngine.isProtected()) {
+        renderEngine.useProtectedContext(false);
     }
 
     base::unique_fd fd;
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index 09f37fb..29fd4b9 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -159,6 +159,7 @@
         EXPECT_CALL(mCompositionEngine, getHwComposer()).WillRepeatedly(ReturnRef(mHwComposer));
         EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
         EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+        EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
     }
 
     DisplayCreationArgs getDisplayCreationArgsForPhysicalHWCDisplay() {
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 7a06400..8f76afa 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -2871,6 +2871,7 @@
     mOutput.mState.usesClientComposition = false;
 
     EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+    EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
 
     EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
 
@@ -2883,6 +2884,7 @@
     mOutput.mState.flipClientTarget = true;
 
     EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+    EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
 
     EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
     EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
@@ -2892,6 +2894,7 @@
 
 TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
     EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+    EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
 
     EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
 
@@ -2904,6 +2907,7 @@
     mOutput.mState.flipClientTarget = true;
 
     EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+    EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
 
     EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
 
@@ -2914,6 +2918,7 @@
     EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
     EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
     EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+    EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
     EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
             .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
     EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
@@ -2936,6 +2941,7 @@
     EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
     EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
     EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+    EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
     EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
             .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
     EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
@@ -2963,6 +2969,7 @@
     EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
     EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
     EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+    EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
     EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
             .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
     EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
@@ -2991,6 +2998,7 @@
     EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
     EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
     EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+    EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
     EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
             .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
     EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
@@ -3019,6 +3027,7 @@
     EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
     EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
     EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+    EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
     EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
             .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
     EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
@@ -3050,6 +3059,7 @@
     EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
     EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
     EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+    EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
     EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
             .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
             .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
@@ -3072,6 +3082,7 @@
 struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
     OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
         EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+        EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
         EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
                 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
         EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
@@ -3219,6 +3230,8 @@
     mOutput.mState.isSecure = false;
     mLayer2.mLayerFEState.hasProtectedContent = true;
     EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
+    EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
+    EXPECT_CALL(mRenderEngine, useProtectedContext(false)).WillOnce(Return(true));
 
     mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
 }
@@ -3311,6 +3324,7 @@
         EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
         EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
         EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+        EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
         EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
                 .WillRepeatedly(Return());
         EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
diff --git a/services/surfaceflinger/StartPropertySetThread.cpp b/services/surfaceflinger/StartPropertySetThread.cpp
index db82772..f42cd53 100644
--- a/services/surfaceflinger/StartPropertySetThread.cpp
+++ b/services/surfaceflinger/StartPropertySetThread.cpp
@@ -31,6 +31,7 @@
     property_set(kTimestampProperty, mTimestampPropertyValue ? "1" : "0");
     // Clear BootAnimation exit flag
     property_set("service.bootanim.exit", "0");
+    property_set("service.bootanim.progress", "0");
     // Start BootAnimation if not started
     property_set("ctl.start", "bootanim");
     // Exit immediately
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 39f923f..02b5324 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4501,12 +4501,9 @@
 
 void SurfaceFlinger::dumpFrameEventsLocked(std::string& result) {
     result.append("Layer frame timestamps:\n");
-
-    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
-    const size_t count = currentLayers.size();
-    for (size_t i=0 ; i<count ; i++) {
-        currentLayers[i]->dumpFrameEvents(result);
-    }
+    // Traverse all layers to dump frame-events for each layer
+    mCurrentState.traverseInZOrder(
+        [&] (Layer* layer) { layer->dumpFrameEvents(result); });
 }
 
 void SurfaceFlinger::dumpBufferingStats(std::string& result) const {