allow re-targetting of surfaces

Surfaces can now be parcelized and sent to remote
processes. When a surface crosses a process
boundary, it looses its connection with the
current process and gets attached to the new one.

Change-Id: I39c7b055bcd3ea1162ef2718d3d4b866bf7c81c0
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index a94fdd4..e7247bd 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -76,15 +76,18 @@
 status_t Layer::setToken(const sp<UserClient>& userClient,
         SharedClient* sharedClient, int32_t token)
 {
-    SharedBufferServer* lcblk = new SharedBufferServer(
+    sp<SharedBufferServer> lcblk = new SharedBufferServer(
             sharedClient, token, mBufferManager.getDefaultBufferCount(),
             getIdentity());
 
     status_t err = mUserClientRef.setToken(userClient, lcblk, token);
-    if (err != NO_ERROR) {
-        LOGE("ClientRef::setToken(%p, %p, %u) failed",
-                userClient.get(), lcblk, token);
-        delete lcblk;
+
+    LOGE_IF(err != NO_ERROR,
+            "ClientRef::setToken(%p, %p, %u) failed",
+            userClient.get(), lcblk.get(), token);
+
+    if (err == NO_ERROR) {
+        // we need to free the buffers associated with this surface
     }
 
     return err;
@@ -95,6 +98,11 @@
     return mUserClientRef.getToken();
 }
 
+sp<UserClient> Layer::getClient() const
+{
+    return mUserClientRef.getClient();
+}
+
 // called with SurfaceFlinger::mStateLock as soon as the layer is entered
 // in the purgatory list
 void Layer::onRemoved()
@@ -626,11 +634,10 @@
 // ---------------------------------------------------------------------------
 
 Layer::ClientRef::ClientRef()
-    : mToken(-1) {
+    : mControlBlock(0), mToken(-1) {
 }
 
 Layer::ClientRef::~ClientRef() {
-    delete lcblk;
 }
 
 int32_t Layer::ClientRef::getToken() const {
@@ -638,14 +645,25 @@
     return mToken;
 }
 
-status_t Layer::ClientRef::setToken(const sp<UserClient>& uc,
-        SharedBufferServer* sharedClient, int32_t token) {
+sp<UserClient> Layer::ClientRef::getClient() const {
     Mutex::Autolock _l(mLock);
-    if (mToken >= 0)
-        return INVALID_OPERATION;
+    return mUserClient.promote();
+}
+
+status_t Layer::ClientRef::setToken(const sp<UserClient>& uc,
+        const sp<SharedBufferServer>& sharedClient, int32_t token) {
+    Mutex::Autolock _l(mLock);
+
+    { // scope for strong mUserClient reference
+        sp<UserClient> userClient(mUserClient.promote());
+        if (mUserClient != 0 && mControlBlock != 0) {
+            mControlBlock->setStatus(NO_INIT);
+        }
+    }
+
     mUserClient = uc;
     mToken = token;
-    lcblk = sharedClient;
+    mControlBlock = sharedClient;
     return NO_ERROR;
 }
 
@@ -657,12 +675,16 @@
 // it makes sure the UserClient (and its associated shared memory)
 // won't go away while we're accessing it.
 Layer::ClientRef::Access::Access(const ClientRef& ref)
-    : lcblk(0)
+    : mControlBlock(0)
 {
     Mutex::Autolock _l(ref.mLock);
     mUserClientStrongRef = ref.mUserClient.promote();
     if (mUserClientStrongRef != 0)
-        lcblk = ref.lcblk;
+        mControlBlock = ref.mControlBlock;
+}
+
+Layer::ClientRef::Access::~Access()
+{
 }
 
 // ---------------------------------------------------------------------------