Merge "Remove manual interface that have been AIDLized"
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index b038feb..5c34069 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -486,6 +486,19 @@
     }
 }
 
+bool IPCThreadState::flushIfNeeded()
+{
+    if (mIsLooper || mServingStackPointer != nullptr) {
+        return false;
+    }
+    // In case this thread is not a looper and is not currently serving a binder transaction,
+    // there's no guarantee that this thread will call back into the kernel driver any time
+    // soon. Therefore, flush pending commands such as BC_FREE_BUFFER, to prevent them from getting
+    // stuck in this thread's out buffer.
+    flushCommands();
+    return true;
+}
+
 void IPCThreadState::blockUntilThreadAvailable()
 {
     pthread_mutex_lock(&mProcess->mThreadCountLock);
@@ -604,6 +617,7 @@
 
     mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
 
+    mIsLooper = true;
     status_t result;
     do {
         processPendingDerefs();
@@ -626,6 +640,7 @@
         (void*)pthread_self(), getpid(), result);
 
     mOut.writeInt32(BC_EXIT_LOOPER);
+    mIsLooper = false;
     talkWithDriver(false);
 }
 
@@ -739,9 +754,11 @@
     LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle);
     mOut.writeInt32(BC_ACQUIRE);
     mOut.writeInt32(handle);
-    // Create a temp reference until the driver has handled this command.
-    proxy->incStrong(mProcess.get());
-    mPostWriteStrongDerefs.push(proxy);
+    if (!flushIfNeeded()) {
+        // Create a temp reference until the driver has handled this command.
+        proxy->incStrong(mProcess.get());
+        mPostWriteStrongDerefs.push(proxy);
+    }
 }
 
 void IPCThreadState::decStrongHandle(int32_t handle)
@@ -749,6 +766,7 @@
     LOG_REMOTEREFS("IPCThreadState::decStrongHandle(%d)\n", handle);
     mOut.writeInt32(BC_RELEASE);
     mOut.writeInt32(handle);
+    flushIfNeeded();
 }
 
 void IPCThreadState::incWeakHandle(int32_t handle, BpBinder *proxy)
@@ -756,9 +774,11 @@
     LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle);
     mOut.writeInt32(BC_INCREFS);
     mOut.writeInt32(handle);
-    // Create a temp reference until the driver has handled this command.
-    proxy->getWeakRefs()->incWeak(mProcess.get());
-    mPostWriteWeakDerefs.push(proxy->getWeakRefs());
+    if (!flushIfNeeded()) {
+        // Create a temp reference until the driver has handled this command.
+        proxy->getWeakRefs()->incWeak(mProcess.get());
+        mPostWriteWeakDerefs.push(proxy->getWeakRefs());
+    }
 }
 
 void IPCThreadState::decWeakHandle(int32_t handle)
@@ -766,6 +786,7 @@
     LOG_REMOTEREFS("IPCThreadState::decWeakHandle(%d)\n", handle);
     mOut.writeInt32(BC_DECREFS);
     mOut.writeInt32(handle);
+    flushIfNeeded();
 }
 
 status_t IPCThreadState::attemptIncStrongHandle(int32_t handle)
@@ -821,6 +842,7 @@
       mServingStackPointer(nullptr),
       mWorkSource(kUnsetWorkSource),
       mPropagateWorkSource(false),
+      mIsLooper(false),
       mStrictModePolicy(0),
       mLastTransactionBinderFlags(0),
       mCallRestriction(mProcess->mCallRestriction)
@@ -1401,6 +1423,7 @@
     IPCThreadState* state = self();
     state->mOut.writeInt32(BC_FREE_BUFFER);
     state->mOut.writePointer((uintptr_t)data);
+    state->flushIfNeeded();
 }
 
 } // namespace android
diff --git a/libs/binder/LazyServiceRegistrar.cpp b/libs/binder/LazyServiceRegistrar.cpp
index 1173138..f96b6bb 100644
--- a/libs/binder/LazyServiceRegistrar.cpp
+++ b/libs/binder/LazyServiceRegistrar.cpp
@@ -38,8 +38,7 @@
                          bool allowIsolated, int dumpFlags);
     void forcePersist(bool persist);
 
-    void setActiveServicesCountCallback(const std::function<bool(int)>&
-                                        activeServicesCountCallback);
+    void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback);
 
     bool tryUnregister();
 
@@ -82,13 +81,16 @@
     // count of services with clients
     size_t mNumConnectedServices;
 
+    // previous value passed to the active services callback
+    std::optional<bool> mPreviousHasClients;
+
     // map of registered names and services
     std::map<std::string, Service> mRegisteredServices;
 
     bool mForcePersist;
 
-    // Callback used to report the number of services with clients
-    std::function<bool(int)> mActiveServicesCountCallback;
+    // Callback used to report if there are services with clients
+    std::function<bool(bool)> mActiveServicesCallback;
 };
 
 class ClientCounterCallback {
@@ -103,8 +105,7 @@
      */
     void forcePersist(bool persist);
 
-    void setActiveServicesCountCallback(const std::function<bool(int)>&
-                                        activeServicesCountCallback);
+    void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback);
 
     bool tryUnregister();
 
@@ -158,7 +159,7 @@
 
 void ClientCounterCallbackImpl::forcePersist(bool persist) {
     mForcePersist = persist;
-    if (!mForcePersist && mNumConnectedServices == 0) {
+    if (!mForcePersist) {
         // Attempt a shutdown in case the number of clients hit 0 while the flag was on
         maybeTryShutdown();
     }
@@ -204,8 +205,12 @@
     }
 
     bool handledInCallback = false;
-    if (mActiveServicesCountCallback != nullptr) {
-        handledInCallback = mActiveServicesCountCallback(mNumConnectedServices);
+    if (mActiveServicesCallback != nullptr) {
+        bool hasClients = mNumConnectedServices != 0;
+        if (hasClients != mPreviousHasClients) {
+            handledInCallback = mActiveServicesCallback(hasClients);
+            mPreviousHasClients = hasClients;
+        }
     }
 
     // If there is no callback defined or the callback did not handle this
@@ -256,9 +261,9 @@
     reRegister();
 }
 
-void ClientCounterCallbackImpl::setActiveServicesCountCallback(const std::function<bool(int)>&
-                                                               activeServicesCountCallback) {
-    mActiveServicesCountCallback = activeServicesCountCallback;
+void ClientCounterCallbackImpl::setActiveServicesCallback(const std::function<bool(bool)>&
+                                                          activeServicesCallback) {
+    mActiveServicesCallback = activeServicesCallback;
 }
 
 ClientCounterCallback::ClientCounterCallback() {
@@ -274,9 +279,9 @@
     mImpl->forcePersist(persist);
 }
 
-void ClientCounterCallback::setActiveServicesCountCallback(const std::function<bool(int)>&
-                                                           activeServicesCountCallback) {
-    mImpl->setActiveServicesCountCallback(activeServicesCountCallback);
+void ClientCounterCallback::setActiveServicesCallback(const std::function<bool(bool)>&
+                                                      activeServicesCallback) {
+    mImpl->setActiveServicesCallback(activeServicesCallback);
 }
 
 bool ClientCounterCallback::tryUnregister() {
@@ -310,9 +315,9 @@
     mClientCC->forcePersist(persist);
 }
 
-void LazyServiceRegistrar::setActiveServicesCountCallback(const std::function<bool(int)>&
-                                                          activeServicesCountCallback) {
-    mClientCC->setActiveServicesCountCallback(activeServicesCountCallback);
+void LazyServiceRegistrar::setActiveServicesCallback(const std::function<bool(bool)>&
+                                                     activeServicesCallback) {
+    mClientCC->setActiveServicesCallback(activeServicesCallback);
 }
 
 bool LazyServiceRegistrar::tryUnregister() {
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index 4da8aa1..0183324 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -110,6 +110,7 @@
             status_t            setupPolling(int* fd);
             status_t            handlePolledCommands();
             void                flushCommands();
+            bool                flushIfNeeded();
 
             void                joinThreadPool(bool isMain = true);
             
@@ -204,6 +205,7 @@
             int32_t             mWorkSource;
             // Whether the work source should be propagated.
             bool                mPropagateWorkSource;
+            bool                mIsLooper;
             int32_t             mStrictModePolicy;
             int32_t             mLastTransactionBinderFlags;
             CallRestriction     mCallRestriction;
diff --git a/libs/binder/include/binder/LazyServiceRegistrar.h b/libs/binder/include/binder/LazyServiceRegistrar.h
index 73893c7..9659732 100644
--- a/libs/binder/include/binder/LazyServiceRegistrar.h
+++ b/libs/binder/include/binder/LazyServiceRegistrar.h
@@ -56,10 +56,10 @@
      void forcePersist(bool persist);
 
      /**
-      * Set a callback that is executed when the total number of services with
-      * clients changes.
-      * The callback takes an argument, which is the number of registered
-      * lazy services for this process which have clients.
+      * Set a callback that is invoked when the active service count (i.e. services with clients)
+      * registered with this process drops to zero (or becomes nonzero).
+      * The callback takes a boolean argument, which is 'true' if there is
+      * at least one service with clients.
       *
       * Callback return value:
       * - false: Default behavior for lazy services (shut down the process if there
@@ -73,8 +73,7 @@
       *
       * This method should be called before 'registerService' to avoid races.
       */
-     void setActiveServicesCountCallback(const std::function<bool(int)>&
-                                         activeServicesCountCallback);
+     void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback);
 
     /**
       * Try to unregister all services previously registered with 'registerService'.
diff --git a/libs/binder/ndk/include_cpp/android/binder_auto_utils.h b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
index 6b52c0a..0ad400b 100644
--- a/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
@@ -265,7 +265,18 @@
             AStatus_deleteDescription(cStr);
             return ret;
         }
-        return "(not available)";
+        binder_exception_t exception = getExceptionCode();
+        std::string desc = std::to_string(exception);
+        if (exception == EX_SERVICE_SPECIFIC) {
+            desc += " (" + std::to_string(getServiceSpecificError()) + ")";
+        } else if (exception == EX_TRANSACTION_FAILED) {
+            desc += " (" + std::to_string(getStatus()) + ")";
+        }
+        if (const char* msg = getMessage(); msg != nullptr) {
+            desc += ": ";
+            desc += msg;
+        }
+        return desc;
     }
 
     /**
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index b7df115..0d1989e 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -375,8 +375,7 @@
 
     AIBinder_decStrong(binder);
 
-    // assert because would need to decStrong if non-null and we shouldn't need to add a no-op here
-    ASSERT_NE(nullptr, AIBinder_Weak_promote(wBinder));
+    ASSERT_EQ(nullptr, AIBinder_Weak_promote(wBinder));
 
     AIBinder_Weak_delete(wBinder);
 }
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index f4b5a26..0a3d44d 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -117,11 +117,13 @@
 }
 
 BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface,
-                                   int width, int height, bool enableTripleBuffering)
+                                   int width, int height, int32_t format,
+                                   bool enableTripleBuffering)
       : mName(name),
         mSurfaceControl(surface),
         mSize(width, height),
         mRequestedSize(mSize),
+        mFormat(format),
         mNextTransaction(nullptr) {
     createBufferQueue(&mProducer, &mConsumer);
     // since the adapter is in the client process, set dequeue timeout
@@ -140,7 +142,7 @@
     mBufferItemConsumer->setFrameAvailableListener(this);
     mBufferItemConsumer->setBufferFreedListener(this);
     mBufferItemConsumer->setDefaultBufferSize(mSize.width, mSize.height);
-    mBufferItemConsumer->setDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888);
+    mBufferItemConsumer->setDefaultBufferFormat(format);
 
     mTransformHint = mSurfaceControl->getTransformHint();
     mBufferItemConsumer->setTransformHint(mTransformHint);
@@ -164,10 +166,16 @@
     t.apply();
 }
 
-void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height) {
+void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height,
+                              int32_t format) {
     std::unique_lock _lock{mMutex};
     mSurfaceControl = surface;
 
+    if (mFormat != format) {
+        mFormat = format;
+        mBufferItemConsumer->setDefaultBufferFormat(format);
+    }
+
     ui::Size newSize(width, height);
     if (mRequestedSize != newSize) {
         mRequestedSize.set(newSize);
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 97c2693..4a372bb 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1418,17 +1418,6 @@
 }
 
 SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFocusedWindow(
-        const sp<IBinder>& token, const sp<IBinder>& focusedToken, nsecs_t timestampNanos,
-        int32_t displayId) {
-    FocusRequest request;
-    request.token = token;
-    request.focusedToken = focusedToken;
-    request.timestamp = timestampNanos;
-    request.displayId = displayId;
-    return setFocusedWindow(request);
-}
-
-SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFocusedWindow(
         const FocusRequest& request) {
     mInputWindowCommands.focusRequests.push_back(request);
     return *this;
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index 0fbcbdc..411526e 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -68,7 +68,7 @@
 {
 public:
     BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width,
-                     int height, bool enableTripleBuffering = true);
+                     int height, int32_t format, bool enableTripleBuffering = true);
 
     sp<IGraphicBufferProducer> getIGraphicBufferProducer() const {
         return mProducer;
@@ -88,7 +88,7 @@
     void setTransactionCompleteCallback(uint64_t frameNumber,
                                         std::function<void(int64_t)>&& transactionCompleteCallback);
 
-    void update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height);
+    void update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format);
     void flushShadowQueue() { mFlushShadowQueue = true; }
 
     status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless);
@@ -136,6 +136,7 @@
 
     ui::Size mSize GUARDED_BY(mMutex);
     ui::Size mRequestedSize GUARDED_BY(mMutex);
+    int32_t mFormat GUARDED_BY(mMutex);
 
     uint32_t mTransformHint GUARDED_BY(mMutex);
 
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 48bc5d5..11db658 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -522,8 +522,6 @@
 
 #ifndef NO_INPUT
         Transaction& setInputWindowInfo(const sp<SurfaceControl>& sc, const InputWindowInfo& info);
-        Transaction& setFocusedWindow(const sp<IBinder>& token, const sp<IBinder>& focusedToken,
-                                      nsecs_t timestampNanos, int32_t displayId);
         Transaction& setFocusedWindow(const FocusRequest& request);
         Transaction& syncInputWindows();
 #endif
diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp
index d69b7c3..70e656d 100644
--- a/libs/gui/tests/BLASTBufferQueue_test.cpp
+++ b/libs/gui/tests/BLASTBufferQueue_test.cpp
@@ -45,11 +45,12 @@
 class BLASTBufferQueueHelper {
 public:
     BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) {
-        mBlastBufferQueueAdapter = new BLASTBufferQueue("TestBLASTBufferQueue", sc, width, height);
+        mBlastBufferQueueAdapter = new BLASTBufferQueue("TestBLASTBufferQueue", sc, width, height,
+                                                        PIXEL_FORMAT_RGBA_8888);
     }
 
     void update(const sp<SurfaceControl>& sc, int width, int height) {
-        mBlastBufferQueueAdapter->update(sc, width, height);
+        mBlastBufferQueueAdapter->update(sc, width, height, PIXEL_FORMAT_RGBA_8888);
     }
 
     void setNextTransaction(Transaction* next) {
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 3965ea0..31cbbdc 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -202,8 +202,14 @@
 
     void requestFocus() {
         SurfaceComposerClient::Transaction t;
-        t.setFocusedWindow(mInputInfo.token, nullptr, systemTime(SYSTEM_TIME_MONOTONIC),
-                           0 /* displayId */);
+        FocusRequest request;
+        request.token = mInputInfo.token;
+        request.windowName = mInputInfo.name;
+        request.focusedToken = nullptr;
+        request.focusedWindowName = "";
+        request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
+        request.displayId = 0;
+        t.setFocusedWindow(request);
         t.apply(true);
     }
 
diff --git a/libs/input/android/FocusRequest.aidl b/libs/input/android/FocusRequest.aidl
index 303dd1c..8812d34 100644
--- a/libs/input/android/FocusRequest.aidl
+++ b/libs/input/android/FocusRequest.aidl
@@ -22,6 +22,7 @@
      * Input channel token used to identify the window that should gain focus.
      */
     IBinder token;
+    @utf8InCpp String windowName;
     /**
      * The token that the caller expects currently to be focused. If the
      * specified token does not match the currently focused window, this request will be dropped.
@@ -30,6 +31,7 @@
      * is.
      */
     @nullable IBinder focusedToken;
+    @utf8InCpp String focusedWindowName;
     /**
      * SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm) when requesting the focus
      * change. This determines which request gets precedence if there is a focus change request
diff --git a/libs/renderengine/RenderEngine.cpp b/libs/renderengine/RenderEngine.cpp
index 45db31c..b2ad22d 100644
--- a/libs/renderengine/RenderEngine.cpp
+++ b/libs/renderengine/RenderEngine.cpp
@@ -51,11 +51,28 @@
             return renderengine::threaded::RenderEngineThreaded::create(
                     [args]() { return android::renderengine::gl::GLESRenderEngine::create(args); });
         case RenderEngineType::SKIA_GL:
+            ALOGD("RenderEngine with SkiaGL Backend");
             return renderengine::skia::SkiaGLRenderEngine::create(args);
-        case RenderEngineType::SKIA_GL_THREADED:
-            return renderengine::threaded::RenderEngineThreaded::create([args]() {
-                return android::renderengine::skia::SkiaGLRenderEngine::create(args);
+        case RenderEngineType::SKIA_GL_THREADED: {
+            // These need to be recreated, since they are a constant reference, and we need to
+            // let SkiaRE know that it's running as threaded, and all GL operation will happen on
+            // the same thread.
+            RenderEngineCreationArgs skiaArgs =
+                    RenderEngineCreationArgs::Builder()
+                            .setPixelFormat(args.pixelFormat)
+                            .setImageCacheSize(args.imageCacheSize)
+                            .setUseColorManagerment(args.useColorManagement)
+                            .setEnableProtectedContext(args.enableProtectedContext)
+                            .setPrecacheToneMapperShaderOnly(args.precacheToneMapperShaderOnly)
+                            .setSupportsBackgroundBlur(args.supportsBackgroundBlur)
+                            .setContextPriority(args.contextPriority)
+                            .setRenderEngineType(RenderEngineType::SKIA_GL_THREADED)
+                            .build();
+            ALOGD("Threaded RenderEngine with SkiaGL Backend");
+            return renderengine::threaded::RenderEngineThreaded::create([skiaArgs]() {
+                return android::renderengine::skia::SkiaGLRenderEngine::create(skiaArgs);
             });
+        }
         case RenderEngineType::GLES:
         default:
             ALOGD("RenderEngine with GLES Backend");
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index c88e298..70ae0b2 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -746,6 +746,7 @@
 }
 
 void GLESRenderEngine::cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
+    ATRACE_CALL();
     mImageManager->cacheAsync(buffer, nullptr);
 }
 
diff --git a/libs/renderengine/skia/AutoBackendTexture.h b/libs/renderengine/skia/AutoBackendTexture.h
index 30f4b77..bb75878 100644
--- a/libs/renderengine/skia/AutoBackendTexture.h
+++ b/libs/renderengine/skia/AutoBackendTexture.h
@@ -30,7 +30,7 @@
 namespace skia {
 
 /**
- * AutoBackendTexture manages GPU image  lifetime. It is a ref-counted object
+ * AutoBackendTexture manages GPU image lifetime. It is a ref-counted object
  * that keeps GPU resources alive until the last SkImage or SkSurface object using them is
  * destroyed.
  */
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index dc04f69..03e3339 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -267,7 +267,8 @@
         mPlaceholderSurface(placeholder),
         mProtectedEGLContext(protectedContext),
         mProtectedPlaceholderSurface(protectedPlaceholder),
-        mUseColorManagement(args.useColorManagement) {
+        mUseColorManagement(args.useColorManagement),
+        mRenderEngineType(args.renderEngineType) {
     sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
     LOG_ALWAYS_FATAL_IF(!glInterface.get());
 
@@ -453,7 +454,30 @@
     return colorTransform != mat4() || needsToneMapping(sourceDataspace, destinationDataspace);
 }
 
+void SkiaGLRenderEngine::cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
+    // Only run this if RE is running on its own thread. This way the access to GL
+    // operations is guaranteed to be happening on the same thread.
+    if (mRenderEngineType != RenderEngineType::SKIA_GL_THREADED) {
+        return;
+    }
+    ATRACE_CALL();
+
+    std::lock_guard<std::mutex> lock(mRenderingMutex);
+    auto iter = mTextureCache.find(buffer->getId());
+    if (iter != mTextureCache.end()) {
+        ALOGV("Texture already exists in cache.");
+        return;
+    } else {
+        std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef =
+                std::make_shared<AutoBackendTexture::LocalRef>();
+        imageTextureRef->setTexture(
+                new AutoBackendTexture(mGrContext.get(), buffer->toAHardwareBuffer(), false));
+        mTextureCache.insert({buffer->getId(), imageTextureRef});
+    }
+}
+
 void SkiaGLRenderEngine::unbindExternalTextureBuffer(uint64_t bufferId) {
+    ATRACE_CALL();
     std::lock_guard<std::mutex> lock(mRenderingMutex);
     mTextureCache.erase(bufferId);
     mProtectedTextureCache.erase(bufferId);
@@ -523,11 +547,13 @@
         auto iter = cache.find(buffer->getId());
         if (iter != cache.end()) {
             ALOGV("Cache hit!");
+            ATRACE_NAME("Cache hit");
             surfaceTextureRef = iter->second;
         }
     }
 
     if (surfaceTextureRef == nullptr || surfaceTextureRef->getTexture() == nullptr) {
+        ATRACE_NAME("Cache miss");
         surfaceTextureRef = std::make_shared<AutoBackendTexture::LocalRef>();
         surfaceTextureRef->setTexture(
                 new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer(), true));
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h
index ed62a2a..e344f41 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -50,6 +50,7 @@
                        EGLSurface protectedPlaceholder);
     ~SkiaGLRenderEngine() override EXCLUDES(mRenderingMutex);
 
+    void cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) override;
     void unbindExternalTextureBuffer(uint64_t bufferId) override;
     status_t drawLayers(const DisplaySettings& display,
                         const std::vector<const LayerSettings*>& layers,
@@ -128,6 +129,10 @@
     bool mInProtectedContext = false;
     // Object to capture commands send to Skia.
     std::unique_ptr<SkiaCapture> mCapture;
+
+    // Keep this information as a local variable to determine whether the access of the GL
+    // operations is working on the same threads.
+    const RenderEngineType mRenderEngineType = RenderEngineType::SKIA_GL;
 };
 
 } // namespace skia
diff --git a/libs/renderengine/tests/RenderEngineThreadedTest.cpp b/libs/renderengine/tests/RenderEngineThreadedTest.cpp
index ba5175d..02ff06f 100644
--- a/libs/renderengine/tests/RenderEngineThreadedTest.cpp
+++ b/libs/renderengine/tests/RenderEngineThreadedTest.cpp
@@ -62,22 +62,6 @@
     mThreadedRE->deleteTextures(1, &texName);
 }
 
-TEST_F(RenderEngineThreadedTest, cacheExternalTextureBuffer_nullptr) {
-    EXPECT_CALL(*mRenderEngine, cacheExternalTextureBuffer(Eq(nullptr)));
-    mThreadedRE->cacheExternalTextureBuffer(nullptr);
-}
-
-TEST_F(RenderEngineThreadedTest, cacheExternalTextureBuffer_withBuffer) {
-    sp<GraphicBuffer> buf = new GraphicBuffer();
-    EXPECT_CALL(*mRenderEngine, cacheExternalTextureBuffer(buf));
-    mThreadedRE->cacheExternalTextureBuffer(buf);
-}
-
-TEST_F(RenderEngineThreadedTest, unbindExternalTextureBuffer) {
-    EXPECT_CALL(*mRenderEngine, unbindExternalTextureBuffer(0x0));
-    mThreadedRE->unbindExternalTextureBuffer(0x0);
-}
-
 TEST_F(RenderEngineThreadedTest, getMaxTextureSize_returns20) {
     size_t size = 20;
     EXPECT_CALL(*mRenderEngine, getMaxTextureSize()).WillOnce(Return(size));
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.cpp b/libs/renderengine/threaded/RenderEngineThreaded.cpp
index 08f2949..3b97f56 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.cpp
+++ b/libs/renderengine/threaded/RenderEngineThreaded.cpp
@@ -147,33 +147,29 @@
 }
 
 void RenderEngineThreaded::cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
-    std::promise<void> resultPromise;
-    std::future<void> resultFuture = resultPromise.get_future();
+    // This function is designed so it can run asynchronously, so we do not need to wait
+    // for the futures.
     {
         std::lock_guard lock(mThreadMutex);
-        mFunctionCalls.push([&resultPromise, &buffer](renderengine::RenderEngine& instance) {
+        mFunctionCalls.push([=](renderengine::RenderEngine& instance) {
             ATRACE_NAME("REThreaded::cacheExternalTextureBuffer");
             instance.cacheExternalTextureBuffer(buffer);
-            resultPromise.set_value();
         });
     }
     mCondition.notify_one();
-    resultFuture.wait();
 }
 
 void RenderEngineThreaded::unbindExternalTextureBuffer(uint64_t bufferId) {
-    std::promise<void> resultPromise;
-    std::future<void> resultFuture = resultPromise.get_future();
+    // This function is designed so it can run asynchronously, so we do not need to wait
+    // for the futures.
     {
         std::lock_guard lock(mThreadMutex);
-        mFunctionCalls.push([&resultPromise, &bufferId](renderengine::RenderEngine& instance) {
+        mFunctionCalls.push([=](renderengine::RenderEngine& instance) {
             ATRACE_NAME("REThreaded::unbindExternalTextureBuffer");
             instance.unbindExternalTextureBuffer(bufferId);
-            resultPromise.set_value();
         });
     }
     mCondition.notify_one();
-    resultFuture.wait();
 }
 
 size_t RenderEngineThreaded::getMaxTextureSize() const {
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index b3558c6..fff0239 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -127,6 +127,13 @@
     return value ? "true" : "false";
 }
 
+static inline const std::string toString(sp<IBinder> binder) {
+    if (binder == nullptr) {
+        return "<null>";
+    }
+    return StringPrintf("%p", binder.get());
+}
+
 static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
     return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
             AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
@@ -2470,19 +2477,20 @@
 
 std::string InputDispatcher::dumpWindowForTouchOcclusion(const InputWindowInfo* info,
                                                          bool isTouchedWindow) const {
-    return StringPrintf(INDENT2 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32
-                                ", mode=%s, alpha=%.2f, "
-                                "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
-                                "], touchableRegion=%s, window={%s}, applicationInfo=%s, "
-                                "flags={%s}, inputFeatures={%s}, hasToken=%s\n",
+    return StringPrintf(INDENT2
+                        "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
+                        "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
+                        "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
+                        "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
                         (isTouchedWindow) ? "[TOUCHED] " : "",
                         NamedEnum::string(info->type, "%" PRId32).c_str(),
                         info->packageName.c_str(), info->ownerUid, info->id,
                         toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
                         info->frameTop, info->frameRight, info->frameBottom,
                         dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
-                        info->applicationInfo.name.c_str(), info->flags.string().c_str(),
-                        info->inputFeatures.string().c_str(), toString(info->token != nullptr));
+                        info->flags.string().c_str(), info->inputFeatures.string().c_str(),
+                        toString(info->token != nullptr), info->applicationInfo.name.c_str(),
+                        toString(info->applicationInfo.token).c_str());
 }
 
 bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
@@ -4797,7 +4805,8 @@
                                                  "hasWallpaper=%s, visible=%s, alpha=%.2f, "
                                                  "flags=%s, type=%s, "
                                                  "frame=[%d,%d][%d,%d], globalScale=%f, "
-                                                 "applicationInfo=%s, "
+                                                 "applicationInfo.name=%s, "
+                                                 "applicationInfo.token=%s, "
                                                  "touchableRegion=",
                                          i, windowInfo->name.c_str(), windowInfo->id,
                                          windowInfo->displayId, windowInfo->portalToDisplayId,
@@ -4810,7 +4819,8 @@
                                          windowInfo->frameLeft, windowInfo->frameTop,
                                          windowInfo->frameRight, windowInfo->frameBottom,
                                          windowInfo->globalScaleFactor,
-                                         windowInfo->applicationInfo.name.c_str());
+                                         windowInfo->applicationInfo.name.c_str(),
+                                         toString(windowInfo->applicationInfo.token).c_str());
                     dump += dumpRegion(windowInfo->touchableRegion);
                     dump += StringPrintf(", inputFeatures=%s",
                                          windowInfo->inputFeatures.string().c_str());