diff options
-rw-r--r-- | include/gui/ISurfaceComposer.h | 14 | ||||
-rw-r--r-- | include/gui/SurfaceComposerClient.h | 4 | ||||
-rw-r--r-- | include/gui/SurfaceControl.h | 4 | ||||
-rw-r--r-- | include/private/gui/LayerState.h | 2 | ||||
-rw-r--r-- | libs/gui/ISurfaceComposer.cpp | 18 | ||||
-rw-r--r-- | libs/gui/LayerState.cpp | 2 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 32 | ||||
-rw-r--r-- | libs/gui/SurfaceControl.cpp | 8 | ||||
-rw-r--r-- | libs/gui/tests/Surface_test.cpp | 4 | ||||
-rw-r--r-- | services/surfaceflinger/Client.cpp | 29 | ||||
-rw-r--r-- | services/surfaceflinger/Client.h | 9 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 28 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 1 | ||||
-rw-r--r-- | services/surfaceflinger/MonitoredProducer.cpp | 11 | ||||
-rw-r--r-- | services/surfaceflinger/MonitoredProducer.h | 9 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 44 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 1 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger_hwc1.cpp | 44 |
18 files changed, 237 insertions, 27 deletions
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h index ff04e2f276..8af4d46555 100644 --- a/include/gui/ISurfaceComposer.h +++ b/include/gui/ISurfaceComposer.h @@ -78,6 +78,17 @@ public: */ virtual sp<ISurfaceComposerClient> createConnection() = 0; + /** create a scoped connection with surface flinger. + * Surfaces produced with this connection will act + * as children of the passed in GBP. That is to say + * SurfaceFlinger will draw them relative and confined to + * drawing of buffers from the layer associated with parent. + * As this is graphically equivalent in reach to just drawing + * pixels into the parent buffers, it requires no special permission. + */ + virtual sp<ISurfaceComposerClient> createScopedConnection( + const sp<IGraphicBufferProducer>& parent) = 0; + /* create a graphic buffer allocator */ virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc() = 0; @@ -216,7 +227,8 @@ public: GET_ACTIVE_COLOR_MODE, SET_ACTIVE_COLOR_MODE, ENABLE_VSYNC_INJECTIONS, - INJECT_VSYNC + INJECT_VSYNC, + CREATE_SCOPED_CONNECTION }; virtual status_t onTransact(uint32_t code, const Parcel& data, diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h index 789dc7c932..f537020b26 100644 --- a/include/gui/SurfaceComposerClient.h +++ b/include/gui/SurfaceComposerClient.h @@ -52,6 +52,7 @@ class SurfaceComposerClient : public RefBase friend class Composer; public: SurfaceComposerClient(); + SurfaceComposerClient(const sp<IGraphicBufferProducer>& parent); virtual ~SurfaceComposerClient(); // Always make sure we could initialize @@ -154,6 +155,8 @@ public: status_t setLayerStack(const sp<IBinder>& id, uint32_t layerStack); status_t deferTransactionUntil(const sp<IBinder>& id, const sp<IBinder>& handle, uint64_t frameNumber); + status_t reparentChildren(const sp<IBinder>& id, + const sp<IBinder>& newParentHandle); status_t setOverrideScalingMode(const sp<IBinder>& id, int32_t overrideScalingMode); status_t setGeometryAppliesWithResize(const sp<IBinder>& id); @@ -201,6 +204,7 @@ private: status_t mStatus; sp<ISurfaceComposerClient> mClient; Composer& mComposer; + wp<IGraphicBufferProducer> mParent; }; // --------------------------------------------------------------------------- diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h index 62217ad107..2dcbfa79f9 100644 --- a/include/gui/SurfaceControl.h +++ b/include/gui/SurfaceControl.h @@ -82,7 +82,9 @@ public: // Defers applying any changes made in this transaction until the Layer // identified by handle reaches the given frameNumber - status_t deferTransactionUntil(sp<IBinder> handle, uint64_t frameNumber); + status_t deferTransactionUntil(const sp<IBinder>& handle, uint64_t frameNumber); + // Reparents all children of this layer to the new parent handle. + status_t reparentChildren(const sp<IBinder>& newParentHandle); // Set an override scaling mode as documented in <system/window.h> // the override scaling mode will take precedence over any client diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h index b3481d6465..aac76d23dc 100644 --- a/include/private/gui/LayerState.h +++ b/include/private/gui/LayerState.h @@ -57,6 +57,7 @@ struct layer_state_t { eOverrideScalingModeChanged = 0x00000800, eGeometryAppliesWithResize = 0x00001000, eLayerInfoChanged = 0x00002000, + eReparentChildren = 0x00004000, }; layer_state_t() @@ -96,6 +97,7 @@ struct layer_state_t { Rect crop; Rect finalCrop; sp<IBinder> handle; + sp<IBinder> reparentHandle; uint64_t frameNumber; int32_t overrideScalingMode; uint32_t type; diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index 74c3bedf98..2a327da07d 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -64,6 +64,16 @@ public: return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder()); } + virtual sp<ISurfaceComposerClient> createScopedConnection( + const sp<IGraphicBufferProducer>& parent) + { + Parcel data, reply; + data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); + data.writeStrongBinder(IInterface::asBinder(parent)); + remote()->transact(BnSurfaceComposer::CREATE_SCOPED_CONNECTION, data, &reply); + return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder()); + } + virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc() { Parcel data, reply; @@ -489,6 +499,14 @@ status_t BnSurfaceComposer::onTransact( reply->writeStrongBinder(b); return NO_ERROR; } + case CREATE_SCOPED_CONNECTION: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + sp<IGraphicBufferProducer> bufferProducer = + interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); + sp<IBinder> b = IInterface::asBinder(createScopedConnection(bufferProducer)); + reply->writeStrongBinder(b); + return NO_ERROR; + } case CREATE_GRAPHIC_BUFFER_ALLOC: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> b = IInterface::asBinder(createGraphicBufferAlloc()); diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 16bf324298..fbf76a1f50 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -40,6 +40,7 @@ status_t layer_state_t::write(Parcel& output) const output.write(crop); output.write(finalCrop); output.writeStrongBinder(handle); + output.writeStrongBinder(reparentHandle); output.writeUint64(frameNumber); output.writeInt32(overrideScalingMode); output.writeUint32(type); @@ -70,6 +71,7 @@ status_t layer_state_t::read(const Parcel& input) input.read(crop); input.read(finalCrop); handle = input.readStrongBinder(); + reparentHandle = input.readStrongBinder(); frameNumber = input.readUint64(); overrideScalingMode = input.readInt32(); type = input.readUint32(); diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index c2be6eb751..ece07a33fb 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -170,6 +170,9 @@ public: status_t deferTransactionUntil(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, const sp<IBinder>& handle, uint64_t frameNumber); + status_t reparentChildren(const sp<SurfaceComposerClient>& client, + const sp<IBinder>& id, + const sp<IBinder>& newParentHandle); status_t setOverrideScalingMode(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, int32_t overrideScalingMode); status_t setGeometryAppliesWithResize(const sp<SurfaceComposerClient>& client, @@ -455,6 +458,20 @@ status_t Composer::deferTransactionUntil( return NO_ERROR; } +status_t Composer::reparentChildren( + const sp<SurfaceComposerClient>& client, + const sp<IBinder>& id, + const sp<IBinder>& newParentHandle) { + Mutex::Autolock lock(mLock); + layer_state_t* s = getLayerStateLocked(client, id); + if (!s) { + return BAD_INDEX; + } + s->what |= layer_state_t::eReparentChildren; + s->reparentHandle = newParentHandle; + return NO_ERROR; +} + status_t Composer::setOverrideScalingMode( const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, int32_t overrideScalingMode) { @@ -564,10 +581,18 @@ SurfaceComposerClient::SurfaceComposerClient() { } +SurfaceComposerClient::SurfaceComposerClient(const sp<IGraphicBufferProducer>& root) + : mStatus(NO_INIT), mComposer(Composer::getInstance()), mParent(root) +{ +} + void SurfaceComposerClient::onFirstRef() { sp<ISurfaceComposer> sm(ComposerService::getComposerService()); if (sm != 0) { - sp<ISurfaceComposerClient> conn = sm->createConnection(); + auto rootProducer = mParent.promote(); + sp<ISurfaceComposerClient> conn; + conn = (rootProducer != nullptr) ? sm->createScopedConnection(rootProducer) : + sm->createConnection(); if (conn != 0) { mClient = conn; mStatus = NO_ERROR; @@ -768,6 +793,11 @@ status_t SurfaceComposerClient::deferTransactionUntil(const sp<IBinder>& id, return getComposer().deferTransactionUntil(this, id, handle, frameNumber); } +status_t SurfaceComposerClient::reparentChildren(const sp<IBinder>& id, + const sp<IBinder>& newParentHandle) { + return getComposer().reparentChildren(this, id, newParentHandle); +} + status_t SurfaceComposerClient::setOverrideScalingMode( const sp<IBinder>& id, int32_t overrideScalingMode) { return getComposer().setOverrideScalingMode( diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index c82f6a7812..2d05b78483 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -168,13 +168,19 @@ status_t SurfaceControl::setFinalCrop(const Rect& crop) { return mClient->setFinalCrop(mHandle, crop); } -status_t SurfaceControl::deferTransactionUntil(sp<IBinder> handle, +status_t SurfaceControl::deferTransactionUntil(const sp<IBinder>& handle, uint64_t frameNumber) { status_t err = validate(); if (err < 0) return err; return mClient->deferTransactionUntil(mHandle, handle, frameNumber); } +status_t SurfaceControl::reparentChildren(const sp<IBinder>& newParentHandle) { + status_t err = validate(); + if (err < 0) return err; + return mClient->reparentChildren(mHandle, newParentHandle); +} + status_t SurfaceControl::setOverrideScalingMode(int32_t overrideScalingMode) { status_t err = validate(); if (err < 0) return err; diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 7b78175333..412c0f6486 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -333,6 +333,10 @@ public: } sp<ISurfaceComposerClient> createConnection() override { return nullptr; } + sp<ISurfaceComposerClient> createScopedConnection( + const sp<IGraphicBufferProducer>& /* parent */) override { + return nullptr; + } sp<IGraphicBufferAlloc> createGraphicBufferAlloc() override { return nullptr; } diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp index 7e04fda6de..f63784e18b 100644 --- a/services/surfaceflinger/Client.cpp +++ b/services/surfaceflinger/Client.cpp @@ -35,7 +35,13 @@ const String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER" // --------------------------------------------------------------------------- Client::Client(const sp<SurfaceFlinger>& flinger) - : mFlinger(flinger) + : Client(flinger, nullptr) +{ +} + +Client::Client(const sp<SurfaceFlinger>& flinger, const sp<Layer>& parentLayer) + : mFlinger(flinger), + mParentLayer(parentLayer) { } @@ -47,6 +53,10 @@ Client::~Client() } } +void Client::setParentLayer(const sp<Layer>& parentLayer) { + mParentLayer = parentLayer; +} + status_t Client::initCheck() const { return NO_ERROR; } @@ -90,12 +100,17 @@ status_t Client::onTransact( const int pid = ipc->getCallingPid(); const int uid = ipc->getCallingUid(); const int self_pid = getpid(); - if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != AID_SYSTEM && uid != 0)) { + // If we are called from another non root process without the GRAPHICS, SYSTEM, or ROOT + // uid we require the sAccessSurfaceFlinger permission. + // We grant an exception in the case that the Client has a "parent layer", as its + // effects will be scoped to that layer. + if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != AID_SYSTEM && uid != 0) + && (mParentLayer.promote() == nullptr)) { // we're called from a different process, do the real check if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger)) { ALOGE("Permission Denial: " - "can't openGlobalTransaction pid=%d, uid=%d", pid, uid); + "can't openGlobalTransaction pid=%d, uid<=%d", pid, uid); return PERMISSION_DENIED; } } @@ -117,6 +132,14 @@ status_t Client::createSurface( return NAME_NOT_FOUND; } } + if (parent == nullptr && mParentLayer != nullptr) { + parent = mParentLayer.promote(); + // If we had a parent, but it died, we've lost all + // our capabilities. + if (parent == nullptr) { + return NAME_NOT_FOUND; + } + } /* * createSurface must be called from the GL thread so that it can diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h index 2a9825c687..7328c224e9 100644 --- a/services/surfaceflinger/Client.h +++ b/services/surfaceflinger/Client.h @@ -38,8 +38,9 @@ class SurfaceFlinger; class Client : public BnSurfaceComposerClient { public: - explicit Client(const sp<SurfaceFlinger>& flinger); - ~Client(); + explicit Client(const sp<SurfaceFlinger>& flinger); + Client(const sp<SurfaceFlinger>& flinger, const sp<Layer>& parentLayer); + ~Client(); status_t initCheck() const; @@ -50,6 +51,8 @@ public: sp<Layer> getLayerUser(const sp<IBinder>& handle) const; + void setParentLayer(const sp<Layer>& parentLayer); + private: // ISurfaceComposerClient interface virtual status_t createSurface( @@ -76,6 +79,8 @@ private: // protected by mLock DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayers; + wp<Layer> mParentLayer; + // thread-safe mutable Mutex mLock; }; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 226e70a821..e57c19ad2b 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -162,7 +162,7 @@ void Layer::onFirstRef() { sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer, nullptr, true); - mProducer = new MonitoredProducer(producer, mFlinger); + mProducer = new MonitoredProducer(producer, mFlinger, this); mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName, this); mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); mSurfaceFlingerConsumer->setContentsChangedListener(this); @@ -2380,6 +2380,32 @@ ssize_t Layer::removeChild(const sp<Layer>& layer) { return mCurrentChildren.remove(layer); } +bool Layer::reparentChildren(const sp<IBinder>& newParentHandle) { + sp<Handle> handle = nullptr; + sp<Layer> newParent = nullptr; + if (newParentHandle == nullptr) { + return false; + } + handle = static_cast<Handle*>(newParentHandle.get()); + newParent = handle->owner.promote(); + if (newParent == nullptr) { + ALOGE("Unable to promote Layer handle"); + return false; + } + + for (const sp<Layer>& child : mCurrentChildren) { + newParent->addChild(child); + + sp<Client> client(child->mClientRef.promote()); + if (client != nullptr) { + client->setParentLayer(newParent); + } + } + mCurrentChildren.clear(); + + return true; +} + void Layer::setParent(const sp<Layer>& layer) { mParent = layer; } diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index ee7cfb80df..7335be780f 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -176,6 +176,7 @@ public: void deferTransactionUntil(const sp<IBinder>& handle, uint64_t frameNumber); bool setOverrideScalingMode(int32_t overrideScalingMode); void setInfo(uint32_t type, uint32_t appId); + bool reparentChildren(const sp<IBinder>& layer); // If we have received a new buffer this frame, we will pass its surface // damage down to hardware composer. Otherwise, we must send a region with diff --git a/services/surfaceflinger/MonitoredProducer.cpp b/services/surfaceflinger/MonitoredProducer.cpp index 8bf6e8243c..2ba1b338dd 100644 --- a/services/surfaceflinger/MonitoredProducer.cpp +++ b/services/surfaceflinger/MonitoredProducer.cpp @@ -17,13 +17,16 @@ #include "MessageQueue.h" #include "MonitoredProducer.h" #include "SurfaceFlinger.h" +#include "Layer.h" namespace android { MonitoredProducer::MonitoredProducer(const sp<IGraphicBufferProducer>& producer, - const sp<SurfaceFlinger>& flinger) : + const sp<SurfaceFlinger>& flinger, + const wp<Layer>& layer) : mProducer(producer), - mFlinger(flinger) {} + mFlinger(flinger), + mLayer(layer) {} MonitoredProducer::~MonitoredProducer() { // Remove ourselves from SurfaceFlinger's list. We do this asynchronously @@ -159,5 +162,9 @@ IBinder* MonitoredProducer::onAsBinder() { return this; } +sp<Layer> MonitoredProducer::getLayer() const { + return mLayer.promote(); +} + // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/surfaceflinger/MonitoredProducer.h b/services/surfaceflinger/MonitoredProducer.h index becc740818..a3ec29d711 100644 --- a/services/surfaceflinger/MonitoredProducer.h +++ b/services/surfaceflinger/MonitoredProducer.h @@ -24,13 +24,15 @@ namespace android { class IProducerListener; class NativeHandle; class SurfaceFlinger; +class Layer; // MonitoredProducer wraps an IGraphicBufferProducer so that SurfaceFlinger will // be notified upon its destruction class MonitoredProducer : public BnGraphicBufferProducer { public: MonitoredProducer(const sp<IGraphicBufferProducer>& producer, - const sp<SurfaceFlinger>& flinger); + const sp<SurfaceFlinger>& flinger, + const wp<Layer>& layer); virtual ~MonitoredProducer(); // From IGraphicBufferProducer @@ -67,9 +69,14 @@ public: virtual void getFrameTimestamps(FrameEventHistoryDelta *outDelta) override; virtual status_t getUniqueId(uint64_t* outId) const override; + // The Layer which created this producer, and on which queued Buffer's will be displayed. + sp<Layer> getLayer() const; + private: sp<IGraphicBufferProducer> mProducer; sp<SurfaceFlinger> mFlinger; + // The Layer which created this producer, and on which queued Buffer's will be displayed. + wp<Layer> mLayer; }; }; // namespace android diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 4798ecdedd..8cc8e318a6 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -71,6 +71,7 @@ #include "Layer.h" #include "LayerVector.h" #include "LayerDim.h" +#include "MonitoredProducer.h" #include "SurfaceFlinger.h" #include "DisplayHardware/FramebufferSurface.h" @@ -221,15 +222,29 @@ void SurfaceFlinger::binderDied(const wp<IBinder>& /* who */) startBootAnim(); } -sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() -{ - sp<ISurfaceComposerClient> bclient; - sp<Client> client(new Client(this)); +static sp<ISurfaceComposerClient> initClient(const sp<Client>& client) { status_t err = client->initCheck(); if (err == NO_ERROR) { - bclient = client; + return client; } - return bclient; + return nullptr; +} + +sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() { + return initClient(new Client(this)); +} + +sp<ISurfaceComposerClient> SurfaceFlinger::createScopedConnection( + const sp<IGraphicBufferProducer>& gbp) { + if (authenticateSurfaceTexture(gbp) == false) { + return nullptr; + } + const auto& layer = (static_cast<MonitoredProducer*>(gbp.get()))->getLayer(); + if (layer == nullptr) { + return nullptr; + } + + return initClient(new Client(this, layer)); } sp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName, @@ -2575,6 +2590,11 @@ uint32_t SurfaceFlinger::setClientStateLocked( // We don't trigger a traversal here because if no other state is // changed, we don't want this to cause any more work } + if (what & layer_state_t::eReparentChildren) { + if (layer->reparentChildren(s.reparentHandle)) { + flags |= eTransactionNeeded|eTraversalNeeded; + } + } if (what & layer_state_t::eOverrideScalingModeChanged) { layer->setOverrideScalingMode(s.overrideScalingMode); // We don't trigger a traversal here because if no other state is @@ -3268,7 +3288,6 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { switch (code) { case CREATE_CONNECTION: case CREATE_DISPLAY: - case SET_TRANSACTION_STATE: case BOOT_FINISHED: case CLEAR_ANIMATION_FRAME_STATS: case GET_ANIMATION_FRAME_STATS: @@ -3286,6 +3305,17 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { } break; } + /* + * Calling setTransactionState is safe, because you need to have been + * granted a reference to Client* and Handle* to do anything with it. + * + * Creating a scoped connection is safe, as per discussion in ISurfaceComposer.h + */ + case SET_TRANSACTION_STATE: + case CREATE_SCOPED_CONNECTION: + { + return OK; + } case CAPTURE_SCREEN: { // codes that require permission check diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 4f3ee7433d..45a52689d6 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -189,6 +189,7 @@ private: * ISurfaceComposer interface */ virtual sp<ISurfaceComposerClient> createConnection(); + virtual sp<ISurfaceComposerClient> createScopedConnection(const sp<IGraphicBufferProducer>& gbp); virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc(); virtual sp<IBinder> createDisplay(const String8& displayName, bool secure); virtual void destroyDisplay(const sp<IBinder>& display); diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp index 1976d2e739..2cd02a0919 100644 --- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp +++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp @@ -74,6 +74,7 @@ #include "Layer.h" #include "LayerVector.h" #include "LayerDim.h" +#include "MonitoredProducer.h" #include "SurfaceFlinger.h" #include "DisplayHardware/FramebufferSurface.h" @@ -219,15 +220,29 @@ void SurfaceFlinger::binderDied(const wp<IBinder>& /* who */) startBootAnim(); } -sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() -{ - sp<ISurfaceComposerClient> bclient; - sp<Client> client(new Client(this)); +static sp<ISurfaceComposerClient> initClient(const sp<Client>& client) { status_t err = client->initCheck(); if (err == NO_ERROR) { - bclient = client; + return client; + } + return nullptr; +} + +sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() { + return initClient(new Client(this)); +} + +sp<ISurfaceComposerClient> SurfaceFlinger::createScopedConnection( + const sp<IGraphicBufferProducer>& gbp) { + if (authenticateSurfaceTexture(gbp) == false) { + return nullptr; + } + const auto& layer = (static_cast<MonitoredProducer*>(gbp.get()))->getLayer(); + if (layer == nullptr) { + return nullptr; } - return bclient; + + return initClient(new Client(this, layer)); } sp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName, @@ -2482,6 +2497,11 @@ uint32_t SurfaceFlinger::setClientStateLocked( // We don't trigger a traversal here because if no other state is // changed, we don't want this to cause any more work } + if (what & layer_state_t::eReparentChildren) { + if (layer->reparentChildren(s.reparentHandle)) { + flags |= eTransactionNeeded|eTraversalNeeded; + } + } if (what & layer_state_t::eOverrideScalingModeChanged) { layer->setOverrideScalingMode(s.overrideScalingMode); // We don't trigger a traversal here because if no other state is @@ -3153,7 +3173,6 @@ status_t SurfaceFlinger::onTransact( switch (code) { case CREATE_CONNECTION: case CREATE_DISPLAY: - case SET_TRANSACTION_STATE: case BOOT_FINISHED: case CLEAR_ANIMATION_FRAME_STATS: case GET_ANIMATION_FRAME_STATS: @@ -3172,6 +3191,17 @@ status_t SurfaceFlinger::onTransact( } break; } + /* + * Calling setTransactionState is safe, because you need to have been + * granted a reference to Client* and Handle* to do anything with it. + * + * Creating a scoped connection is safe, as per discussion in ISurfaceComposer.h + */ + case SET_TRANSACTION_STATE: + case CREATE_SCOPED_CONNECTION: + { + break; + } case CAPTURE_SCREEN: { // codes that require permission check |