Loading libs/gui/tests/RegionSampling_test.cpp +13 −0 Original line number Diff line number Diff line Loading @@ -240,6 +240,19 @@ protected: float const luma_gray = 0.50; }; TEST_F(RegionSamplingTest, invalidLayerHandle_doesNotCrash) { sp<ISurfaceComposer> composer = ComposerService::getComposerService(); sp<Listener> listener = new Listener(); const Rect sampleArea{100, 100, 200, 200}; // Passing in composer service as the layer handle should not crash, we'll // treat it as a layer that no longer exists and silently allow sampling to // occur. status_t status = composer->addRegionSamplingListener(sampleArea, IInterface::asBinder(composer), listener); ASSERT_EQ(NO_ERROR, status); composer->removeRegionSamplingListener(listener); } TEST_F(RegionSamplingTest, DISABLED_CollectsLuma) { fill_render(rgba_green); Loading services/surfaceflinger/RegionSamplingThread.cpp +1 −6 Original line number Diff line number Diff line Loading @@ -199,13 +199,8 @@ RegionSamplingThread::~RegionSamplingThread() { } } void RegionSamplingThread::addListener(const Rect& samplingArea, const sp<IBinder>& stopLayerHandle, void RegionSamplingThread::addListener(const Rect& samplingArea, const wp<Layer>& stopLayer, const sp<IRegionSamplingListener>& listener) { wp<Layer> stopLayer; if (stopLayerHandle != nullptr && stopLayerHandle->localBinder() != nullptr) { stopLayer = static_cast<Layer::Handle*>(stopLayerHandle.get())->owner; } sp<IBinder> asBinder = IInterface::asBinder(listener); asBinder->linkToDeath(this); std::lock_guard lock(mSamplingMutex); Loading services/surfaceflinger/RegionSamplingThread.h +1 −1 Original line number Diff line number Diff line Loading @@ -69,7 +69,7 @@ public: // Add a listener to receive luma notifications. The luma reported via listener will // report the median luma for the layers under the stopLayerHandle, in the samplingArea region. void addListener(const Rect& samplingArea, const sp<IBinder>& stopLayerHandle, void addListener(const Rect& samplingArea, const wp<Layer>& stopLayer, const sp<IRegionSamplingListener>& listener); // Remove the listener to stop receiving median luma notifications. void removeListener(const sp<IRegionSamplingListener>& listener); Loading services/surfaceflinger/SurfaceFlinger.cpp +15 −8 Original line number Diff line number Diff line Loading @@ -1454,7 +1454,9 @@ status_t SurfaceFlinger::addRegionSamplingListener(const Rect& samplingArea, if (!listener || samplingArea == Rect::INVALID_RECT) { return BAD_VALUE; } mRegionSamplingThread->addListener(samplingArea, stopLayerHandle, listener); const wp<Layer> stopLayer = fromHandle(stopLayerHandle); mRegionSamplingThread->addListener(samplingArea, stopLayer, listener); return NO_ERROR; } Loading Loading @@ -3160,7 +3162,7 @@ status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBind Mutex::Autolock _l(mStateLock); sp<Layer> parent; if (parentHandle != nullptr) { parent = fromHandle(parentHandle); parent = fromHandleLocked(parentHandle).promote(); if (parent == nullptr) { return NAME_NOT_FOUND; } Loading Loading @@ -3534,7 +3536,7 @@ uint32_t SurfaceFlinger::setClientStateLocked( sp<Layer> layer = nullptr; if (s.surface) { layer = fromHandle(s.surface); layer = fromHandleLocked(s.surface).promote(); } else { // The client may provide us a null handle. Treat it as if the layer was removed. ALOGW("Attempt to set client state with a null layer handle"); Loading Loading @@ -3850,7 +3852,7 @@ status_t SurfaceFlinger::mirrorLayer(const sp<Client>& client, const sp<IBinder> { Mutex::Autolock _l(mStateLock); mirrorFrom = fromHandle(mirrorFromHandle); mirrorFrom = fromHandleLocked(mirrorFromHandle).promote(); if (!mirrorFrom) { return NAME_NOT_FOUND; } Loading Loading @@ -5562,7 +5564,7 @@ status_t SurfaceFlinger::captureLayers( { Mutex::Autolock lock(mStateLock); parent = fromHandle(layerHandleBinder); parent = fromHandleLocked(layerHandleBinder).promote(); if (parent == nullptr || parent->isRemovedFromCurrentState()) { ALOGE("captureLayers called with an invalid or removed parent"); return NAME_NOT_FOUND; Loading Loading @@ -5595,7 +5597,7 @@ status_t SurfaceFlinger::captureLayers( reqHeight = crop.height() * frameScale; for (const auto& handle : excludeHandles) { sp<Layer> excludeLayer = fromHandle(handle); sp<Layer> excludeLayer = fromHandleLocked(handle).promote(); if (excludeLayer != nullptr) { excludeLayers.emplace(excludeLayer); } else { Loading Loading @@ -6058,7 +6060,12 @@ void SurfaceFlinger::SetInputWindowsListener::onSetInputWindowsFinished() { mFlinger->setInputWindowsFinished(); } sp<Layer> SurfaceFlinger::fromHandle(const sp<IBinder>& handle) { wp<Layer> SurfaceFlinger::fromHandle(const sp<IBinder>& handle) { Mutex::Autolock _l(mStateLock); return fromHandleLocked(handle); } wp<Layer> SurfaceFlinger::fromHandleLocked(const sp<IBinder>& handle) { BBinder* b = nullptr; if (handle) { b = handle->localBinder(); Loading @@ -6068,7 +6075,7 @@ sp<Layer> SurfaceFlinger::fromHandle(const sp<IBinder>& handle) { } auto it = mLayersByLocalBinderToken.find(b); if (it != mLayersByLocalBinderToken.end()) { return it->second.promote(); return it->second; } return nullptr; } Loading services/surfaceflinger/SurfaceFlinger.h +6 −1 Original line number Diff line number Diff line Loading @@ -331,7 +331,12 @@ public: return mTransactionCompletedThread; } sp<Layer> fromHandle(const sp<IBinder>& handle) REQUIRES(mStateLock); // Converts from a binder handle to a Layer // Returns nullptr if the handle does not point to an existing layer. // Otherwise, returns a weak reference so that callers off the main-thread // won't accidentally hold onto the last strong reference. wp<Layer> fromHandle(const sp<IBinder>& handle); wp<Layer> fromHandleLocked(const sp<IBinder>& handle) REQUIRES(mStateLock); // Inherit from ClientCache::ErasedRecipient void bufferErased(const client_cache_t& clientCacheId) override; Loading Loading
libs/gui/tests/RegionSampling_test.cpp +13 −0 Original line number Diff line number Diff line Loading @@ -240,6 +240,19 @@ protected: float const luma_gray = 0.50; }; TEST_F(RegionSamplingTest, invalidLayerHandle_doesNotCrash) { sp<ISurfaceComposer> composer = ComposerService::getComposerService(); sp<Listener> listener = new Listener(); const Rect sampleArea{100, 100, 200, 200}; // Passing in composer service as the layer handle should not crash, we'll // treat it as a layer that no longer exists and silently allow sampling to // occur. status_t status = composer->addRegionSamplingListener(sampleArea, IInterface::asBinder(composer), listener); ASSERT_EQ(NO_ERROR, status); composer->removeRegionSamplingListener(listener); } TEST_F(RegionSamplingTest, DISABLED_CollectsLuma) { fill_render(rgba_green); Loading
services/surfaceflinger/RegionSamplingThread.cpp +1 −6 Original line number Diff line number Diff line Loading @@ -199,13 +199,8 @@ RegionSamplingThread::~RegionSamplingThread() { } } void RegionSamplingThread::addListener(const Rect& samplingArea, const sp<IBinder>& stopLayerHandle, void RegionSamplingThread::addListener(const Rect& samplingArea, const wp<Layer>& stopLayer, const sp<IRegionSamplingListener>& listener) { wp<Layer> stopLayer; if (stopLayerHandle != nullptr && stopLayerHandle->localBinder() != nullptr) { stopLayer = static_cast<Layer::Handle*>(stopLayerHandle.get())->owner; } sp<IBinder> asBinder = IInterface::asBinder(listener); asBinder->linkToDeath(this); std::lock_guard lock(mSamplingMutex); Loading
services/surfaceflinger/RegionSamplingThread.h +1 −1 Original line number Diff line number Diff line Loading @@ -69,7 +69,7 @@ public: // Add a listener to receive luma notifications. The luma reported via listener will // report the median luma for the layers under the stopLayerHandle, in the samplingArea region. void addListener(const Rect& samplingArea, const sp<IBinder>& stopLayerHandle, void addListener(const Rect& samplingArea, const wp<Layer>& stopLayer, const sp<IRegionSamplingListener>& listener); // Remove the listener to stop receiving median luma notifications. void removeListener(const sp<IRegionSamplingListener>& listener); Loading
services/surfaceflinger/SurfaceFlinger.cpp +15 −8 Original line number Diff line number Diff line Loading @@ -1454,7 +1454,9 @@ status_t SurfaceFlinger::addRegionSamplingListener(const Rect& samplingArea, if (!listener || samplingArea == Rect::INVALID_RECT) { return BAD_VALUE; } mRegionSamplingThread->addListener(samplingArea, stopLayerHandle, listener); const wp<Layer> stopLayer = fromHandle(stopLayerHandle); mRegionSamplingThread->addListener(samplingArea, stopLayer, listener); return NO_ERROR; } Loading Loading @@ -3160,7 +3162,7 @@ status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBind Mutex::Autolock _l(mStateLock); sp<Layer> parent; if (parentHandle != nullptr) { parent = fromHandle(parentHandle); parent = fromHandleLocked(parentHandle).promote(); if (parent == nullptr) { return NAME_NOT_FOUND; } Loading Loading @@ -3534,7 +3536,7 @@ uint32_t SurfaceFlinger::setClientStateLocked( sp<Layer> layer = nullptr; if (s.surface) { layer = fromHandle(s.surface); layer = fromHandleLocked(s.surface).promote(); } else { // The client may provide us a null handle. Treat it as if the layer was removed. ALOGW("Attempt to set client state with a null layer handle"); Loading Loading @@ -3850,7 +3852,7 @@ status_t SurfaceFlinger::mirrorLayer(const sp<Client>& client, const sp<IBinder> { Mutex::Autolock _l(mStateLock); mirrorFrom = fromHandle(mirrorFromHandle); mirrorFrom = fromHandleLocked(mirrorFromHandle).promote(); if (!mirrorFrom) { return NAME_NOT_FOUND; } Loading Loading @@ -5562,7 +5564,7 @@ status_t SurfaceFlinger::captureLayers( { Mutex::Autolock lock(mStateLock); parent = fromHandle(layerHandleBinder); parent = fromHandleLocked(layerHandleBinder).promote(); if (parent == nullptr || parent->isRemovedFromCurrentState()) { ALOGE("captureLayers called with an invalid or removed parent"); return NAME_NOT_FOUND; Loading Loading @@ -5595,7 +5597,7 @@ status_t SurfaceFlinger::captureLayers( reqHeight = crop.height() * frameScale; for (const auto& handle : excludeHandles) { sp<Layer> excludeLayer = fromHandle(handle); sp<Layer> excludeLayer = fromHandleLocked(handle).promote(); if (excludeLayer != nullptr) { excludeLayers.emplace(excludeLayer); } else { Loading Loading @@ -6058,7 +6060,12 @@ void SurfaceFlinger::SetInputWindowsListener::onSetInputWindowsFinished() { mFlinger->setInputWindowsFinished(); } sp<Layer> SurfaceFlinger::fromHandle(const sp<IBinder>& handle) { wp<Layer> SurfaceFlinger::fromHandle(const sp<IBinder>& handle) { Mutex::Autolock _l(mStateLock); return fromHandleLocked(handle); } wp<Layer> SurfaceFlinger::fromHandleLocked(const sp<IBinder>& handle) { BBinder* b = nullptr; if (handle) { b = handle->localBinder(); Loading @@ -6068,7 +6075,7 @@ sp<Layer> SurfaceFlinger::fromHandle(const sp<IBinder>& handle) { } auto it = mLayersByLocalBinderToken.find(b); if (it != mLayersByLocalBinderToken.end()) { return it->second.promote(); return it->second; } return nullptr; } Loading
services/surfaceflinger/SurfaceFlinger.h +6 −1 Original line number Diff line number Diff line Loading @@ -331,7 +331,12 @@ public: return mTransactionCompletedThread; } sp<Layer> fromHandle(const sp<IBinder>& handle) REQUIRES(mStateLock); // Converts from a binder handle to a Layer // Returns nullptr if the handle does not point to an existing layer. // Otherwise, returns a weak reference so that callers off the main-thread // won't accidentally hold onto the last strong reference. wp<Layer> fromHandle(const sp<IBinder>& handle); wp<Layer> fromHandleLocked(const sp<IBinder>& handle) REQUIRES(mStateLock); // Inherit from ClientCache::ErasedRecipient void bufferErased(const client_cache_t& clientCacheId) override; Loading