diff options
-rw-r--r-- | include/gui/ISurfaceComposer.h | 8 | ||||
-rw-r--r-- | include/gui/SurfaceComposerClient.h | 9 | ||||
-rw-r--r-- | libs/gui/ISurfaceComposer.cpp | 51 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 9 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 19 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 1 |
6 files changed, 80 insertions, 17 deletions
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h index 0606aff..5c3c99c 100644 --- a/include/gui/ISurfaceComposer.h +++ b/include/gui/ISurfaceComposer.h @@ -70,12 +70,17 @@ public: /* return an IDisplayEventConnection */ virtual sp<IDisplayEventConnection> createDisplayEventConnection() = 0; - /* create a display + /* create a virtual display * requires ACCESS_SURFACE_FLINGER permission. */ virtual sp<IBinder> createDisplay(const String8& displayName, bool secure) = 0; + /* destroy a virtual display + * requires ACCESS_SURFACE_FLINGER permission. + */ + virtual void destroyDisplay(const sp<IBinder>& display) = 0; + /* get the token for the existing default displays. possible values * for id are eDisplayIdMain and eDisplayIdHdmi. */ @@ -130,6 +135,7 @@ public: CREATE_GRAPHIC_BUFFER_ALLOC, CREATE_DISPLAY_EVENT_CONNECTION, CREATE_DISPLAY, + DESTROY_DISPLAY, GET_BUILT_IN_DISPLAY, SET_TRANSACTION_STATE, AUTHENTICATE_SURFACE, diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h index 643d7cf..e982bcd 100644 --- a/include/gui/SurfaceComposerClient.h +++ b/include/gui/SurfaceComposerClient.h @@ -48,7 +48,7 @@ class Region; class SurfaceComposerClient : public RefBase { friend class Composer; -public: +public: SurfaceComposerClient(); virtual ~SurfaceComposerClient(); @@ -57,7 +57,7 @@ public: // Return the connection of this client sp<IBinder> connection() const; - + // Forcibly remove connection before all references have gone away. void dispose(); @@ -86,9 +86,12 @@ public: uint32_t flags = 0 // usage flags ); - //! Create a display + //! Create a virtual display static sp<IBinder> createDisplay(const String8& displayName, bool secure); + //! Destroy a virtual display + static void destroyDisplay(const sp<IBinder>& display); + //! Get the token for the existing default displays. //! Possible values for id are eDisplayIdMain and eDisplayIdHdmi. static sp<IBinder> getBuiltInDisplay(int32_t id); diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index a9217ca..aab0604 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -185,6 +185,14 @@ public: return reply.readStrongBinder(); } + virtual void destroyDisplay(const sp<IBinder>& display) + { + Parcel data, reply; + data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); + data.writeStrongBinder(display); + remote()->transact(BnSurfaceComposer::DESTROY_DISPLAY, data, &reply); + } + virtual sp<IBinder> getBuiltInDisplay(int32_t id) { Parcel data, reply; @@ -233,12 +241,14 @@ status_t BnSurfaceComposer::onTransact( CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> b = createConnection()->asBinder(); reply->writeStrongBinder(b); - } break; + return NO_ERROR; + } case CREATE_GRAPHIC_BUFFER_ALLOC: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> b = createGraphicBufferAlloc()->asBinder(); reply->writeStrongBinder(b); - } break; + return NO_ERROR; + } case SET_TRANSACTION_STATE: { CHECK_INTERFACE(ISurfaceComposer, data, reply); size_t count = data.readInt32(); @@ -259,11 +269,13 @@ status_t BnSurfaceComposer::onTransact( } uint32_t flags = data.readInt32(); setTransactionState(state, displays, flags); - } break; + return NO_ERROR; + } case BOOT_FINISHED: { CHECK_INTERFACE(ISurfaceComposer, data, reply); bootFinished(); - } break; + return NO_ERROR; + } case CAPTURE_SCREEN: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> display = data.readStrongBinder(); @@ -276,20 +288,22 @@ status_t BnSurfaceComposer::onTransact( status_t res = captureScreen(display, producer, reqWidth, reqHeight, minLayerZ, maxLayerZ); reply->writeInt32(res); - } break; + return NO_ERROR; + } case AUTHENTICATE_SURFACE: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IGraphicBufferProducer> bufferProducer = interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); int32_t result = authenticateSurfaceTexture(bufferProducer) ? 1 : 0; reply->writeInt32(result); - } break; + return NO_ERROR; + } case CREATE_DISPLAY_EVENT_CONNECTION: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IDisplayEventConnection> connection(createDisplayEventConnection()); reply->writeStrongBinder(connection->asBinder()); return NO_ERROR; - } break; + } case CREATE_DISPLAY: { CHECK_INTERFACE(ISurfaceComposer, data, reply); String8 displayName = data.readString8(); @@ -297,24 +311,32 @@ status_t BnSurfaceComposer::onTransact( sp<IBinder> display(createDisplay(displayName, secure)); reply->writeStrongBinder(display); return NO_ERROR; - } break; + } + case DESTROY_DISPLAY: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + sp<IBinder> display = data.readStrongBinder(); + destroyDisplay(display); + return NO_ERROR; + } case GET_BUILT_IN_DISPLAY: { CHECK_INTERFACE(ISurfaceComposer, data, reply); int32_t id = data.readInt32(); sp<IBinder> display(getBuiltInDisplay(id)); reply->writeStrongBinder(display); return NO_ERROR; - } break; + } case BLANK: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> display = data.readStrongBinder(); blank(display); - } break; + return NO_ERROR; + } case UNBLANK: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> display = data.readStrongBinder(); unblank(display); - } break; + return NO_ERROR; + } case GET_DISPLAY_INFO: { CHECK_INTERFACE(ISurfaceComposer, data, reply); DisplayInfo info; @@ -322,10 +344,13 @@ status_t BnSurfaceComposer::onTransact( status_t result = getDisplayInfo(display, &info); memcpy(reply->writeInplace(sizeof(DisplayInfo)), &info, sizeof(DisplayInfo)); reply->writeInt32(result); - } break; - default: + return NO_ERROR; + } + default: { return BBinder::onTransact(code, data, reply, flags); + } } + // should be unreachable return NO_ERROR; } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index e067479..aafc4d2 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -135,6 +135,7 @@ class Composer : public Singleton<Composer> public: sp<IBinder> createDisplay(const String8& displayName, bool secure); + void destroyDisplay(const sp<IBinder>& display); sp<IBinder> getBuiltInDisplay(int32_t id); status_t setPosition(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, @@ -188,6 +189,10 @@ sp<IBinder> Composer::createDisplay(const String8& displayName, bool secure) { secure); } +void Composer::destroyDisplay(const sp<IBinder>& display) { + return ComposerService::getComposerService()->destroyDisplay(display); +} + sp<IBinder> Composer::getBuiltInDisplay(int32_t id) { return ComposerService::getComposerService()->getBuiltInDisplay(id); } @@ -490,6 +495,10 @@ sp<IBinder> SurfaceComposerClient::createDisplay(const String8& displayName, return Composer::getInstance().createDisplay(displayName, secure); } +void SurfaceComposerClient::destroyDisplay(const sp<IBinder>& display) { + Composer::getInstance().destroyDisplay(display); +} + sp<IBinder> SurfaceComposerClient::getBuiltInDisplay(int32_t id) { return Composer::getInstance().getBuiltInDisplay(id); } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index b38ad10..bc10853 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -205,6 +205,25 @@ sp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName, return token; } +void SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) { + Mutex::Autolock _l(mStateLock); + + ssize_t idx = mCurrentState.displays.indexOfKey(display); + if (idx < 0) { + ALOGW("destroyDisplay: invalid display token"); + return; + } + + const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx)); + if (!info.isVirtualDisplay()) { + ALOGE("destroyDisplay called for non-virtual display"); + return; + } + + mCurrentState.displays.removeItemsAt(idx); + setTransactionFlags(eDisplayTransactionNeeded); +} + void SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) { ALOGW_IF(mBuiltinDisplays[type], "Overwriting display token for display type %d", type); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index acc8fab..92fcc25 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -184,6 +184,7 @@ private: virtual sp<ISurfaceComposerClient> createConnection(); virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc(); virtual sp<IBinder> createDisplay(const String8& displayName, bool secure); + virtual void destroyDisplay(const sp<IBinder>& display); virtual sp<IBinder> getBuiltInDisplay(int32_t id); virtual void setTransactionState(const Vector<ComposerState>& state, const Vector<DisplayState>& displays, uint32_t flags); |