summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Robert Carr <racarr@google.com> 2016-12-21 12:58:51 -0800
committer Robert Carr <racarr@google.com> 2017-01-27 13:59:42 -0800
commit1db73f66624e7d151710483dd58e03eed672f064 (patch)
tree40d09da72f244ae593284ac3bd895d078e9c4220
parentbf89eb7b24f930e77be57bc7b6393e39691a4d35 (diff)
SurfaceFlinger: Add support for non-privileged clients.
Allow clients without privilege to create child layers through scoped connections. We enable this in preparation for allowing SurfaceView to bypass the WindowManager. We include support for reparenting of all of a layer's children for the WindowManager to use in cases where one surface is replacing another (while keeping its children around). Test: Tested with corresponding SurfaceView modifications. Change-Id: I9920e6730d719113522a68788e63fb59f70d3406
-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