summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/gui/ISurfaceComposer.h14
-rw-r--r--include/gui/SurfaceComposerClient.h4
-rw-r--r--include/gui/SurfaceControl.h4
-rw-r--r--include/private/gui/LayerState.h2
-rw-r--r--libs/gui/ISurfaceComposer.cpp18
-rw-r--r--libs/gui/LayerState.cpp2
-rw-r--r--libs/gui/SurfaceComposerClient.cpp32
-rw-r--r--libs/gui/SurfaceControl.cpp8
-rw-r--r--libs/gui/tests/Surface_test.cpp4
-rw-r--r--services/surfaceflinger/Client.cpp29
-rw-r--r--services/surfaceflinger/Client.h9
-rw-r--r--services/surfaceflinger/Layer.cpp28
-rw-r--r--services/surfaceflinger/Layer.h1
-rw-r--r--services/surfaceflinger/MonitoredProducer.cpp11
-rw-r--r--services/surfaceflinger/MonitoredProducer.h9
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp44
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h1
-rw-r--r--services/surfaceflinger/SurfaceFlinger_hwc1.cpp44
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