Merge "[Rounded Corners] Take display rotation into account."
diff --git a/cmds/installd/view_compiler.cpp b/cmds/installd/view_compiler.cpp
index f1ac717..60d6492 100644
--- a/cmds/installd/view_compiler.cpp
+++ b/cmds/installd/view_compiler.cpp
@@ -45,7 +45,7 @@
     // and pass file descriptors.
 
     // Open input file
-    unique_fd infd{open(apk_path, 0)};
+    unique_fd infd{open(apk_path, O_RDONLY)}; // NOLINT(android-cloexec-open)
     if (infd.get() < 0) {
         PLOG(ERROR) << "Could not open input file: " << apk_path;
         return false;
@@ -53,7 +53,7 @@
 
     // Set up output file. viewcompiler can't open outputs by fd, but it can write to stdout, so
     // we close stdout and open it towards the right output.
-    unique_fd outfd{open(out_dex_file, O_CREAT | O_TRUNC | O_WRONLY, 0644)};
+    unique_fd outfd{open(out_dex_file, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644)};
     if (outfd.get() < 0) {
         PLOG(ERROR) << "Could not open output file: " << out_dex_file;
         return false;
@@ -62,10 +62,6 @@
         PLOG(ERROR) << "Could not change output file permissions";
         return false;
     }
-    if (close(STDOUT_FILENO) != 0) {
-        PLOG(ERROR) << "Could not close stdout";
-        return false;
-    }
     if (dup2(outfd, STDOUT_FILENO) < 0) {
         PLOG(ERROR) << "Could not duplicate output file descriptor";
         return false;
@@ -96,4 +92,4 @@
 }
 
 } // namespace installd
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/cmds/installd/view_compiler.h b/cmds/installd/view_compiler.h
index f7c6e57..aa141ca 100644
--- a/cmds/installd/view_compiler.h
+++ b/cmds/installd/view_compiler.h
@@ -26,4 +26,4 @@
 } // namespace installd
 } // namespace android
 
-#endif // VIEW_COMPILER_H_
\ No newline at end of file
+#endif // VIEW_COMPILER_H_
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index a595c01..5427ff8 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -76,14 +76,6 @@
 // Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER
 #define STRICT_MODE_PENALTY_GATHER (1 << 31)
 
-// XXX This can be made public if we want to provide
-// support for typed data.
-struct small_flat_data
-{
-    uint32_t type;
-    uint32_t data;
-};
-
 namespace android {
 
 static pthread_mutex_t gParcelGlobalAllocSizeLock = PTHREAD_MUTEX_INITIALIZER;
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp
index f2d5c8e..776c6e6 100644
--- a/libs/gui/BufferQueueConsumer.cpp
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -58,7 +58,7 @@
     int numDroppedBuffers = 0;
     sp<IProducerListener> listener;
     {
-        Mutex::Autolock lock(mCore->mMutex);
+        std::unique_lock<std::mutex> lock(mCore->mMutex);
 
         // Check that the consumer doesn't currently have the maximum number of
         // buffers acquired. We allow the max buffer count to be exceeded by one
@@ -203,7 +203,7 @@
 
         if (sharedBufferAvailable && mCore->mQueue.empty()) {
             // make sure the buffer has finished allocating before acquiring it
-            mCore->waitWhileAllocatingLocked();
+            mCore->waitWhileAllocatingLocked(lock);
 
             slot = mCore->mSharedBufferSlot;
 
@@ -264,7 +264,7 @@
         // We might have freed a slot while dropping old buffers, or the producer
         // may be blocked waiting for the number of buffers in the queue to
         // decrease.
-        mCore->mDequeueCondition.broadcast();
+        mCore->mDequeueCondition.notify_all();
 
         ATRACE_INT(mCore->mConsumerName.string(),
                 static_cast<int32_t>(mCore->mQueue.size()));
@@ -286,7 +286,7 @@
     ATRACE_CALL();
     ATRACE_BUFFER_INDEX(slot);
     BQ_LOGV("detachBuffer: slot %d", slot);
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
 
     if (mCore->mIsAbandoned) {
         BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
@@ -312,7 +312,7 @@
     mCore->mActiveBuffers.erase(slot);
     mCore->mFreeSlots.insert(slot);
     mCore->clearBufferSlotLocked(slot);
-    mCore->mDequeueCondition.broadcast();
+    mCore->mDequeueCondition.notify_all();
     VALIDATE_CONSISTENCY();
 
     return NO_ERROR;
@@ -330,7 +330,7 @@
         return BAD_VALUE;
     }
 
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
 
     if (mCore->mSharedBufferMode) {
         BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode");
@@ -422,7 +422,7 @@
 
     sp<IProducerListener> listener;
     { // Autolock scope
-        Mutex::Autolock lock(mCore->mMutex);
+        std::lock_guard<std::mutex> lock(mCore->mMutex);
 
         // If the frame number has changed because the buffer has been reallocated,
         // we can ignore this releaseBuffer for the old buffer.
@@ -461,7 +461,7 @@
         listener = mCore->mConnectedProducerListener;
         BQ_LOGV("releaseBuffer: releasing slot %d", slot);
 
-        mCore->mDequeueCondition.broadcast();
+        mCore->mDequeueCondition.notify_all();
         VALIDATE_CONSISTENCY();
     } // Autolock scope
 
@@ -485,7 +485,7 @@
     BQ_LOGV("connect: controlledByApp=%s",
             controlledByApp ? "true" : "false");
 
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
 
     if (mCore->mIsAbandoned) {
         BQ_LOGE("connect: BufferQueue has been abandoned");
@@ -503,7 +503,7 @@
 
     BQ_LOGV("disconnect");
 
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
 
     if (mCore->mConsumerListener == nullptr) {
         BQ_LOGE("disconnect: no consumer is connected");
@@ -515,7 +515,7 @@
     mCore->mQueue.clear();
     mCore->freeAllBuffersLocked();
     mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
-    mCore->mDequeueCondition.broadcast();
+    mCore->mDequeueCondition.notify_all();
     return NO_ERROR;
 }
 
@@ -527,7 +527,7 @@
         return BAD_VALUE;
     }
 
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
 
     if (mCore->mIsAbandoned) {
         BQ_LOGE("getReleasedBuffers: BufferQueue has been abandoned");
@@ -569,7 +569,7 @@
 
     BQ_LOGV("setDefaultBufferSize: width=%u height=%u", width, height);
 
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
     mCore->mDefaultWidth = width;
     mCore->mDefaultHeight = height;
     return NO_ERROR;
@@ -583,7 +583,7 @@
         return BAD_VALUE;
     }
 
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
 
     if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
         BQ_LOGE("setMaxBufferCount: producer is already connected");
@@ -623,8 +623,8 @@
 
     sp<IConsumerListener> listener;
     { // Autolock scope
-        Mutex::Autolock lock(mCore->mMutex);
-        mCore->waitWhileAllocatingLocked();
+        std::unique_lock<std::mutex> lock(mCore->mMutex);
+        mCore->waitWhileAllocatingLocked(lock);
 
         if (mCore->mIsAbandoned) {
             BQ_LOGE("setMaxAcquiredBufferCount: consumer is abandoned");
@@ -684,7 +684,7 @@
 status_t BufferQueueConsumer::setConsumerName(const String8& name) {
     ATRACE_CALL();
     BQ_LOGV("setConsumerName: '%s'", name.string());
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
     mCore->mConsumerName = name;
     mConsumerName = name;
     return NO_ERROR;
@@ -693,7 +693,7 @@
 status_t BufferQueueConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) {
     ATRACE_CALL();
     BQ_LOGV("setDefaultBufferFormat: %u", defaultFormat);
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
     mCore->mDefaultBufferFormat = defaultFormat;
     return NO_ERROR;
 }
@@ -702,7 +702,7 @@
         android_dataspace defaultDataSpace) {
     ATRACE_CALL();
     BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace);
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
     mCore->mDefaultBufferDataSpace = defaultDataSpace;
     return NO_ERROR;
 }
@@ -710,7 +710,7 @@
 status_t BufferQueueConsumer::setConsumerUsageBits(uint64_t usage) {
     ATRACE_CALL();
     BQ_LOGV("setConsumerUsageBits: %#" PRIx64, usage);
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
     mCore->mConsumerUsageBits = usage;
     return NO_ERROR;
 }
@@ -718,7 +718,7 @@
 status_t BufferQueueConsumer::setConsumerIsProtected(bool isProtected) {
     ATRACE_CALL();
     BQ_LOGV("setConsumerIsProtected: %s", isProtected ? "true" : "false");
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
     mCore->mConsumerIsProtected = isProtected;
     return NO_ERROR;
 }
@@ -726,26 +726,26 @@
 status_t BufferQueueConsumer::setTransformHint(uint32_t hint) {
     ATRACE_CALL();
     BQ_LOGV("setTransformHint: %#x", hint);
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
     mCore->mTransformHint = hint;
     return NO_ERROR;
 }
 
 status_t BufferQueueConsumer::getSidebandStream(sp<NativeHandle>* outStream) const {
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
     *outStream = mCore->mSidebandStream;
     return NO_ERROR;
 }
 
 status_t BufferQueueConsumer::getOccupancyHistory(bool forceFlush,
         std::vector<OccupancyTracker::Segment>* outHistory) {
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
     *outHistory = mCore->mOccupancyTracker.getSegmentHistory(forceFlush);
     return NO_ERROR;
 }
 
 status_t BufferQueueConsumer::discardFreeBuffers() {
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
     mCore->discardFreeBuffersLocked();
     return NO_ERROR;
 }
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
index 960b194..96c55ac 100644
--- a/libs/gui/BufferQueueCore.cpp
+++ b/libs/gui/BufferQueueCore.cpp
@@ -110,7 +110,7 @@
 BufferQueueCore::~BufferQueueCore() {}
 
 void BufferQueueCore::dumpState(const String8& prefix, String8* outResult) const {
-    Mutex::Autolock lock(mMutex);
+    std::lock_guard<std::mutex> lock(mMutex);
 
     outResult->appendFormat("%s- BufferQueue ", prefix.string());
     outResult->appendFormat("mMaxAcquiredBufferCount=%d mMaxDequeuedBufferCount=%d\n",
@@ -306,10 +306,10 @@
     return true;
 }
 
-void BufferQueueCore::waitWhileAllocatingLocked() const {
+void BufferQueueCore::waitWhileAllocatingLocked(std::unique_lock<std::mutex>& lock) const {
     ATRACE_CALL();
     while (mIsAllocating) {
-        mIsAllocatingCondition.wait(mMutex);
+        mIsAllocatingCondition.wait(lock);
     }
 }
 
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index e657488..72ae375 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -59,14 +59,15 @@
     mNextCallbackTicket(0),
     mCurrentCallbackTicket(0),
     mCallbackCondition(),
-    mDequeueTimeout(-1) {}
+    mDequeueTimeout(-1),
+    mDequeueWaitingForAllocation(false) {}
 
 BufferQueueProducer::~BufferQueueProducer() {}
 
 status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
     ATRACE_CALL();
     BQ_LOGV("requestBuffer: slot %d", slot);
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
 
     if (mCore->mIsAbandoned) {
         BQ_LOGE("requestBuffer: BufferQueue has been abandoned");
@@ -101,8 +102,8 @@
 
     sp<IConsumerListener> listener;
     { // Autolock scope
-        Mutex::Autolock lock(mCore->mMutex);
-        mCore->waitWhileAllocatingLocked();
+        std::unique_lock<std::mutex> lock(mCore->mMutex);
+        mCore->waitWhileAllocatingLocked(lock);
 
         if (mCore->mIsAbandoned) {
             BQ_LOGE("setMaxDequeuedBufferCount: BufferQueue has been "
@@ -163,7 +164,7 @@
         if (delta < 0) {
             listener = mCore->mConsumerListener;
         }
-        mCore->mDequeueCondition.broadcast();
+        mCore->mDequeueCondition.notify_all();
     } // Autolock scope
 
     // Call back without lock held
@@ -180,8 +181,8 @@
 
     sp<IConsumerListener> listener;
     { // Autolock scope
-        Mutex::Autolock lock(mCore->mMutex);
-        mCore->waitWhileAllocatingLocked();
+        std::unique_lock<std::mutex> lock(mCore->mMutex);
+        mCore->waitWhileAllocatingLocked(lock);
 
         if (mCore->mIsAbandoned) {
             BQ_LOGE("setAsyncMode: BufferQueue has been abandoned");
@@ -215,7 +216,7 @@
         }
         mCore->mAsyncMode = async;
         VALIDATE_CONSISTENCY();
-        mCore->mDequeueCondition.broadcast();
+        mCore->mDequeueCondition.notify_all();
         if (delta < 0) {
             listener = mCore->mConsumerListener;
         }
@@ -247,7 +248,7 @@
 }
 
 status_t BufferQueueProducer::waitForFreeSlotThenRelock(FreeSlotCaller caller,
-        int* found) const {
+        std::unique_lock<std::mutex>& lock, int* found) const {
     auto callerString = (caller == FreeSlotCaller::Dequeue) ?
             "dequeueBuffer" : "attachBuffer";
     bool tryAgain = true;
@@ -334,13 +335,13 @@
                 return WOULD_BLOCK;
             }
             if (mDequeueTimeout >= 0) {
-                status_t result = mCore->mDequeueCondition.waitRelative(
-                        mCore->mMutex, mDequeueTimeout);
-                if (result == TIMED_OUT) {
-                    return result;
+                std::cv_status result = mCore->mDequeueCondition.wait_for(lock,
+                        std::chrono::nanoseconds(mDequeueTimeout));
+                if (result == std::cv_status::timeout) {
+                    return TIMED_OUT;
                 }
             } else {
-                mCore->mDequeueCondition.wait(mCore->mMutex);
+                mCore->mDequeueCondition.wait(lock);
             }
         }
     } // while (tryAgain)
@@ -354,7 +355,7 @@
                                             FrameEventHistoryDelta* outTimestamps) {
     ATRACE_CALL();
     { // Autolock scope
-        Mutex::Autolock lock(mCore->mMutex);
+        std::lock_guard<std::mutex> lock(mCore->mMutex);
         mConsumerName = mCore->mConsumerName;
 
         if (mCore->mIsAbandoned) {
@@ -381,7 +382,16 @@
     bool attachedByConsumer = false;
 
     { // Autolock scope
-        Mutex::Autolock lock(mCore->mMutex);
+        std::unique_lock<std::mutex> lock(mCore->mMutex);
+
+        // If we don't have a free buffer, but we are currently allocating, we wait until allocation
+        // is finished such that we don't allocate in parallel.
+        if (mCore->mFreeBuffers.empty() && mCore->mIsAllocating) {
+            mDequeueWaitingForAllocation = true;
+            mCore->waitWhileAllocatingLocked(lock);
+            mDequeueWaitingForAllocation = false;
+            mDequeueWaitingForAllocationCondition.notify_all();
+        }
 
         if (format == 0) {
             format = mCore->mDefaultBufferFormat;
@@ -398,8 +408,7 @@
 
         int found = BufferItem::INVALID_BUFFER_SLOT;
         while (found == BufferItem::INVALID_BUFFER_SLOT) {
-            status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue,
-                    &found);
+            status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue, lock, &found);
             if (status != NO_ERROR) {
                 return status;
             }
@@ -506,7 +515,7 @@
         status_t error = graphicBuffer->initCheck();
 
         { // Autolock scope
-            Mutex::Autolock lock(mCore->mMutex);
+            std::lock_guard<std::mutex> lock(mCore->mMutex);
 
             if (error == NO_ERROR && !mCore->mIsAbandoned) {
                 graphicBuffer->setGenerationNumber(mCore->mGenerationNumber);
@@ -514,7 +523,7 @@
             }
 
             mCore->mIsAllocating = false;
-            mCore->mIsAllocatingCondition.broadcast();
+            mCore->mIsAllocatingCondition.notify_all();
 
             if (error != NO_ERROR) {
                 mCore->mFreeSlots.insert(*outSlot);
@@ -580,7 +589,7 @@
 
     sp<IConsumerListener> listener;
     {
-        Mutex::Autolock lock(mCore->mMutex);
+        std::lock_guard<std::mutex> lock(mCore->mMutex);
 
         if (mCore->mIsAbandoned) {
             BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
@@ -615,7 +624,7 @@
         mCore->mActiveBuffers.erase(slot);
         mCore->mFreeSlots.insert(slot);
         mCore->clearBufferSlotLocked(slot);
-        mCore->mDequeueCondition.broadcast();
+        mCore->mDequeueCondition.notify_all();
         VALIDATE_CONSISTENCY();
         listener = mCore->mConsumerListener;
     }
@@ -641,7 +650,7 @@
 
     sp<IConsumerListener> listener;
     {
-        Mutex::Autolock lock(mCore->mMutex);
+        std::unique_lock<std::mutex> lock(mCore->mMutex);
 
         if (mCore->mIsAbandoned) {
             BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned");
@@ -659,7 +668,7 @@
             return BAD_VALUE;
         }
 
-        mCore->waitWhileAllocatingLocked();
+        mCore->waitWhileAllocatingLocked(lock);
 
         if (mCore->mFreeBuffers.empty()) {
             return NO_MEMORY;
@@ -697,7 +706,7 @@
         return BAD_VALUE;
     }
 
-    Mutex::Autolock lock(mCore->mMutex);
+    std::unique_lock<std::mutex> lock(mCore->mMutex);
 
     if (mCore->mIsAbandoned) {
         BQ_LOGE("attachBuffer: BufferQueue has been abandoned");
@@ -721,11 +730,11 @@
         return BAD_VALUE;
     }
 
-    mCore->waitWhileAllocatingLocked();
+    mCore->waitWhileAllocatingLocked(lock);
 
     status_t returnFlags = NO_ERROR;
     int found;
-    status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Attach, &found);
+    status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Attach, lock, &found);
     if (status != NO_ERROR) {
         return status;
     }
@@ -798,7 +807,7 @@
     uint64_t currentFrameNumber = 0;
     BufferItem item;
     { // Autolock scope
-        Mutex::Autolock lock(mCore->mMutex);
+        std::lock_guard<std::mutex> lock(mCore->mMutex);
 
         if (mCore->mIsAbandoned) {
             BQ_LOGE("queueBuffer: BufferQueue has been abandoned");
@@ -939,7 +948,7 @@
         }
 
         mCore->mBufferHasBeenQueued = true;
-        mCore->mDequeueCondition.broadcast();
+        mCore->mDequeueCondition.notify_all();
         mCore->mLastQueuedSlot = slot;
 
         output->width = mCore->mDefaultWidth;
@@ -975,9 +984,9 @@
     sp<Fence> lastQueuedFence;
 
     { // scope for the lock
-        Mutex::Autolock lock(mCallbackMutex);
+        std::unique_lock<std::mutex> lock(mCallbackMutex);
         while (callbackTicket != mCurrentCallbackTicket) {
-            mCallbackCondition.wait(mCallbackMutex);
+            mCallbackCondition.wait(lock);
         }
 
         if (frameAvailableListener != nullptr) {
@@ -994,7 +1003,7 @@
         mLastQueuedTransform = item.mTransform;
 
         ++mCurrentCallbackTicket;
-        mCallbackCondition.broadcast();
+        mCallbackCondition.notify_all();
     }
 
     // Wait without lock held
@@ -1022,7 +1031,7 @@
 status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
     ATRACE_CALL();
     BQ_LOGV("cancelBuffer: slot %d", slot);
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
 
     if (mCore->mIsAbandoned) {
         BQ_LOGE("cancelBuffer: BufferQueue has been abandoned");
@@ -1067,7 +1076,7 @@
     }
 
     mSlots[slot].mFence = fence;
-    mCore->mDequeueCondition.broadcast();
+    mCore->mDequeueCondition.notify_all();
     VALIDATE_CONSISTENCY();
 
     return NO_ERROR;
@@ -1075,7 +1084,7 @@
 
 int BufferQueueProducer::query(int what, int *outValue) {
     ATRACE_CALL();
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
 
     if (outValue == nullptr) {
         BQ_LOGE("query: outValue was NULL");
@@ -1143,7 +1152,7 @@
 status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
         int api, bool producerControlledByApp, QueueBufferOutput *output) {
     ATRACE_CALL();
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
     mConsumerName = mCore->mConsumerName;
     BQ_LOGV("connect: api=%d producerControlledByApp=%s", api,
             producerControlledByApp ? "true" : "false");
@@ -1238,7 +1247,7 @@
     int status = NO_ERROR;
     sp<IConsumerListener> listener;
     { // Autolock scope
-        Mutex::Autolock lock(mCore->mMutex);
+        std::unique_lock<std::mutex> lock(mCore->mMutex);
 
         if (mode == DisconnectMode::AllLocal) {
             if (BufferQueueThreadState::getCallingPid() != mCore->mConnectedPid) {
@@ -1247,7 +1256,7 @@
             api = BufferQueueCore::CURRENTLY_CONNECTED_API;
         }
 
-        mCore->waitWhileAllocatingLocked();
+        mCore->waitWhileAllocatingLocked(lock);
 
         if (mCore->mIsAbandoned) {
             // It's not really an error to disconnect after the surface has
@@ -1291,7 +1300,7 @@
                     mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
                     mCore->mConnectedPid = -1;
                     mCore->mSidebandStream.clear();
-                    mCore->mDequeueCondition.broadcast();
+                    mCore->mDequeueCondition.notify_all();
                     listener = mCore->mConsumerListener;
                 } else if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
                     BQ_LOGE("disconnect: not connected (req=%d)", api);
@@ -1321,7 +1330,7 @@
 status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) {
     sp<IConsumerListener> listener;
     { // Autolock scope
-        Mutex::Autolock _l(mCore->mMutex);
+        std::lock_guard<std::mutex> _l(mCore->mMutex);
         mCore->mSidebandStream = stream;
         listener = mCore->mConsumerListener;
     } // Autolock scope
@@ -1343,8 +1352,8 @@
         uint64_t allocUsage = 0;
         std::string allocName;
         { // Autolock scope
-            Mutex::Autolock lock(mCore->mMutex);
-            mCore->waitWhileAllocatingLocked();
+            std::unique_lock<std::mutex> lock(mCore->mMutex);
+            mCore->waitWhileAllocatingLocked(lock);
 
             if (!mCore->mAllowAllocation) {
                 BQ_LOGE("allocateBuffers: allocation is not allowed for this "
@@ -1379,16 +1388,16 @@
             if (result != NO_ERROR) {
                 BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format"
                         " %u, usage %#" PRIx64 ")", width, height, format, usage);
-                Mutex::Autolock lock(mCore->mMutex);
+                std::lock_guard<std::mutex> lock(mCore->mMutex);
                 mCore->mIsAllocating = false;
-                mCore->mIsAllocatingCondition.broadcast();
+                mCore->mIsAllocatingCondition.notify_all();
                 return;
             }
             buffers.push_back(graphicBuffer);
         }
 
         { // Autolock scope
-            Mutex::Autolock lock(mCore->mMutex);
+            std::unique_lock<std::mutex> lock(mCore->mMutex);
             uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth;
             uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight;
             PixelFormat checkFormat = format != 0 ?
@@ -1399,7 +1408,7 @@
                 // Something changed while we released the lock. Retry.
                 BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying.");
                 mCore->mIsAllocating = false;
-                mCore->mIsAllocatingCondition.broadcast();
+                mCore->mIsAllocatingCondition.notify_all();
                 continue;
             }
 
@@ -1434,8 +1443,14 @@
             }
 
             mCore->mIsAllocating = false;
-            mCore->mIsAllocatingCondition.broadcast();
+            mCore->mIsAllocatingCondition.notify_all();
             VALIDATE_CONSISTENCY();
+
+            // If dequeue is waiting for to allocate a buffer, release the lock until it's not
+            // waiting anymore so it can use the buffer we just allocated.
+            while (mDequeueWaitingForAllocation) {
+                mDequeueWaitingForAllocationCondition.wait(lock);
+            }
         } // Autolock scope
     }
 }
@@ -1444,7 +1459,7 @@
     ATRACE_CALL();
     BQ_LOGV("allowAllocation: %s", allow ? "true" : "false");
 
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
     mCore->mAllowAllocation = allow;
     return NO_ERROR;
 }
@@ -1453,14 +1468,14 @@
     ATRACE_CALL();
     BQ_LOGV("setGenerationNumber: %u", generationNumber);
 
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
     mCore->mGenerationNumber = generationNumber;
     return NO_ERROR;
 }
 
 String8 BufferQueueProducer::getConsumerName() const {
     ATRACE_CALL();
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
     BQ_LOGV("getConsumerName: %s", mConsumerName.string());
     return mConsumerName;
 }
@@ -1469,7 +1484,7 @@
     ATRACE_CALL();
     BQ_LOGV("setSharedBufferMode: %d", sharedBufferMode);
 
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
     if (!sharedBufferMode) {
         mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
     }
@@ -1481,7 +1496,7 @@
     ATRACE_CALL();
     BQ_LOGV("setAutoRefresh: %d", autoRefresh);
 
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
 
     mCore->mAutoRefresh = autoRefresh;
     return NO_ERROR;
@@ -1491,7 +1506,7 @@
     ATRACE_CALL();
     BQ_LOGV("setDequeueTimeout: %" PRId64, timeout);
 
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
     int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, false,
             mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked();
     if (!mCore->adjustAvailableSlotsLocked(delta)) {
@@ -1512,7 +1527,7 @@
     ATRACE_CALL();
     BQ_LOGV("getLastQueuedBuffer");
 
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
     if (mCore->mLastQueuedSlot == BufferItem::INVALID_BUFFER_SLOT) {
         *outBuffer = nullptr;
         *outFence = Fence::NO_FENCE;
@@ -1548,7 +1563,7 @@
     BQ_LOGV("addAndGetFrameTimestamps");
     sp<IConsumerListener> listener;
     {
-        Mutex::Autolock lock(mCore->mMutex);
+        std::lock_guard<std::mutex> lock(mCore->mMutex);
         listener = mCore->mConsumerListener;
     }
     if (listener != nullptr) {
@@ -1575,7 +1590,7 @@
 status_t BufferQueueProducer::getConsumerUsage(uint64_t* outUsage) const {
     BQ_LOGV("getConsumerUsage");
 
-    Mutex::Autolock lock(mCore->mMutex);
+    std::lock_guard<std::mutex> lock(mCore->mMutex);
     *outUsage = mCore->mConsumerUsageBits;
     return NO_ERROR;
 }
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 14eca43..bf44121 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -360,7 +360,7 @@
         data.writeUint32(height);
         data.writeInt32(static_cast<int32_t>(format));
         data.writeUint64(usage);
-        status_t result = remote()->transact(ALLOCATE_BUFFERS, data, &reply, TF_ONE_WAY);
+        status_t result = remote()->transact(ALLOCATE_BUFFERS, data, &reply, IBinder::FLAG_ONEWAY);
         if (result != NO_ERROR) {
             ALOGE("allocateBuffers failed to transact: %d", result);
         }
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index b74d675..b586bf3 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -551,8 +551,8 @@
             ALOGE("enableVSyncInjections failed to writeBool: %d", result);
             return result;
         }
-        result = remote()->transact(BnSurfaceComposer::ENABLE_VSYNC_INJECTIONS,
-                data, &reply, TF_ONE_WAY);
+        result = remote()->transact(BnSurfaceComposer::ENABLE_VSYNC_INJECTIONS, data, &reply,
+                                    IBinder::FLAG_ONEWAY);
         if (result != NO_ERROR) {
             ALOGE("enableVSyncInjections failed to transact: %d", result);
             return result;
@@ -572,7 +572,8 @@
             ALOGE("injectVSync failed to writeInt64: %d", result);
             return result;
         }
-        result = remote()->transact(BnSurfaceComposer::INJECT_VSYNC, data, &reply, TF_ONE_WAY);
+        result = remote()->transact(BnSurfaceComposer::INJECT_VSYNC, data, &reply,
+                                    IBinder::FLAG_ONEWAY);
         if (result != NO_ERROR) {
             ALOGE("injectVSync failed to transact: %d", result);
             return result;
diff --git a/libs/gui/include/gui/BufferQueueCore.h b/libs/gui/include/gui/BufferQueueCore.h
index b377a41..0e80283 100644
--- a/libs/gui/include/gui/BufferQueueCore.h
+++ b/libs/gui/include/gui/BufferQueueCore.h
@@ -22,8 +22,6 @@
 #include <gui/BufferSlot.h>
 #include <gui/OccupancyTracker.h>
 
-#include <utils/Condition.h>
-#include <utils/Mutex.h>
 #include <utils/NativeHandle.h>
 #include <utils/RefBase.h>
 #include <utils/String8.h>
@@ -33,6 +31,8 @@
 
 #include <list>
 #include <set>
+#include <mutex>
+#include <condition_variable>
 
 #define BQ_LOGV(x, ...) ALOGV("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
 #define BQ_LOGD(x, ...) ALOGD("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
@@ -134,7 +134,7 @@
     bool adjustAvailableSlotsLocked(int delta);
 
     // waitWhileAllocatingLocked blocks until mIsAllocating is false.
-    void waitWhileAllocatingLocked() const;
+    void waitWhileAllocatingLocked(std::unique_lock<std::mutex>& lock) const;
 
 #if DEBUG_ONLY_CODE
     // validateConsistencyLocked ensures that the free lists are in sync with
@@ -145,7 +145,7 @@
     // mMutex is the mutex used to prevent concurrent access to the member
     // variables of BufferQueueCore objects. It must be locked whenever any
     // member variable is accessed.
-    mutable Mutex mMutex;
+    mutable std::mutex mMutex;
 
     // mIsAbandoned indicates that the BufferQueue will no longer be used to
     // consume image buffers pushed to it using the IGraphicBufferProducer
@@ -219,7 +219,7 @@
 
     // mDequeueCondition is a condition variable used for dequeueBuffer in
     // synchronous mode.
-    mutable Condition mDequeueCondition;
+    mutable std::condition_variable mDequeueCondition;
 
     // mDequeueBufferCannotBlock indicates whether dequeueBuffer is allowed to
     // block. This flag is set during connect when both the producer and
@@ -282,7 +282,7 @@
 
     // mIsAllocatingCondition is a condition variable used by producers to wait until mIsAllocating
     // becomes false.
-    mutable Condition mIsAllocatingCondition;
+    mutable std::condition_variable mIsAllocatingCondition;
 
     // mAllowAllocation determines whether dequeueBuffer is allowed to allocate
     // new buffers
diff --git a/libs/gui/include/gui/BufferQueueProducer.h b/libs/gui/include/gui/BufferQueueProducer.h
index 73bc5dd..415e2a6 100644
--- a/libs/gui/include/gui/BufferQueueProducer.h
+++ b/libs/gui/include/gui/BufferQueueProducer.h
@@ -211,7 +211,8 @@
         Dequeue,
         Attach,
     };
-    status_t waitForFreeSlotThenRelock(FreeSlotCaller caller, int* found) const;
+    status_t waitForFreeSlotThenRelock(FreeSlotCaller caller, std::unique_lock<std::mutex>& lock,
+            int* found) const;
 
     sp<BufferQueueCore> mCore;
 
@@ -243,15 +244,22 @@
     // (mCore->mMutex) is held, a ticket is retained by the producer. After
     // dropping the BufferQueue lock, the producer must wait on the condition
     // variable until the current callback ticket matches its retained ticket.
-    Mutex mCallbackMutex;
+    std::mutex mCallbackMutex;
     int mNextCallbackTicket; // Protected by mCore->mMutex
     int mCurrentCallbackTicket; // Protected by mCallbackMutex
-    Condition mCallbackCondition;
+    std::condition_variable mCallbackCondition;
 
     // Sets how long dequeueBuffer or attachBuffer will block if a buffer or
     // slot is not yet available.
     nsecs_t mDequeueTimeout;
 
+    // If set to true, dequeueBuffer() is currently waiting for buffer allocation to complete.
+    bool mDequeueWaitingForAllocation;
+
+    // Condition variable to signal allocateBuffers() that dequeueBuffer() is no longer waiting for
+    // allocation to complete.
+    std::condition_variable mDequeueWaitingForAllocationCondition;
+
 }; // class BufferQueueProducer
 
 } // namespace android
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index 7c55133..faf6d2a 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -248,7 +248,8 @@
     bool useContextPriority = extensions.hasContextPriority() &&
             (featureFlags & RenderEngine::USE_HIGH_PRIORITY_CONTEXT);
     EGLContext protectedContext = EGL_NO_CONTEXT;
-    if (extensions.hasProtectedContent()) {
+    if ((featureFlags & RenderEngine::ENABLE_PROTECTED_CONTEXT) &&
+        extensions.hasProtectedContent()) {
         protectedContext = createEglContext(display, config, nullptr, useContextPriority,
                                             Protection::PROTECTED);
         ALOGE_IF(protectedContext == EGL_NO_CONTEXT, "Can't create protected context");
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index bf614fd..e707004 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -63,6 +63,9 @@
     enum FeatureFlag {
         USE_COLOR_MANAGEMENT = 1 << 0,      // Device manages color
         USE_HIGH_PRIORITY_CONTEXT = 1 << 1, // Use high priority context
+
+        // Create a protected context when if possible
+        ENABLE_PROTECTED_CONTEXT = 1 << 2,
     };
 
     static std::unique_ptr<impl::RenderEngine> create(int hwcFormat, uint32_t featureFlags,
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 0d5bc15..4dc9111 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -2055,7 +2055,7 @@
             return; // skip the inconsistent event
         }
 
-        dispatchPointerDownOutsideFocusIfNecessary(motionEntry->source,
+        dispatchPointerDownOutsideFocus(motionEntry->source,
                 dispatchEntry->resolvedAction, inputTarget->inputChannel->getToken());
 
         break;
@@ -2073,10 +2073,11 @@
 
 }
 
-void InputDispatcher::dispatchPointerDownOutsideFocusIfNecessary(uint32_t source, int32_t action,
+void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
         const sp<IBinder>& newToken) {
     int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
-    if (source != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
+    uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
+    if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
         return;
     }
 
@@ -2095,7 +2096,9 @@
         return;
     }
 
-    // Dispatch onPointerDownOutsideFocus to the policy.
+    CommandEntry* commandEntry = postCommandLocked(
+            & InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
+    commandEntry->newToken = newToken;
 }
 
 void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
@@ -3997,6 +4000,12 @@
     entry->release();
 }
 
+void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
+    mLock.unlock();
+    mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
+    mLock.lock();
+}
+
 void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
         CommandEntry* commandEntry) {
     sp<Connection> connection = commandEntry->connection;
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 3735a0b..32bc414 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -272,6 +272,13 @@
      */
     virtual bool checkInjectEventsPermissionNonReentrant(
             int32_t injectorPid, int32_t injectorUid) = 0;
+
+    /* Notifies the policy that a pointer down event has occurred outside the current focused
+     * window.
+     *
+     * The touchedToken passed as an argument is the window that received the input event.
+     */
+    virtual void onPointerDownOutsideFocus(const sp<IBinder>& touchedToken) = 0;
 };
 
 
@@ -1149,7 +1156,7 @@
     void releaseDispatchEntry(DispatchEntry* dispatchEntry);
     static int handleReceiveCallback(int fd, int events, void* data);
     // The action sent should only be of type AMOTION_EVENT_*
-    void dispatchPointerDownOutsideFocusIfNecessary(uint32_t source, int32_t action,
+    void dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
             const sp<IBinder>& newToken) REQUIRES(mLock);
 
     void synthesizeCancelationEventsForAllConnectionsLocked(
@@ -1204,6 +1211,8 @@
             DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled) REQUIRES(mLock);
     void doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
     void initializeKeyEvent(KeyEvent* event, const KeyEntry* entry);
+    void doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry)
+            REQUIRES(mLock);
 
     // Statistics gathering.
     void updateDispatchStatistics(nsecs_t currentTime, const EventEntry* entry,
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 745fac0..f0c36e5 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -52,6 +52,7 @@
         mTime = -1;
         mAction = -1;
         mDisplayId = -1;
+        mOnPointerDownToken.clear();
     }
 
     void assertFilterInputEventWasCalledWithExpectedArgs(const NotifyMotionArgs* args) {
@@ -87,11 +88,18 @@
                 << "Expected filterInputEvent() to not have been called.";
     }
 
+    void assertOnPointerDownEquals(const sp<IBinder>& touchedToken) {
+        ASSERT_EQ(mOnPointerDownToken, touchedToken)
+                << "Expected token from onPointerDownOutsideFocus was not matched";
+        reset();
+    }
+
 private:
     bool mInputEventFiltered;
     nsecs_t mTime;
     int32_t mAction;
     int32_t mDisplayId;
+    sp<IBinder> mOnPointerDownToken;
 
     virtual void notifyConfigurationChanged(nsecs_t) {
     }
@@ -161,11 +169,16 @@
         return false;
     }
 
+    virtual void onPointerDownOutsideFocus(const sp<IBinder>& newToken) {
+        mOnPointerDownToken = newToken;
+    }
+
     void reset() {
         mInputEventFiltered = false;
         mTime = -1;
         mAction = -1;
         mDisplayId = -1;
+        mOnPointerDownToken.clear();
     }
 };
 
@@ -432,10 +445,10 @@
     FakeWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle,
         const sp<InputDispatcher>& dispatcher, const std::string name, int32_t displayId) :
             FakeInputReceiver(dispatcher, name, displayId),
-            mFocused(false) {
+            mFocused(false), mFrame(Rect(0, 0, WIDTH, HEIGHT)), mLayoutParamFlags(0) {
             mServerChannel->setToken(new BBinder());
             mDispatcher->registerInputChannel(mServerChannel, displayId);
- 
+
             inputApplicationHandle->updateInfo();
             mInfo.applicationInfo = *inputApplicationHandle->getInfo();
     }
@@ -443,15 +456,15 @@
     virtual bool updateInfo() {
         mInfo.token = mServerChannel ? mServerChannel->getToken() : nullptr;
         mInfo.name = mName;
-        mInfo.layoutParamsFlags = 0;
+        mInfo.layoutParamsFlags = mLayoutParamFlags;
         mInfo.layoutParamsType = InputWindowInfo::TYPE_APPLICATION;
         mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
-        mInfo.frameLeft = 0;
-        mInfo.frameTop = 0;
-        mInfo.frameRight = WIDTH;
-        mInfo.frameBottom = HEIGHT;
+        mInfo.frameLeft = mFrame.left;
+        mInfo.frameTop = mFrame.top;
+        mInfo.frameRight = mFrame.right;
+        mInfo.frameBottom = mFrame.bottom;
         mInfo.globalScaleFactor = 1.0;
-        mInfo.addTouchableRegion(Rect(0, 0, WIDTH, HEIGHT));
+        mInfo.addTouchableRegion(mFrame);
         mInfo.visible = true;
         mInfo.canReceiveKeys = true;
         mInfo.hasFocus = mFocused;
@@ -470,6 +483,14 @@
         mFocused = true;
     }
 
+    void setFrame(const Rect& frame) {
+        mFrame.set(frame);
+    }
+
+    void setLayoutParamFlags(int32_t flags) {
+        mLayoutParamFlags = flags;
+    }
+
     void releaseChannel() {
         mServerChannel.clear();
         InputWindowHandle::releaseChannel();
@@ -480,6 +501,8 @@
     }
 
     bool mFocused;
+    Rect mFrame;
+    int32_t mLayoutParamFlags;
 };
 
 static int32_t injectKeyDown(const sp<InputDispatcher>& dispatcher,
@@ -500,7 +523,7 @@
 }
 
 static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t source,
-        int32_t displayId) {
+        int32_t displayId, int32_t x = 100, int32_t y = 200) {
     MotionEvent event;
     PointerProperties pointerProperties[1];
     PointerCoords pointerCoords[1];
@@ -510,13 +533,13 @@
     pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
 
     pointerCoords[0].clear();
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 100);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 200);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
 
     nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
     // Define a valid motion down event.
     event.initialize(DEVICE_ID, source, displayId,
-            AMOTION_EVENT_ACTION_DOWN, /* actionButton */0, /* flags */ 0, /* edgeFlags */ 0,
+            AMOTION_EVENT_ACTION_DOWN, /* actionButton */ 0, /* flags */ 0, /* edgeFlags */ 0,
             AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
             /* xOffset */ 0, /* yOffset */ 0, /* xPrecision */ 0,
             /* yPrecision */ 0, currentTime, currentTime, /*pointerCount*/ 1, pointerProperties,
@@ -907,4 +930,98 @@
     testNotifyKey(/*expectToBeFiltered*/ false);
 }
 
+class InputDispatcherOnPointerDownOutsideFocus : public InputDispatcherTest {
+    virtual void SetUp() {
+        InputDispatcherTest::SetUp();
+
+        sp<FakeApplicationHandle> application = new FakeApplicationHandle();
+        mUnfocusedWindow = new FakeWindowHandle(application, mDispatcher, "Top",
+                ADISPLAY_ID_DEFAULT);
+        mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
+        // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
+        // window.
+        mUnfocusedWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
+
+        mWindowFocused = new FakeWindowHandle(application, mDispatcher, "Second",
+                ADISPLAY_ID_DEFAULT);
+        mWindowFocused->setFrame(Rect(50, 50, 100, 100));
+        mWindowFocused->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
+        mWindowFocusedTouchPoint = 60;
+
+        // Set focused application.
+        mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
+        mWindowFocused->setFocus();
+
+        // Expect one focus window exist in display.
+        std::vector<sp<InputWindowHandle>> inputWindowHandles;
+        inputWindowHandles.push_back(mUnfocusedWindow);
+        inputWindowHandles.push_back(mWindowFocused);
+        mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
+    }
+
+    virtual void TearDown() {
+        InputDispatcherTest::TearDown();
+
+        mUnfocusedWindow.clear();
+        mWindowFocused.clear();
+    }
+
+protected:
+    sp<FakeWindowHandle> mUnfocusedWindow;
+    sp<FakeWindowHandle> mWindowFocused;
+    int32_t mWindowFocusedTouchPoint;
+};
+
+// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
+// DOWN on the window that doesn't have focus. Ensure the window that didn't have focus received
+// the onPointerDownOutsideFocus callback.
+TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_Success) {
+    ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
+            AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, 20, 20))
+            << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+    // Call monitor to wait for the command queue to get flushed.
+    mDispatcher->monitor();
+
+    mFakePolicy->assertOnPointerDownEquals(mUnfocusedWindow->getToken());
+}
+
+// Have two windows, one with focus. Inject MotionEvent with source TRACKBALL and action
+// DOWN on the window that doesn't have focus. Ensure no window received the
+// onPointerDownOutsideFocus callback.
+TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPointerSource) {
+    ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
+            AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_DEFAULT, 20, 20))
+            << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+    // Call monitor to wait for the command queue to get flushed.
+    mDispatcher->monitor();
+
+    mFakePolicy->assertOnPointerDownEquals(nullptr);
+}
+
+// Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't
+// have focus. Ensure no window received the onPointerDownOutsideFocus callback.
+TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) {
+    ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
+            << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+    // Call monitor to wait for the command queue to get flushed.
+    mDispatcher->monitor();
+
+    mFakePolicy->assertOnPointerDownEquals(nullptr);
+}
+
+// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
+// DOWN on the window that already has focus. Ensure no window received the
+// onPointerDownOutsideFocus callback.
+TEST_F(InputDispatcherOnPointerDownOutsideFocus,
+        OnPointerDownOutsideFocus_OnAlreadyFocusedWindow) {
+    ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
+            AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, mWindowFocusedTouchPoint,
+            mWindowFocusedTouchPoint))
+            << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+    // Call monitor to wait for the command queue to get flushed.
+    mDispatcher->monitor();
+
+    mFakePolicy->assertOnPointerDownEquals(nullptr);
+}
+
 } // namespace android
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index d3b36fe..b623991 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -23,6 +23,7 @@
 
 #include "BufferQueueLayer.h"
 #include "LayerRejecter.h"
+#include "SurfaceInterceptor.h"
 
 #include "TimeStats/TimeStats.h"
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0e498b7..2ba55b5 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -75,6 +75,7 @@
 #include "BufferLayer.h"
 #include "BufferQueueLayer.h"
 #include "BufferStateLayer.h"
+#include "BufferStateLayerCache.h"
 #include "Client.h"
 #include "ColorLayer.h"
 #include "Colorizer.h"
@@ -95,12 +96,14 @@
 #include "DisplayHardware/HWComposer.h"
 #include "DisplayHardware/VirtualDisplaySurface.h"
 #include "Effects/Daltonizer.h"
+#include "RegionSamplingThread.h"
 #include "Scheduler/DispSync.h"
 #include "Scheduler/DispSyncSource.h"
 #include "Scheduler/EventControlThread.h"
 #include "Scheduler/EventThread.h"
 #include "Scheduler/InjectVSyncSource.h"
 #include "Scheduler/MessageQueue.h"
+#include "Scheduler/PhaseOffsets.h"
 #include "Scheduler/Scheduler.h"
 #include "TimeStats/TimeStats.h"
 
@@ -266,49 +269,17 @@
     }
 }
 
-SurfaceFlingerBE::SurfaceFlingerBE()
-      : mHwcServiceName(getHwcServiceName()),
-        mFrameBuckets(),
-        mTotalTime(0),
-        mLastSwapTime(0),
-        mComposerSequenceId(0) {
-}
+SurfaceFlingerBE::SurfaceFlingerBE() : mHwcServiceName(getHwcServiceName()) {}
 
-SurfaceFlinger::SurfaceFlinger(surfaceflinger::Factory& factory,
-                               SurfaceFlinger::SkipInitializationTag)
-      : BnSurfaceComposer(),
-        mFactory(factory),
-        mTransactionPending(false),
-        mAnimTransactionPending(false),
-        mTraversalNeededMainThread(false),
-        mLayersRemoved(false),
-        mLayersAdded(false),
-        mBootTime(systemTime()),
-        mPhaseOffsets{getFactory().createPhaseOffsets()},
-        mVisibleRegionsDirty(false),
-        mGeometryInvalid(false),
-        mAnimCompositionPending(false),
-        mBootStage(BootStage::BOOTLOADER),
-        mDebugRegion(0),
-        mDebugDisableHWC(0),
-        mDebugDisableTransformHint(0),
-        mDebugEnableProtectedContent(false),
-        mDebugInTransaction(0),
-        mLastTransactionTime(0),
-        mForceFullDamage(false),
-        mTracing(*this),
-        mTimeStats(factory.createTimeStats()),
-        mRefreshStartTime(0),
-        mHasPoweredOff(false),
-        mNumLayers(0),
-        mVrFlingerRequestsDisplay(false),
-        mMainThreadId(std::this_thread::get_id()),
-        mCompositionEngine{getFactory().createCompositionEngine()} {
-    mSetInputWindowsListener = new SetInputWindowsListener(this);
-}
+SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
+      : mFactory(factory),
+        mPhaseOffsets(mFactory.createPhaseOffsets()),
+        mInterceptor(mFactory.createSurfaceInterceptor(this)),
+        mTimeStats(mFactory.createTimeStats()),
+        mEventQueue(mFactory.createMessageQueue()),
+        mCompositionEngine(mFactory.createCompositionEngine()) {}
 
-SurfaceFlinger::SurfaceFlinger(surfaceflinger::Factory& factory)
-      : SurfaceFlinger(factory, SkipInitialization) {
+SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) {
     ALOGI("SurfaceFlinger is starting");
 
     hasSyncFramework = running_without_sync_framework(true);
@@ -427,9 +398,7 @@
     mEventQueue->init(this);
 }
 
-SurfaceFlinger::~SurfaceFlinger()
-{
-}
+SurfaceFlinger::~SurfaceFlinger() = default;
 
 void SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
 {
@@ -667,6 +636,9 @@
                             renderengine::RenderEngine::USE_COLOR_MANAGEMENT : 0);
     renderEngineFeature |= (useContextPriority ?
                             renderengine::RenderEngine::USE_HIGH_PRIORITY_CONTEXT : 0);
+    renderEngineFeature |=
+            (enable_protected_contents(false) ? renderengine::RenderEngine::ENABLE_PROTECTED_CONTEXT
+                                              : 0);
 
     // TODO(b/77156734): We need to stop casting and use HAL types when possible.
     // Sending maxFrameBufferAcquiredBuffers as the cache size is tightly tuned to single-display.
@@ -1704,22 +1676,22 @@
     ATRACE_CALL();
     uint32_t transactionFlags = peekTransactionFlags();
 
-    // Apply any ready transactions in the queues if there are still transactions that have not been
-    // applied, wake up during the next vsync period and check again
-    bool transactionNeeded = false;
-    if (!flushTransactionQueues()) {
-        transactionNeeded = true;
+    bool flushedATransaction = flushTransactionQueues();
+
+    bool runHandleTransaction = transactionFlags &&
+            ((transactionFlags != eTransactionFlushNeeded) || flushedATransaction);
+
+    if (runHandleTransaction) {
+        handleTransaction(eTransactionMask);
+    } else {
+        getTransactionFlags(eTransactionFlushNeeded);
     }
 
-    if (transactionFlags) {
-        handleTransaction(transactionFlags);
+    if (transactionFlushNeeded()) {
+        setTransactionFlags(eTransactionFlushNeeded);
     }
 
-    if (transactionNeeded) {
-        setTransactionFlags(eTransactionNeeded);
-    }
-
-    return transactionFlags;
+    return runHandleTransaction;
 }
 
 void SurfaceFlinger::handleMessageRefresh() {
@@ -2417,8 +2389,6 @@
     const auto& displayState = display->getState();
     const auto displayId = display->getId();
 
-    mPostFramebufferTime = systemTime();
-
     if (displayState.isEnabled) {
         if (displayId) {
             getHwComposer().presentAndGetReleaseFences(*displayId);
@@ -2481,8 +2451,7 @@
     State drawingState(mDrawingState);
 
     Mutex::Autolock _l(mStateLock);
-    const nsecs_t now = systemTime();
-    mDebugInTransaction = now;
+    mDebugInTransaction = systemTime();
 
     // Here we're guaranteed that some transaction flags are set
     // so we can call handleTransactionLocked() unconditionally.
@@ -2494,7 +2463,6 @@
     transactionFlags = getTransactionFlags(eTransactionMask);
     handleTransactionLocked(transactionFlags);
 
-    mLastTransactionTime = systemTime() - now;
     mDebugInTransaction = 0;
     invalidateHwcGeometry();
     // here the transaction has been committed
@@ -3519,6 +3487,8 @@
 
 bool SurfaceFlinger::flushTransactionQueues() {
     Mutex::Autolock _l(mStateLock);
+    bool flushedATransaction = false;
+
     auto it = mTransactionQueues.begin();
     while (it != mTransactionQueues.end()) {
         auto& [applyToken, transactionQueue] = *it;
@@ -3528,17 +3498,23 @@
                     [states, displays, flags, desiredPresentTime, uncacheBuffer, listenerCallbacks,
                      postTime, privileged] = transactionQueue.front();
             if (!transactionIsReadyToBeApplied(desiredPresentTime, states)) {
+                setTransactionFlags(eTransactionFlushNeeded);
                 break;
             }
             applyTransactionState(states, displays, flags, mPendingInputWindowCommands,
                                   desiredPresentTime, uncacheBuffer, listenerCallbacks, postTime,
                                   privileged, /*isMainThread*/ true);
             transactionQueue.pop();
+            flushedATransaction = true;
         }
 
         it = (transactionQueue.empty()) ? mTransactionQueues.erase(it) : std::next(it, 1);
     }
-    return mTransactionQueues.empty();
+    return flushedATransaction;
+}
+
+bool SurfaceFlinger::transactionFlushNeeded() {
+    return !mTransactionQueues.empty();
 }
 
 bool SurfaceFlinger::containsAnyInvalidClientState(const Vector<ComposerState>& states) {
@@ -3610,7 +3586,7 @@
         mTransactionQueues[applyToken].emplace(states, displays, flags, desiredPresentTime,
                                                uncacheBuffer, listenerCallbacks, postTime,
                                                privileged);
-        setTransactionFlags(eTransactionNeeded);
+        setTransactionFlags(eTransactionFlushNeeded);
         return;
     }
 
@@ -5104,13 +5080,13 @@
             }
             case 1008:  // toggle use of hw composer
                 n = data.readInt32();
-                mDebugDisableHWC = n ? 1 : 0;
+                mDebugDisableHWC = n != 0;
                 invalidateHwcGeometry();
                 repaintEverything();
                 return NO_ERROR;
             case 1009:  // toggle use of transform hint
                 n = data.readInt32();
-                mDebugDisableTransformHint = n ? 1 : 0;
+                mDebugDisableTransformHint = n != 0;
                 invalidateHwcGeometry();
                 repaintEverything();
                 return NO_ERROR;
@@ -5192,7 +5168,7 @@
             }
             case 1017: {
                 n = data.readInt32();
-                mForceFullDamage = static_cast<bool>(n);
+                mForceFullDamage = n != 0;
                 return NO_ERROR;
             }
             case 1018: { // Modify Choreographer's phase offset
@@ -5919,14 +5895,11 @@
     return NO_ERROR;
 }
 
-// ----------------------------------------------------------------------------
-
-void SetInputWindowsListener::onSetInputWindowsFinished() {
+void SurfaceFlinger::SetInputWindowsListener::onSetInputWindowsFinished() {
     mFlinger->setInputWindowsFinished();
 }
 
-}; // namespace android
-
+} // namespace android
 
 #if defined(__gl_h_)
 #error "don't include gl/gl.h in this file"
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 3d8b6b7..176c65d 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_SURFACE_FLINGER_H
-#define ANDROID_SURFACE_FLINGER_H
+#pragma once
 
 #include <sys/types.h>
 
@@ -48,27 +47,18 @@
 #include <utils/threads.h>
 
 #include "AllowedDisplayConfigs.h"
-#include "Barrier.h"
-#include "BufferStateLayerCache.h"
 #include "DisplayDevice.h"
 #include "DisplayHardware/HWC2.h"
-#include "DisplayHardware/HWComposer.h"
 #include "DisplayHardware/PowerAdvisor.h"
 #include "Effects/Daltonizer.h"
 #include "FrameTracker.h"
 #include "LayerStats.h"
 #include "LayerVector.h"
-#include "RegionSamplingThread.h"
-#include "Scheduler/DispSync.h"
-#include "Scheduler/EventThread.h"
-#include "Scheduler/MessageQueue.h"
-#include "Scheduler/PhaseOffsets.h"
 #include "Scheduler/RefreshRateConfigs.h"
 #include "Scheduler/RefreshRateStats.h"
 #include "Scheduler/Scheduler.h"
 #include "Scheduler/VSyncModulator.h"
 #include "SurfaceFlingerFactory.h"
-#include "SurfaceInterceptor.h"
 #include "SurfaceTracing.h"
 #include "TransactionCompletedThread.h"
 
@@ -90,56 +80,37 @@
 
 namespace android {
 
-using RefreshRateType = scheduler::RefreshRateConfigs::RefreshRateType;
-
-// ---------------------------------------------------------------------------
-
 class Client;
-class ColorLayer;
-class DisplayEventConnection;
-class EventControlThread;
 class EventThread;
-class IGraphicBufferConsumer;
+class HWComposer;
 class IGraphicBufferProducer;
 class IInputFlinger;
 class InjectVSyncSource;
 class Layer;
+class MessageBase;
 class RefreshRateOverlay;
-class Surface;
-class SurfaceFlingerBE;
+class RegionSamplingThread;
 class TimeStats;
-class VSyncSource;
 
 namespace compositionengine {
 class DisplaySurface;
 } // namespace compositionengine
 
-namespace impl {
-class EventThread;
-} // namespace impl
-
 namespace renderengine {
 class RenderEngine;
-}
-
-typedef std::function<void(const LayerVector::Visitor&)> TraverseLayersFunction;
+} // namespace renderengine
 
 namespace dvr {
 class VrFlinger;
 } // namespace dvr
 
-namespace surfaceflinger {
-class NativeWindowSurface;
-} // namespace surfaceflinger
-
-// ---------------------------------------------------------------------------
-
 enum {
-    eTransactionNeeded        = 0x01,
-    eTraversalNeeded          = 0x02,
+    eTransactionNeeded = 0x01,
+    eTraversalNeeded = 0x02,
     eDisplayTransactionNeeded = 0x04,
     eDisplayLayerStackChanged = 0x08,
-    eTransactionMask          = 0x0f,
+    eTransactionFlushNeeded = 0x10,
+    eTransactionMask = 0x1f,
 };
 
 enum class DisplayColorSetting : int32_t {
@@ -164,35 +135,28 @@
 
     // Only accessed from the main thread.
     struct CompositePresentTime {
-        nsecs_t composite { -1 };
-        std::shared_ptr<FenceTime> display { FenceTime::NO_FENCE };
+        nsecs_t composite = -1;
+        std::shared_ptr<FenceTime> display = FenceTime::NO_FENCE;
     };
     std::queue<CompositePresentTime> mCompositePresentTimes;
 
     static const size_t NUM_BUCKETS = 8; // < 1-7, 7+
-    nsecs_t mFrameBuckets[NUM_BUCKETS];
-    nsecs_t mTotalTime;
-    std::atomic<nsecs_t> mLastSwapTime;
+    nsecs_t mFrameBuckets[NUM_BUCKETS] = {};
+    nsecs_t mTotalTime = 0;
+    std::atomic<nsecs_t> mLastSwapTime = 0;
 
     // Double- vs. triple-buffering stats
     struct BufferingStats {
-        BufferingStats()
-          : numSegments(0),
-            totalTime(0),
-            twoBufferTime(0),
-            doubleBufferedTime(0),
-            tripleBufferedTime(0) {}
-
-        size_t numSegments;
-        nsecs_t totalTime;
+        size_t numSegments = 0;
+        nsecs_t totalTime = 0;
 
         // "Two buffer" means that a third buffer was never used, whereas
         // "double-buffered" means that on average the segment only used two
         // buffers (though it may have used a third for some part of the
         // segment)
-        nsecs_t twoBufferTime;
-        nsecs_t doubleBufferedTime;
-        nsecs_t tripleBufferedTime;
+        nsecs_t twoBufferTime = 0;
+        nsecs_t doubleBufferedTime = 0;
+        nsecs_t tripleBufferedTime = 0;
     };
     mutable Mutex mBufferingStatsMutex;
     std::unordered_map<std::string, BufferingStats> mBufferingStats;
@@ -200,16 +164,7 @@
     // The composer sequence id is a monotonically increasing integer that we
     // use to differentiate callbacks from different hardware composer
     // instances. Each hardware composer instance gets a different sequence id.
-    int32_t mComposerSequenceId;
-};
-
-class SetInputWindowsListener : public BnSetInputWindowsListener {
-public:
-    SetInputWindowsListener(const sp<SurfaceFlinger>& flinger) : mFlinger(flinger) {}
-    void onSetInputWindowsFinished() override;
-
-private:
-    const sp<SurfaceFlinger> mFlinger;
+    int32_t mComposerSequenceId = 0;
 };
 
 class SurfaceFlinger : public BnSurfaceComposer,
@@ -358,16 +313,12 @@
         return mTransactionCompletedThread;
     }
 
-    void setInputWindowsFinished();
-
 private:
-    friend class Client;
-    friend class DisplayEventConnection;
-    friend class impl::EventThread;
-    friend class Layer;
     friend class BufferLayer;
     friend class BufferQueueLayer;
     friend class BufferStateLayer;
+    friend class Client;
+    friend class Layer;
     friend class MonitoredProducer;
     friend class RefreshRateOverlay;
     friend class RegionSamplingThread;
@@ -532,6 +483,8 @@
     void signalLayerUpdate();
     void signalRefresh();
 
+    using RefreshRateType = scheduler::RefreshRateConfigs::RefreshRateType;
+
     struct ActiveConfigInfo {
         RefreshRateType type;
         int configId;
@@ -587,6 +540,7 @@
     void updateInputWindowInfo();
     void commitInputWindowCommands() REQUIRES(mStateLock);
     void executeInputWindowCommands();
+    void setInputWindowsFinished();
     void updateCursorAsync();
 
     /* handlePageFlip - latch a new buffer if available and compute the dirty
@@ -606,7 +560,10 @@
                                const std::vector<ListenerCallbacks>& listenerCallbacks,
                                const int64_t postTime, bool privileged, bool isMainThread = false)
             REQUIRES(mStateLock);
+    // Returns true if at least one transaction was flushed
     bool flushTransactionQueues();
+    // Returns true if there is at least one transaction that needs to be flushed
+    bool transactionFlushNeeded();
     uint32_t getTransactionFlags(uint32_t flags);
     uint32_t peekTransactionFlags();
     // Can only be called from the main thread or with mStateLock held
@@ -673,6 +630,8 @@
 
     void startBootAnim();
 
+    using TraverseLayersFunction = std::function<void(const LayerVector::Visitor&)>;
+
     void renderScreenImplLocked(const RenderArea& renderArea, TraverseLayersFunction traverseLayers,
                                 ANativeWindowBuffer* buffer, bool useIdentityTransform,
                                 int* outSyncFd);
@@ -958,12 +917,12 @@
     // access must be protected by mStateLock
     mutable Mutex mStateLock;
     State mCurrentState{LayerVector::StateSet::Current};
-    std::atomic<int32_t> mTransactionFlags{0};
+    std::atomic<int32_t> mTransactionFlags = 0;
     Condition mTransactionCV;
-    bool mTransactionPending;
-    bool mAnimTransactionPending;
-    SortedVector< sp<Layer> > mLayersPendingRemoval;
-    bool mTraversalNeededMainThread;
+    bool mTransactionPending = false;
+    bool mAnimTransactionPending = false;
+    SortedVector<sp<Layer>> mLayersPendingRemoval;
+    bool mTraversalNeededMainThread = false;
 
     // guards access to the mDrawing state if tracing is enabled.
     mutable std::mutex mDrawingStateLock;
@@ -978,31 +937,30 @@
     size_t mMaxGraphicBufferProducerListSize = MAX_LAYERS;
 
     // protected by mStateLock (but we could use another lock)
-    bool mLayersRemoved;
-    bool mLayersAdded;
+    bool mLayersRemoved = false;
+    bool mLayersAdded = false;
 
-    std::atomic<bool> mRepaintEverything{false};
+    std::atomic<bool> mRepaintEverything = false;
 
     // constant members (no synchronization needed for access)
-    nsecs_t mBootTime;
-    bool mGpuToCpuSupported;
+    const nsecs_t mBootTime = systemTime();
+    bool mGpuToCpuSupported = false;
     std::unique_ptr<EventThread> mInjectorEventThread;
     std::unique_ptr<InjectVSyncSource> mVSyncInjector;
-    std::unique_ptr<EventControlThread> mEventControlThread;
 
     // Calculates correct offsets.
     VSyncModulator mVsyncModulator;
     // Keeps track of all available phase offsets for different refresh types.
-    std::unique_ptr<scheduler::PhaseOffsets> mPhaseOffsets;
+    const std::unique_ptr<scheduler::PhaseOffsets> mPhaseOffsets;
 
     // Can only accessed from the main thread, these members
     // don't need synchronization
     State mDrawingState{LayerVector::StateSet::Drawing};
-    bool mVisibleRegionsDirty;
+    bool mVisibleRegionsDirty = false;
     // Set during transaction commit stage to track if the input info for a layer has changed.
-    bool mInputInfoChanged{false};
-    bool mGeometryInvalid;
-    bool mAnimCompositionPending;
+    bool mInputInfoChanged = false;
+    bool mGeometryInvalid = false;
+    bool mAnimCompositionPending = false;
     std::vector<sp<Layer>> mLayersWithQueuedFrames;
     // Tracks layers that need to update a display's dirty region.
     std::vector<sp<Layer>> mLayersPendingRefresh;
@@ -1019,7 +977,7 @@
         BOOTANIMATION,
         FINISHED,
     };
-    BootStage mBootStage;
+    BootStage mBootStage = BootStage::BOOTLOADER;
 
     struct HotplugEvent {
         hwc2_display_t hwcDisplayId;
@@ -1034,26 +992,23 @@
     std::unordered_map<DisplayId, sp<IBinder>> mPhysicalDisplayTokens;
 
     // don't use a lock for these, we don't care
-    int mDebugRegion;
-    int mDebugDisableHWC;
-    int mDebugDisableTransformHint;
-    bool mDebugEnableProtectedContent;
-    volatile nsecs_t mDebugInSwapBuffers;
-    volatile nsecs_t mDebugInTransaction;
-    nsecs_t mLastTransactionTime;
-    nsecs_t mPostFramebufferTime;
-    bool mForceFullDamage;
+    int mDebugRegion = 0;
+    bool mDebugDisableHWC = false;
+    bool mDebugDisableTransformHint = false;
+    bool mDebugEnableProtectedContent = false;
+    volatile nsecs_t mDebugInTransaction = 0;
+    bool mForceFullDamage = false;
     bool mPropagateBackpressure = true;
-    std::unique_ptr<SurfaceInterceptor> mInterceptor{mFactory.createSurfaceInterceptor(this)};
-    SurfaceTracing mTracing;
+    std::unique_ptr<SurfaceInterceptor> mInterceptor;
+    SurfaceTracing mTracing{*this};
     bool mTracingEnabled = false;
     bool mTracingEnabledChanged GUARDED_BY(mStateLock) = false;
     LayerStats mLayerStats;
-    std::shared_ptr<TimeStats> mTimeStats;
+    const std::shared_ptr<TimeStats> mTimeStats;
     bool mUseHwcVirtualDisplays = false;
-    std::atomic<uint32_t> mFrameMissedCount{0};
-    std::atomic<uint32_t> mHwcFrameMissedCount{0};
-    std::atomic<uint32_t> mGpuFrameMissedCount{0};
+    std::atomic<uint32_t> mFrameMissedCount = 0;
+    std::atomic<uint32_t> mHwcFrameMissedCount = 0;
+    std::atomic<uint32_t> mGpuFrameMissedCount = 0;
 
     TransactionCompletedThread mTransactionCompletedThread;
 
@@ -1061,16 +1016,16 @@
     bool mLayerTripleBufferingDisabled = false;
 
     // these are thread safe
-    mutable std::unique_ptr<MessageQueue> mEventQueue{mFactory.createMessageQueue()};
+    std::unique_ptr<MessageQueue> mEventQueue;
     FrameTracker mAnimFrameTracker;
 
     // protected by mDestroyedLayerLock;
     mutable Mutex mDestroyedLayerLock;
     Vector<Layer const *> mDestroyedLayers;
 
-    nsecs_t mRefreshStartTime;
+    nsecs_t mRefreshStartTime = 0;
 
-    std::atomic<bool> mRefreshPending{false};
+    std::atomic<bool> mRefreshPending = false;
 
     // We maintain a pool of pre-generated texture names to hand out to avoid
     // layer creation needing to run on the main thread (which it would
@@ -1114,21 +1069,21 @@
      * Feature prototyping
      */
 
-    bool mInjectVSyncs;
+    bool mInjectVSyncs = false;
 
     // Static screen stats
-    bool mHasPoweredOff;
+    bool mHasPoweredOff = false;
 
-    size_t mNumLayers;
+    size_t mNumLayers = 0;
 
     // Verify that transaction is being called by an approved process:
     // either AID_GRAPHICS or AID_SYSTEM.
     status_t CheckTransactCodeCredentials(uint32_t code);
 
     std::unique_ptr<dvr::VrFlinger> mVrFlinger;
-    std::atomic<bool> mVrFlingerRequestsDisplay;
+    std::atomic<bool> mVrFlingerRequestsDisplay = false;
     static bool useVrFlinger;
-    std::thread::id mMainThreadId;
+    std::thread::id mMainThreadId = std::this_thread::get_id();
 
     DisplayColorSetting mDisplayColorSetting = DisplayColorSetting::ENHANCED;
 
@@ -1175,23 +1130,30 @@
     bool mDesiredActiveConfigChanged GUARDED_BY(mActiveConfigLock) = false;
     bool mCheckPendingFence = false;
 
-    /* ------------------------------------------------------------------------ */
     bool mLumaSampling = true;
     sp<RegionSamplingThread> mRegionSamplingThread;
+    ui::DisplayPrimaries mInternalDisplayPrimaries;
 
     sp<IInputFlinger> mInputFlinger;
-
     InputWindowCommands mPendingInputWindowCommands GUARDED_BY(mStateLock);
     // Should only be accessed by the main thread.
     InputWindowCommands mInputWindowCommands;
-    ui::DisplayPrimaries mInternalDisplayPrimaries;
 
-    sp<SetInputWindowsListener> mSetInputWindowsListener;
+    struct SetInputWindowsListener : BnSetInputWindowsListener {
+        explicit SetInputWindowsListener(sp<SurfaceFlinger> flinger)
+              : mFlinger(std::move(flinger)) {}
+
+        void onSetInputWindowsFinished() override;
+
+        const sp<SurfaceFlinger> mFlinger;
+    };
+
+    const sp<SetInputWindowsListener> mSetInputWindowsListener = new SetInputWindowsListener(this);
+
     bool mPendingSyncInputWindows GUARDED_BY(mStateLock);
     Hwc2::impl::PowerAdvisor mPowerAdvisor;
 
     std::unique_ptr<RefreshRateOverlay> mRefreshRateOverlay;
 };
-}; // namespace android
 
-#endif // ANDROID_SURFACE_FLINGER_H
+} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlingerProperties.cpp b/services/surfaceflinger/SurfaceFlingerProperties.cpp
index 09b793a..3522429 100644
--- a/services/surfaceflinger/SurfaceFlingerProperties.cpp
+++ b/services/surfaceflinger/SurfaceFlingerProperties.cpp
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2019 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 <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
 #include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
@@ -223,6 +238,14 @@
     return defaultValue;
 }
 
+bool enable_protected_contents(bool defaultValue) {
+    auto temp = SurfaceFlingerProperties::enable_protected_contents();
+    if (temp.has_value()) {
+        return *temp;
+    }
+    return defaultValue;
+}
+
 #define DISPLAY_PRIMARY_SIZE 3
 
 constexpr float kSrgbRedX = 0.4123f;
diff --git a/services/surfaceflinger/SurfaceFlingerProperties.h b/services/surfaceflinger/SurfaceFlingerProperties.h
index b2fafdd..1864290 100644
--- a/services/surfaceflinger/SurfaceFlingerProperties.h
+++ b/services/surfaceflinger/SurfaceFlingerProperties.h
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2019 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.
+ */
 
 #ifndef SURFACEFLINGERPROPERTIES_H_
 #define SURFACEFLINGERPROPERTIES_H_
@@ -59,6 +74,8 @@
 
 bool use_smart_90_for_video(bool defaultValue);
 
+bool enable_protected_contents(bool defaultValue);
+
 android::ui::DisplayPrimaries getDisplayNativePrimaries();
 } // namespace sysprop
 } // namespace android
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
index 4be2ee9..4773307 100644
--- a/services/surfaceflinger/SurfaceTracing.h
+++ b/services/surfaceflinger/SurfaceTracing.h
@@ -41,7 +41,7 @@
  */
 class SurfaceTracing {
 public:
-    SurfaceTracing(SurfaceFlinger& flinger);
+    explicit SurfaceTracing(SurfaceFlinger& flinger);
     void enable();
     bool disable();
     status_t writeToFile();
diff --git a/services/surfaceflinger/TransactionCompletedThread.cpp b/services/surfaceflinger/TransactionCompletedThread.cpp
index 1d2217d..6b2b583 100644
--- a/services/surfaceflinger/TransactionCompletedThread.cpp
+++ b/services/surfaceflinger/TransactionCompletedThread.cpp
@@ -34,7 +34,8 @@
 //         >0 if the first id that doesn't match is greater in c2 or all ids match but c2 is longer
 //
 // See CallbackIdsHash for a explaniation of why this works
-static int compareCallbackIds(const std::vector<CallbackId>& c1, const std::vector<CallbackId> c2) {
+static int compareCallbackIds(const std::vector<CallbackId>& c1,
+                              const std::vector<CallbackId>& c2) {
     if (c1.empty()) {
         return !c2.empty();
     }
diff --git a/services/surfaceflinger/TransactionCompletedThread.h b/services/surfaceflinger/TransactionCompletedThread.h
index 09feb75..21e2678 100644
--- a/services/surfaceflinger/TransactionCompletedThread.h
+++ b/services/surfaceflinger/TransactionCompletedThread.h
@@ -37,7 +37,7 @@
     // 2) CallbackId vectors for the same listener either are identical or contain none of the
     // same members. It is sufficient to just check the first CallbackId in the vectors. If
     // they match, they are the same. If they do not match, they are not the same.
-    std::size_t operator()(const std::vector<CallbackId> callbackIds) const {
+    std::size_t operator()(const std::vector<CallbackId>& callbackIds) const {
         return std::hash<CallbackId>{}((callbackIds.empty()) ? 0 : callbackIds.front());
     }
 };
diff --git a/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop b/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop
index fe6dc93..830c03e 100644
--- a/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop
+++ b/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop
@@ -307,3 +307,11 @@
     access: Readonly
     prop_name: "ro.surface_flinger.use_smart_90_for_video"
 }
+
+prop {
+    api_name: "enable_protected_contents"
+    type: Boolean
+    scope: Internal
+    access: Readonly
+    prop_name: "ro.surface_flinger.protected_contents"
+}
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 46fd964..81235ba 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -31,6 +31,7 @@
 #include "FakePhaseOffsets.h"
 #include "Layer.h"
 #include "NativeWindowSurface.h"
+#include "Scheduler/MessageQueue.h"
 #include "StartPropertySetThread.h"
 #include "SurfaceFlinger.h"
 #include "SurfaceFlingerFactory.h"
@@ -276,8 +277,9 @@
     auto onMessageReceived(int32_t what) { return mFlinger->onMessageReceived(what); }
 
     auto captureScreenImplLocked(const RenderArea& renderArea,
-                                 TraverseLayersFunction traverseLayers, ANativeWindowBuffer* buffer,
-                                 bool useIdentityTransform, bool forSystem, int* outSyncFd) {
+                                 SurfaceFlinger::TraverseLayersFunction traverseLayers,
+                                 ANativeWindowBuffer* buffer, bool useIdentityTransform,
+                                 bool forSystem, int* outSyncFd) {
         return mFlinger->captureScreenImplLocked(renderArea, traverseLayers, buffer,
                                                  useIdentityTransform, forSystem, outSyncFd);
     }