Merge "Caching images and textures for threaded Skia RE"
diff --git a/.gitignore b/.gitignore
index 685e379..ed653c6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
 *.iml
 *.pyc
 .idea/
+.vscode/
+*.code-workspace
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/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/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
index 0ca3a07..bb70588 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
@@ -660,13 +660,15 @@
 /**
  * Whether AIBinder is less than another.
  *
- * This provides a per-process-unique total ordering of binders determined by
- * an underlying allocation address where a null AIBinder* is considered to be
- * ordered before all other binders.
+ * This provides a per-process-unique total ordering of binders where a null
+ * AIBinder* object is considered to be before all other binder objects.
+ * For instance, two binders refer to the same object in a local or remote
+ * process when both AIBinder_lt(a, b) and AIBinder(b, a) are false. This API
+ * might be used to insert and lookup binders in binary search trees.
  *
  * AIBinder* pointers themselves actually also create a per-process-unique total
  * ordering. However, this ordering is inconsistent with AIBinder_Weak_lt for
- * remote binders.
+ * remote binders. So, in general, this function should be preferred.
  *
  * Available since API level 31.
  *
@@ -698,14 +700,21 @@
  * the same as AIBinder_lt. Similarly, a null AIBinder_Weak* is considered to be
  * ordered before all other weak references.
  *
- * If you have many AIBinder_Weak* objects which are all references to distinct
- * binder objects which happen to have the same underlying address (as ordered
- * by AIBinder_lt), these AIBinder_Weak* objects will retain the same order with
- * respect to all other AIBinder_Weak* pointers with different underlying
- * addresses and are also guaranteed to have a per-process-unique ordering. That
- * is, even though multiple AIBinder* instances may happen to be allocated at
- * the same underlying address, this function will still correctly distinguish
- * that these are weak pointers to different binder objects.
+ * This function correctly distinguishes binders even if one is deallocated. So,
+ * for instance, an AIBinder_Weak* entry representing a deleted binder will
+ * never compare as equal to an AIBinder_Weak* entry which represents a
+ * different allocation of a binder, even if the two binders were originally
+ * allocated at the same address. That is:
+ *
+ *     AIBinder* a = ...; // imagine this has address 0x8
+ *     AIBinder_Weak* bWeak = AIBinder_Weak_new(a);
+ *     AIBinder_decStrong(a); // a may be deleted, if this is the last reference
+ *     AIBinder* b = ...; // imagine this has address 0x8 (same address as b)
+ *     AIBinder_Weak* bWeak = AIBinder_Weak_new(b);
+ *
+ * Then when a/b are compared with other binders, their order will be preserved,
+ * and it will either be the case that AIBinder_Weak_lt(aWeak, bWeak) OR
+ * AIBinder_Weak_lt(bWeak, aWeak), but not both.
  *
  * Unlike AIBinder*, the AIBinder_Weak* addresses themselves have nothing to do
  * with the underlying binder.
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/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
index 7b9c012..17d1f3b 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
@@ -481,22 +481,22 @@
 
 void SurfaceFrame::trace(int64_t displayFrameToken) {
     using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
-    {
+
+    int64_t expectedTimelineCookie = mTraceCookieCounter.getCookieForTracing();
+    bool missingToken = false;
+    // Expected timeline start
+    FrameTimelineDataSource::Trace([&](FrameTimelineDataSource::TraceContext ctx) {
         std::lock_guard<std::mutex> lock(mMutex);
         if (mToken == ISurfaceComposer::INVALID_VSYNC_ID) {
             ALOGD("Cannot trace SurfaceFrame - %s with invalid token", mLayerName.c_str());
+            missingToken = true;
             return;
         } else if (displayFrameToken == ISurfaceComposer::INVALID_VSYNC_ID) {
             ALOGD("Cannot trace SurfaceFrame  - %s with invalid displayFrameToken",
                   mLayerName.c_str());
+            missingToken = true;
             return;
         }
-    }
-
-    int64_t expectedTimelineCookie = mTraceCookieCounter.getCookieForTracing();
-    // Expected timeline start
-    FrameTimelineDataSource::Trace([&](FrameTimelineDataSource::TraceContext ctx) {
-        std::lock_guard<std::mutex> lock(mMutex);
         auto packet = ctx.NewTracePacket();
         packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
         packet->set_timestamp(static_cast<uint64_t>(mPredictions.startTime));
@@ -512,6 +512,13 @@
         expectedSurfaceFrameStartEvent->set_pid(mOwnerPid);
         expectedSurfaceFrameStartEvent->set_layer_name(mDebugName);
     });
+
+    if (missingToken) {
+        // If one packet can't be traced because of missing token, then no packets can be traced.
+        // Exit early in this case.
+        return;
+    }
+
     // Expected timeline end
     FrameTimelineDataSource::Trace([&](FrameTimelineDataSource::TraceContext ctx) {
         std::lock_guard<std::mutex> lock(mMutex);
@@ -814,15 +821,16 @@
 }
 
 void FrameTimeline::DisplayFrame::trace(pid_t surfaceFlingerPid) const {
-    if (mToken == ISurfaceComposer::INVALID_VSYNC_ID) {
-        ALOGD("Cannot trace DisplayFrame with invalid token");
-        return;
-    }
-
     int64_t expectedTimelineCookie = mTraceCookieCounter.getCookieForTracing();
+    bool missingToken = false;
     // Expected timeline start
     FrameTimelineDataSource::Trace([&](FrameTimelineDataSource::TraceContext ctx) {
         auto packet = ctx.NewTracePacket();
+        if (mToken == ISurfaceComposer::INVALID_VSYNC_ID) {
+            ALOGD("Cannot trace DisplayFrame with invalid token");
+            missingToken = true;
+            return;
+        }
         packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
         packet->set_timestamp(static_cast<uint64_t>(mSurfaceFlingerPredictions.startTime));
 
@@ -834,6 +842,13 @@
         expectedDisplayFrameStartEvent->set_token(mToken);
         expectedDisplayFrameStartEvent->set_pid(surfaceFlingerPid);
     });
+
+    if (missingToken) {
+        // If one packet can't be traced because of missing token, then no packets can be traced.
+        // Exit early in this case.
+        return;
+    }
+
     // Expected timeline end
     FrameTimelineDataSource::Trace([&](FrameTimelineDataSource::TraceContext ctx) {
         auto packet = ctx.NewTracePacket();
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a6531e1..d91b542 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -276,6 +276,7 @@
 const String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
 const String16 sRotateSurfaceFlinger("android.permission.ROTATE_SURFACE_FLINGER");
 const String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
+const String16 sUseBackgroundBlur("android.permission.USE_BACKGROUND_BLUR");
 const String16 sDump("android.permission.DUMP");
 const char* KERNEL_IDLE_TIMER_PROP = "graphics.display.kernel_idle_timer.enabled";
 
@@ -333,6 +334,10 @@
             PermissionCache::checkPermission(sRotateSurfaceFlinger, pid, uid);
 }
 
+bool originalCallerCanUseBlurs(int originPid, int originUid) {
+    return PermissionCache::checkPermission(sUseBackgroundBlur, originPid, originUid);
+}
+
 SurfaceFlingerBE::SurfaceFlingerBE() : mHwcServiceName(getHwcServiceName()) {}
 
 SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
@@ -3438,9 +3443,10 @@
     std::unordered_set<ListenerCallbacks, ListenerCallbacksHash> listenerCallbacksWithSurfaces;
     uint32_t clientStateFlags = 0;
     for (const ComposerState& state : states) {
-        clientStateFlags |= setClientStateLocked(frameTimelineVsyncId, state, desiredPresentTime,
-                                                 isAutoTimestamp, postTime, privileged,
-                                                 listenerCallbacksWithSurfaces);
+        clientStateFlags |=
+                setClientStateLocked(frameTimelineVsyncId, state, desiredPresentTime,
+                                     isAutoTimestamp, postTime, privileged,
+                                     listenerCallbacksWithSurfaces, originPid, originUid);
         if ((flags & eAnimation) && state.state.surface) {
             if (const auto layer = fromHandleLocked(state.state.surface).promote(); layer) {
                 mScheduler->recordLayerHistory(layer.get(),
@@ -3620,7 +3626,8 @@
 uint32_t SurfaceFlinger::setClientStateLocked(
         int64_t frameTimelineVsyncId, const ComposerState& composerState,
         int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, bool privileged,
-        std::unordered_set<ListenerCallbacks, ListenerCallbacksHash>& listenerCallbacks) {
+        std::unordered_set<ListenerCallbacks, ListenerCallbacksHash>& listenerCallbacks,
+        int originPid, int originUid) {
     const layer_state_t& s = composerState.state;
 
     for (auto& listener : s.listeners) {
@@ -3764,10 +3771,14 @@
         if (layer->setCornerRadius(s.cornerRadius))
             flags |= eTraversalNeeded;
     }
-    if (what & layer_state_t::eBackgroundBlurRadiusChanged && !mDisableBlurs && mSupportsBlur) {
+
+    if (what & layer_state_t::eBackgroundBlurRadiusChanged && !mDisableBlurs && mSupportsBlur &&
+        originalCallerCanUseBlurs(originPid, originUid)) {
         if (layer->setBackgroundBlurRadius(s.backgroundBlurRadius)) flags |= eTraversalNeeded;
     }
-    if (what & layer_state_t::eBlurRegionsChanged) {
+
+    if (what & layer_state_t::eBlurRegionsChanged &&
+        originalCallerCanUseBlurs(originPid, originUid)) {
         if (layer->setBlurRegions(s.blurRegions)) flags |= eTraversalNeeded;
     }
     if (what & layer_state_t::eLayerStackChanged) {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 7253593..b2b7cac 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -344,8 +344,8 @@
     virtual uint32_t setClientStateLocked(
             int64_t frameTimelineVsyncId, const ComposerState& composerState,
             int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, bool privileged,
-            std::unordered_set<ListenerCallbacks, ListenerCallbacksHash>& listenerCallbacks)
-            REQUIRES(mStateLock);
+            std::unordered_set<ListenerCallbacks, ListenerCallbacksHash>& listenerCallbacks,
+            int originPid, int originUid) REQUIRES(mStateLock);
     virtual void commitTransactionLocked();
 
     // Used internally by computeLayerBounds() to gets the clip rectangle to use for the