Merge "atrace: add support for tracing kernel functions" into jb-mr2-dev
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 0d3f643..29838e4 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -69,43 +69,44 @@
 
 /* Tracing categories */
 static const TracingCategory k_categories[] = {
-    { "gfx",    "Graphics",         ATRACE_TAG_GRAPHICS, { } },
-    { "input",  "Input",            ATRACE_TAG_INPUT, { } },
-    { "view",   "View System",      ATRACE_TAG_VIEW, { } },
-    { "wm",     "Window Manager",   ATRACE_TAG_WINDOW_MANAGER, { } },
-    { "am",     "Activity Manager", ATRACE_TAG_ACTIVITY_MANAGER, { } },
-    { "audio",  "Audio",            ATRACE_TAG_AUDIO, { } },
-    { "video",  "Video",            ATRACE_TAG_VIDEO, { } },
-    { "camera", "Camera",           ATRACE_TAG_CAMERA, { } },
-    { "hal",    "Hardware Modules", ATRACE_TAG_HAL, { } },
-    { "sched",  "CPU Scheduling",   0, {
-        { REQ,  "/sys/kernel/debug/tracing/events/sched/sched_switch/enable" },
-        { REQ,  "/sys/kernel/debug/tracing/events/sched/sched_wakeup/enable" },
+    { "gfx",        "Graphics",         ATRACE_TAG_GRAPHICS, { } },
+    { "input",      "Input",            ATRACE_TAG_INPUT, { } },
+    { "view",       "View System",      ATRACE_TAG_VIEW, { } },
+    { "webview",    "WebView",          ATRACE_TAG_WEBVIEW, { } },
+    { "wm",         "Window Manager",   ATRACE_TAG_WINDOW_MANAGER, { } },
+    { "am",         "Activity Manager", ATRACE_TAG_ACTIVITY_MANAGER, { } },
+    { "audio",      "Audio",            ATRACE_TAG_AUDIO, { } },
+    { "video",      "Video",            ATRACE_TAG_VIDEO, { } },
+    { "camera",     "Camera",           ATRACE_TAG_CAMERA, { } },
+    { "hal",        "Hardware Modules", ATRACE_TAG_HAL, { } },
+    { "sched",      "CPU Scheduling",   0, {
+        { REQ,      "/sys/kernel/debug/tracing/events/sched/sched_switch/enable" },
+        { REQ,      "/sys/kernel/debug/tracing/events/sched/sched_wakeup/enable" },
     } },
-    { "freq",   "CPU Frequency",    0, {
-        { REQ,  "/sys/kernel/debug/tracing/events/power/cpu_frequency/enable" },
-        { OPT, "/sys/kernel/debug/tracing/events/power/clock_set_rate/enable" },
+    { "freq",       "CPU Frequency",    0, {
+        { REQ,      "/sys/kernel/debug/tracing/events/power/cpu_frequency/enable" },
+        { OPT,      "/sys/kernel/debug/tracing/events/power/clock_set_rate/enable" },
     } },
-    { "membus", "Memory Bus Utilization", 0, {
-        { REQ,  "/sys/kernel/debug/tracing/events/memory_bus/enable" },
+    { "membus",     "Memory Bus Utilization", 0, {
+        { REQ,      "/sys/kernel/debug/tracing/events/memory_bus/enable" },
     } },
-    { "idle",   "CPU Idle",         0, {
-        { REQ,  "/sys/kernel/debug/tracing/events/power/cpu_idle/enable" },
+    { "idle",       "CPU Idle",         0, {
+        { REQ,      "/sys/kernel/debug/tracing/events/power/cpu_idle/enable" },
     } },
-    { "disk",   "Disk I/O",         0, {
-        { REQ,  "/sys/kernel/debug/tracing/events/ext4/ext4_sync_file_enter/enable" },
-        { REQ,  "/sys/kernel/debug/tracing/events/ext4/ext4_sync_file_exit/enable" },
-        { REQ,  "/sys/kernel/debug/tracing/events/block/block_rq_issue/enable" },
-        { REQ,  "/sys/kernel/debug/tracing/events/block/block_rq_complete/enable" },
+    { "disk",       "Disk I/O",         0, {
+        { REQ,      "/sys/kernel/debug/tracing/events/ext4/ext4_sync_file_enter/enable" },
+        { REQ,      "/sys/kernel/debug/tracing/events/ext4/ext4_sync_file_exit/enable" },
+        { REQ,      "/sys/kernel/debug/tracing/events/block/block_rq_issue/enable" },
+        { REQ,      "/sys/kernel/debug/tracing/events/block/block_rq_complete/enable" },
     } },
-    { "load",   "CPU Load",         0, {
-        { REQ,  "/sys/kernel/debug/tracing/events/cpufreq_interactive/enable" },
+    { "load",       "CPU Load",         0, {
+        { REQ,      "/sys/kernel/debug/tracing/events/cpufreq_interactive/enable" },
     } },
-    { "sync",   "Synchronization",  0, {
-        { REQ,  "/sys/kernel/debug/tracing/events/sync/enable" },
+    { "sync",       "Synchronization",  0, {
+        { REQ,      "/sys/kernel/debug/tracing/events/sync/enable" },
     } },
-    { "workq",  "Kernel Workqueues", 0, {
-        { REQ,  "/sys/kernel/debug/tracing/events/workqueue/enable" },
+    { "workq",      "Kernel Workqueues", 0, {
+        { REQ,      "/sys/kernel/debug/tracing/events/workqueue/enable" },
     } },
 };
 
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 9a1839d..b3a4cc6 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -161,7 +161,7 @@
 
     if (screenshot_path[0]) {
         ALOGI("taking screenshot\n");
-        run_command(NULL, 5, SU_PATH, "root", "screenshot", screenshot_path, NULL);
+        run_command(NULL, 10, "/system/bin/screencap", "-p", screenshot_path, NULL);
         ALOGI("wrote screenshot: %s\n", screenshot_path);
     }
 
@@ -311,6 +311,7 @@
             "  -b: play sound file instead of vibrate, at beginning of job\n"
             "  -e: play sound file instead of vibrate, at end of job\n"
             "  -q: disable vibrate\n"
+            "  -B: send broadcast when finished (requires -o and -p)\n"
 		);
 }
 
@@ -323,6 +324,7 @@
     char* end_sound = 0;
     int use_socket = 0;
     int do_fb = 0;
+    int do_broadcast = 0;
 
     if (getuid() != 0) {
         // Old versions of the adb client would call the
@@ -348,7 +350,7 @@
     dump_traces_path = dump_traces();
 
     int c;
-    while ((c = getopt(argc, argv, "b:de:ho:svqzp")) != -1) {
+    while ((c = getopt(argc, argv, "b:de:ho:svqzpB")) != -1) {
         switch (c) {
             case 'b': begin_sound = optarg;  break;
             case 'd': do_add_date = 1;       break;
@@ -359,6 +361,7 @@
             case 'q': do_vibrate = 0;        break;
             case 'z': do_compress = 6;       break;
             case 'p': do_fb = 1;             break;
+            case 'B': do_broadcast = 1;      break;
             case '?': printf("\n");
             case 'h':
                 usage();
@@ -474,6 +477,14 @@
         fprintf(stderr, "rename(%s, %s): %s\n", tmp_path, path, strerror(errno));
     }
 
+    if (do_broadcast && use_outfile && do_fb) {
+        run_command(NULL, 5, "/system/bin/am", "broadcast",
+                "-a", "android.intent.action.BUGREPORT_FINISHED",
+                "--es", "android.intent.extra.BUGREPORT", path,
+                "--es", "android.intent.extra.SCREENSHOT", screenshot_path,
+                "--receiver-permission", "android.permission.DUMP", NULL);
+    }
+
     ALOGI("done\n");
 
     return 0;
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index d081590..9b0013e 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -379,7 +379,7 @@
         chp = strchr(chp, '/');
         if (chp) {
             *chp = 0;
-            mkdir(path, 0775);  /* drwxrwxr-x */
+            mkdir(path, 0770);  /* drwxrwx--- */
             *chp++ = '/';
         }
     }
diff --git a/include/android/input.h b/include/android/input.h
index f2befa9e..c8ac938 100644
--- a/include/android/input.h
+++ b/include/android/input.h
@@ -428,6 +428,7 @@
 enum {
     AINPUT_SOURCE_CLASS_MASK = 0x000000ff,
 
+    AINPUT_SOURCE_CLASS_NONE = 0x00000000,
     AINPUT_SOURCE_CLASS_BUTTON = 0x00000001,
     AINPUT_SOURCE_CLASS_POINTER = 0x00000002,
     AINPUT_SOURCE_CLASS_NAVIGATION = 0x00000004,
@@ -446,6 +447,7 @@
     AINPUT_SOURCE_STYLUS = 0x00004000 | AINPUT_SOURCE_CLASS_POINTER,
     AINPUT_SOURCE_TRACKBALL = 0x00010000 | AINPUT_SOURCE_CLASS_NAVIGATION,
     AINPUT_SOURCE_TOUCHPAD = 0x00100000 | AINPUT_SOURCE_CLASS_POSITION,
+    AINPUT_SOURCE_TOUCH_NAVIGATION = 0x00200000 | AINPUT_SOURCE_CLASS_NONE,
     AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK,
 
     AINPUT_SOURCE_ANY = 0xffffff00,
diff --git a/include/gui/ISurface.h b/include/gui/ISurface.h
deleted file mode 100644
index 5a928f2..0000000
--- a/include/gui/ISurface.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_GUI_ISURFACE_H
-#define ANDROID_GUI_ISURFACE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-
-#include <binder/IInterface.h>
-
-#include <ui/PixelFormat.h>
-
-namespace android {
-
-class IGraphicBufferProducer;
-
-class ISurface : public IInterface
-{
-protected:
-    enum {
-        GET_SURFACE_TEXTURE = IBinder::FIRST_CALL_TRANSACTION,
-    };
-
-public: 
-    DECLARE_META_INTERFACE(Surface);
-
-    virtual sp<IGraphicBufferProducer> getSurfaceTexture() const = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnSurface : public BnInterface<ISurface>
-{
-public:
-    virtual status_t    onTransact( uint32_t code,
-                                    const Parcel& data,
-                                    Parcel* reply,
-                                    uint32_t flags = 0);
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_GUI_ISURFACE_H
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h
index 08eddcb..47f9552 100644
--- a/include/gui/ISurfaceComposer.h
+++ b/include/gui/ISurfaceComposer.h
@@ -103,16 +103,23 @@
             uint32_t reqWidth, uint32_t reqHeight,
             uint32_t minLayerZ, uint32_t maxLayerZ) = 0;
 
-    /* triggers screen off and waits for it to complete */
+    /* triggers screen off and waits for it to complete
+     * requires ACCESS_SURFACE_FLINGER permission.
+     */
     virtual void blank(const sp<IBinder>& display) = 0;
 
-    /* triggers screen on and waits for it to complete */
+    /* triggers screen on and waits for it to complete
+     * requires ACCESS_SURFACE_FLINGER permission.
+     */
     virtual void unblank(const sp<IBinder>& display) = 0;
 
     /* returns information about a display
      * intended to be used to get information about built-in displays */
     virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) = 0;
 
+    /* Capture the specified screen. requires READ_FRAME_BUFFER permission
+     * This function will fail if there is a secure window on screen.
+     */
     virtual status_t captureScreen(const sp<IBinder>& display,
             const sp<IGraphicBufferProducer>& producer,
             uint32_t reqWidth, uint32_t reqHeight,
diff --git a/include/gui/ISurfaceComposerClient.h b/include/gui/ISurfaceComposerClient.h
index 4afc860..cb9816f 100644
--- a/include/gui/ISurfaceComposerClient.h
+++ b/include/gui/ISurfaceComposerClient.h
@@ -27,11 +27,11 @@
 
 #include <ui/PixelFormat.h>
 
-#include <gui/ISurface.h>
-
 namespace android {
 // ----------------------------------------------------------------------------
 
+class IGraphicBufferProducer;
+
 class ISurfaceComposerClient : public IInterface
 {
 public:
@@ -55,9 +55,11 @@
     /*
      * Requires ACCESS_SURFACE_FLINGER permission
      */
-    virtual sp<ISurface> createSurface(
+    virtual status_t createSurface(
             const String8& name, uint32_t w, uint32_t h,
-            PixelFormat format, uint32_t flags) = 0;
+            PixelFormat format, uint32_t flags,
+            sp<IBinder>* handle,
+            sp<IGraphicBufferProducer>* gbp) = 0;
 
     /*
      * Requires ACCESS_SURFACE_FLINGER permission
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index 18e57ed..c25847c 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -76,24 +76,13 @@
         return surface != NULL && surface->getIGraphicBufferProducer() != NULL;
     }
 
-    /* writes the given Surface into a Parcel */
-    static status_t writeToParcel(const sp<Surface>& surface, Parcel* parcel);
-
-    /* constructs a Surface from a Parcel. see Surface::writeToParcel()
-     * and SurfaceControl::writeToParcel() */
-    static sp<Surface> readFromParcel(const Parcel& data);
-
-
 protected:
-    Surface();
     virtual ~Surface();
-    void setIGraphicBufferProducer(const sp<IGraphicBufferProducer>& bufferProducer);
 
 private:
     // can't be copied
     Surface& operator = (const Surface& rhs);
     Surface(const Surface& rhs);
-    void init();
 
     // ANativeWindow hooks
     static int hook_cancelBuffer(ANativeWindow* window,
diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h
index f70888d..fe8eb6f 100644
--- a/include/gui/SurfaceControl.h
+++ b/include/gui/SurfaceControl.h
@@ -27,7 +27,6 @@
 #include <ui/PixelFormat.h>
 #include <ui/Region.h>
 
-#include <gui/ISurface.h>
 #include <gui/ISurfaceComposerClient.h>
 
 namespace android {
@@ -46,9 +45,11 @@
     static bool isValid(const sp<SurfaceControl>& surface) {
         return (surface != 0) && surface->isValid();
     }
+
     bool isValid() {
-        return mSurface!=0 && mClient!=0;
+        return mHandle!=0 && mClient!=0;
     }
+
     static bool isSameSurface(
             const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs);
         
@@ -82,7 +83,8 @@
 
     SurfaceControl(
             const sp<SurfaceComposerClient>& client,
-            const sp<ISurface>& surface);
+            const sp<IBinder>& handle,
+            const sp<IGraphicBufferProducer>& gbp);
 
     ~SurfaceControl();
 
@@ -90,7 +92,7 @@
     void destroy();
     
     sp<SurfaceComposerClient>   mClient;
-    sp<IBinder>                 mSurface;
+    sp<IBinder>                 mHandle;
     sp<IGraphicBufferProducer>  mGraphicBufferProducer;
     mutable Mutex               mLock;
     mutable sp<Surface>         mSurfaceData;
diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h
index 0798e17..bf4bf03 100644
--- a/include/private/gui/LayerState.h
+++ b/include/private/gui/LayerState.h
@@ -24,7 +24,6 @@
 
 #include <ui/Region.h>
 #include <ui/Rect.h>
-#include <gui/ISurface.h>
 
 namespace android {
 
diff --git a/include/utils/Vector.h b/include/utils/Vector.h
index f3020d6..ed7b725 100644
--- a/include/utils/Vector.h
+++ b/include/utils/Vector.h
@@ -80,7 +80,13 @@
     //! sets the capacity. capacity can never be reduced less than size()
     inline  ssize_t         setCapacity(size_t size)    { return VectorImpl::setCapacity(size); }
 
-    /*! 
+    /*!
+     * set the size of the vector. items are appended with the default
+     * constructor, or removed from the end as needed.
+     */
+    inline  ssize_t         resize(size_t size)         { return VectorImpl::resize(size); }
+
+    /*!
      * C-style array access
      */
      
diff --git a/include/utils/VectorImpl.h b/include/utils/VectorImpl.h
index c4ec2ff..9bc50e6 100644
--- a/include/utils/VectorImpl.h
+++ b/include/utils/VectorImpl.h
@@ -64,6 +64,7 @@
     inline  bool            isEmpty() const     { return mCount == 0; }
             size_t          capacity() const;
             ssize_t         setCapacity(size_t size);
+            ssize_t         resize(size_t size);
 
             /*! append/insert another vector or array */
             ssize_t         insertVectorAt(const VectorImpl& vector, size_t index);
diff --git a/libs/binder/MemoryBase.cpp b/libs/binder/MemoryBase.cpp
index 033066b..5c82330 100644
--- a/libs/binder/MemoryBase.cpp
+++ b/libs/binder/MemoryBase.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "MemoryBase"
 
 #include <stdlib.h>
 #include <stdint.h>
@@ -44,3 +45,11 @@
 
 // ---------------------------------------------------------------------------
 }; // namespace android
+
+// Backwards compatibility for libdatabase_sqlcipher (http://b/8253769).
+extern "C" void _ZN7android10MemoryBaseC1ERKNS_2spINS_11IMemoryHeapEEEij(void*, void*, ssize_t, size_t);
+extern "C" void _ZN7android10MemoryBaseC1ERKNS_2spINS_11IMemoryHeapEEElj(void* obj, void* h, long o, unsigned int size) {
+    _ZN7android10MemoryBaseC1ERKNS_2spINS_11IMemoryHeapEEEij(obj, h, o, size);
+    ALOGW("Using temporary compatibility workaround for usage of MemoryBase "
+          "private API. Please fix your application!");
+}
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index 544b664..5c7bb4c 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -17,7 +17,6 @@
 	IGraphicBufferProducer.cpp \
 	ISensorEventConnection.cpp \
 	ISensorServer.cpp \
-	ISurface.cpp \
 	ISurfaceComposer.cpp \
 	ISurfaceComposerClient.cpp \
 	LayerState.cpp \
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index d93c067..41ee1be 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -995,7 +995,7 @@
 }
 
 status_t BufferQueue::drainQueueLocked() {
-    while (mSynchronousMode && !mQueue.isEmpty()) {
+    while (mSynchronousMode && mQueue.size() > 1) {
         mDequeueCondition.wait(mMutex);
         if (mAbandoned) {
             ST_LOGE("drainQueueLocked: BufferQueue has been abandoned!");
@@ -1012,7 +1012,7 @@
 status_t BufferQueue::drainQueueAndFreeBuffersLocked() {
     status_t err = drainQueueLocked();
     if (err == NO_ERROR) {
-        if (mSynchronousMode) {
+        if (mQueue.empty()) {
             freeAllBuffersLocked();
         } else {
             freeAllBuffersExceptHeadLocked();
diff --git a/libs/gui/ISurface.cpp b/libs/gui/ISurface.cpp
deleted file mode 100644
index 8c25f45..0000000
--- a/libs/gui/ISurface.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "ISurface"
-
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <binder/Parcel.h>
-
-#include <gui/ISurface.h>
-#include <gui/IGraphicBufferProducer.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------
-
-class BpSurface : public BpInterface<ISurface>
-{
-public:
-    BpSurface(const sp<IBinder>& impl)
-        : BpInterface<ISurface>(impl)
-    {
-    }
-
-    virtual sp<IGraphicBufferProducer> getSurfaceTexture() const {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
-        remote()->transact(GET_SURFACE_TEXTURE, data, &reply);
-        return interface_cast<IGraphicBufferProducer>(reply.readStrongBinder());
-    }
-};
-
-IMPLEMENT_META_INTERFACE(Surface, "android.ui.ISurface");
-
-// ----------------------------------------------------------------------
-
-status_t BnSurface::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch(code) {
-        case GET_SURFACE_TEXTURE: {
-            CHECK_INTERFACE(ISurface, data, reply);
-            reply->writeStrongBinder( getSurfaceTexture()->asBinder() );
-            return NO_ERROR;
-        }
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
-}; // namespace android
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index 101292d..1adc134 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -29,7 +29,7 @@
 #include <ui/Point.h>
 #include <ui/Rect.h>
 
-#include <gui/ISurface.h>
+#include <gui/IGraphicBufferProducer.h>
 #include <gui/ISurfaceComposerClient.h>
 #include <private/gui/LayerState.h>
 
@@ -46,16 +46,13 @@
 {
 public:
     BpSurfaceComposerClient(const sp<IBinder>& impl)
-        : BpInterface<ISurfaceComposerClient>(impl)
-    {
+        : BpInterface<ISurfaceComposerClient>(impl) {
     }
 
-    virtual sp<ISurface> createSurface( const String8& name,
-                                        uint32_t w,
-                                        uint32_t h,
-                                        PixelFormat format,
-                                        uint32_t flags)
-    {
+    virtual status_t createSurface(const String8& name, uint32_t w,
+            uint32_t h, PixelFormat format, uint32_t flags,
+            sp<IBinder>* handle,
+            sp<IGraphicBufferProducer>* gbp) {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
         data.writeString8(name);
@@ -64,11 +61,12 @@
         data.writeInt32(format);
         data.writeInt32(flags);
         remote()->transact(CREATE_SURFACE, data, &reply);
-        return interface_cast<ISurface>(reply.readStrongBinder());
+        *handle = reply.readStrongBinder();
+        *gbp = interface_cast<IGraphicBufferProducer>(reply.readStrongBinder());
+        return reply.readInt32();
     }
 
-    virtual status_t destroySurface(const sp<IBinder>& handle)
-    {
+    virtual status_t destroySurface(const sp<IBinder>& handle) {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
         data.writeStrongBinder(handle);
@@ -92,8 +90,13 @@
             uint32_t h = data.readInt32();
             PixelFormat format = data.readInt32();
             uint32_t flags = data.readInt32();
-            sp<ISurface> s = createSurface(name, w, h, format, flags);
-            reply->writeStrongBinder(s->asBinder());
+            sp<IBinder> handle;
+            sp<IGraphicBufferProducer> gbp;
+            status_t result = createSurface(name, w, h, format, flags,
+                    &handle, &gbp);
+            reply->writeStrongBinder(handle);
+            reply->writeStrongBinder(gbp->asBinder());
+            reply->writeInt32(result);
             return NO_ERROR;
         } break;
         case DESTROY_SURFACE: {
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 950d16a..ec55b57 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -38,22 +38,8 @@
 
 Surface::Surface(
         const sp<IGraphicBufferProducer>& bufferProducer)
+    : mGraphicBufferProducer(bufferProducer)
 {
-    Surface::init();
-    Surface::setIGraphicBufferProducer(bufferProducer);
-}
-
-Surface::Surface() {
-    Surface::init();
-}
-
-Surface::~Surface() {
-    if (mConnectedToCpu) {
-        Surface::disconnect(NATIVE_WINDOW_API_CPU);
-    }
-}
-
-void Surface::init() {
     // Initialize the ANativeWindow function pointers.
     ANativeWindow::setSwapInterval  = hook_setSwapInterval;
     ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;
@@ -87,10 +73,10 @@
     mConnectedToCpu = false;
 }
 
-void Surface::setIGraphicBufferProducer(
-        const sp<IGraphicBufferProducer>& bufferProducer)
-{
-    mGraphicBufferProducer = bufferProducer;
+Surface::~Surface() {
+    if (mConnectedToCpu) {
+        Surface::disconnect(NATIVE_WINDOW_API_CPU);
+    }
 }
 
 sp<IGraphicBufferProducer> Surface::getIGraphicBufferProducer() const {
@@ -723,23 +709,6 @@
 
 // ----------------------------------------------------------------------------
 
-status_t Surface::writeToParcel(
-        const sp<Surface>& surface, Parcel* parcel) {
-    sp<IGraphicBufferProducer> bp;
-    if (surface != NULL) {
-        bp = surface->mGraphicBufferProducer;
-    }
-    return parcel->writeStrongBinder(bp->asBinder());
-}
-
-sp<Surface> Surface::readFromParcel(const Parcel& data) {
-    sp<IBinder> binder(data.readStrongBinder());
-    sp<IGraphicBufferProducer> bp(interface_cast<IGraphicBufferProducer>(binder));
-    return bp != NULL ? new Surface(bp): NULL;
-}
-
-// ----------------------------------------------------------------------------
-
 status_t Surface::lock(
         ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
 {
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index edfa78a..4a4c0c8 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -32,7 +32,6 @@
 #include <ui/DisplayInfo.h>
 
 #include <gui/IGraphicBufferProducer.h>
-#include <gui/ISurface.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/ISurfaceComposerClient.h>
 #include <gui/SurfaceComposerClient.h>
@@ -471,14 +470,18 @@
         PixelFormat format,
         uint32_t flags)
 {
-    sp<SurfaceControl> result;
+    sp<SurfaceControl> sur;
     if (mStatus == NO_ERROR) {
-        sp<ISurface> surface = mClient->createSurface(name, w, h, format, flags);
-        if (surface != 0) {
-            result = new SurfaceControl(this, surface);
+        sp<IBinder> handle;
+        sp<IGraphicBufferProducer> gbp;
+        status_t err = mClient->createSurface(name, w, h, format, flags,
+                &handle, &gbp);
+        ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
+        if (err == NO_ERROR) {
+            sur = new SurfaceControl(this, handle, gbp);
         }
     }
-    return result;
+    return sur;
 }
 
 sp<IBinder> SurfaceComposerClient::createDisplay(const String8& displayName,
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index ef52269..bb57948 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -34,7 +34,6 @@
 #include <ui/GraphicBuffer.h>
 #include <ui/Rect.h>
 
-#include <gui/ISurface.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/Surface.h>
 #include <gui/SurfaceComposerClient.h>
@@ -48,13 +47,10 @@
 
 SurfaceControl::SurfaceControl(
         const sp<SurfaceComposerClient>& client, 
-        const sp<ISurface>& surface)
-    : mClient(client)
+        const sp<IBinder>& handle,
+        const sp<IGraphicBufferProducer>& gbp)
+    : mClient(client), mHandle(handle), mGraphicBufferProducer(gbp)
 {
-    if (surface != 0) {
-        mSurface = surface->asBinder();
-        mGraphicBufferProducer = surface->getSurfaceTexture();
-    }
 }
         
 SurfaceControl::~SurfaceControl()
@@ -65,12 +61,12 @@
 void SurfaceControl::destroy()
 {
     if (isValid()) {
-        mClient->destroySurface(mSurface);
+        mClient->destroySurface(mHandle);
     }
     // clear all references and trigger an IPC now, to make sure things
     // happen without delay, since these resources are quite heavy.
     mClient.clear();
-    mSurface.clear();
+    mHandle.clear();
     mGraphicBufferProducer.clear();
     IPCThreadState::self()->flushCommands();
 }
@@ -91,81 +87,81 @@
 {
     if (lhs == 0 || rhs == 0)
         return false;
-    return lhs->mSurface == rhs->mSurface;
+    return lhs->mHandle == rhs->mHandle;
 }
 
 status_t SurfaceControl::setLayerStack(int32_t layerStack) {
     status_t err = validate();
     if (err < 0) return err;
     const sp<SurfaceComposerClient>& client(mClient);
-    return client->setLayerStack(mSurface, layerStack);
+    return client->setLayerStack(mHandle, layerStack);
 }
 status_t SurfaceControl::setLayer(int32_t layer) {
     status_t err = validate();
     if (err < 0) return err;
     const sp<SurfaceComposerClient>& client(mClient);
-    return client->setLayer(mSurface, layer);
+    return client->setLayer(mHandle, layer);
 }
 status_t SurfaceControl::setPosition(int32_t x, int32_t y) {
     status_t err = validate();
     if (err < 0) return err;
     const sp<SurfaceComposerClient>& client(mClient);
-    return client->setPosition(mSurface, x, y);
+    return client->setPosition(mHandle, x, y);
 }
 status_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
     status_t err = validate();
     if (err < 0) return err;
     const sp<SurfaceComposerClient>& client(mClient);
-    return client->setSize(mSurface, w, h);
+    return client->setSize(mHandle, w, h);
 }
 status_t SurfaceControl::hide() {
     status_t err = validate();
     if (err < 0) return err;
     const sp<SurfaceComposerClient>& client(mClient);
-    return client->hide(mSurface);
+    return client->hide(mHandle);
 }
 status_t SurfaceControl::show() {
     status_t err = validate();
     if (err < 0) return err;
     const sp<SurfaceComposerClient>& client(mClient);
-    return client->show(mSurface);
+    return client->show(mHandle);
 }
 status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) {
     status_t err = validate();
     if (err < 0) return err;
     const sp<SurfaceComposerClient>& client(mClient);
-    return client->setFlags(mSurface, flags, mask);
+    return client->setFlags(mHandle, flags, mask);
 }
 status_t SurfaceControl::setTransparentRegionHint(const Region& transparent) {
     status_t err = validate();
     if (err < 0) return err;
     const sp<SurfaceComposerClient>& client(mClient);
-    return client->setTransparentRegionHint(mSurface, transparent);
+    return client->setTransparentRegionHint(mHandle, transparent);
 }
 status_t SurfaceControl::setAlpha(float alpha) {
     status_t err = validate();
     if (err < 0) return err;
     const sp<SurfaceComposerClient>& client(mClient);
-    return client->setAlpha(mSurface, alpha);
+    return client->setAlpha(mHandle, alpha);
 }
 status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
     status_t err = validate();
     if (err < 0) return err;
     const sp<SurfaceComposerClient>& client(mClient);
-    return client->setMatrix(mSurface, dsdx, dtdx, dsdy, dtdy);
+    return client->setMatrix(mHandle, dsdx, dtdx, dsdy, dtdy);
 }
 status_t SurfaceControl::setCrop(const Rect& crop) {
     status_t err = validate();
     if (err < 0) return err;
     const sp<SurfaceComposerClient>& client(mClient);
-    return client->setCrop(mSurface, crop);
+    return client->setCrop(mHandle, crop);
 }
 
 status_t SurfaceControl::validate() const
 {
-    if (mSurface==0 || mClient==0) {
-        ALOGE("invalid ISurface (%p) or client (%p)",
-                mSurface.get(), mClient.get());
+    if (mHandle==0 || mClient==0) {
+        ALOGE("invalid handle (%p) or client (%p)",
+                mHandle.get(), mClient.get());
         return NO_INIT;
     }
     return NO_ERROR;
diff --git a/libs/utils/RefBase.cpp b/libs/utils/RefBase.cpp
index 2b39bce..0623f46 100644
--- a/libs/utils/RefBase.cpp
+++ b/libs/utils/RefBase.cpp
@@ -15,6 +15,7 @@
  */
 
 #define LOG_TAG "RefBase"
+#define LOG_NDEBUG 0
 
 #include <utils/RefBase.h>
 
@@ -440,39 +441,68 @@
     incWeak(id);
     
     weakref_impl* const impl = static_cast<weakref_impl*>(this);
-    
     int32_t curCount = impl->mStrong;
-    ALOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow",
-               this);
+
+    ALOG_ASSERT(curCount >= 0,
+            "attemptIncStrong called on %p after underflow", this);
+
     while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
+        // we're in the easy/common case of promoting a weak-reference
+        // from an existing strong reference.
         if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
             break;
         }
+        // the strong count has changed on us, we need to re-assert our
+        // situation.
         curCount = impl->mStrong;
     }
     
     if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
-        bool allow;
-        if (curCount == INITIAL_STRONG_VALUE) {
-            // Attempting to acquire first strong reference...  this is allowed
-            // if the object does NOT have a longer lifetime (meaning the
-            // implementation doesn't need to see this), or if the implementation
-            // allows it to happen.
-            allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK
-                  || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
+        // we're now in the harder case of either:
+        // - there never was a strong reference on us
+        // - or, all strong references have been released
+        if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {
+            // this object has a "normal" life-time, i.e.: it gets destroyed
+            // when the last strong reference goes away
+            if (curCount <= 0) {
+                // the last strong-reference got released, the object cannot
+                // be revived.
+                decWeak(id);
+                return false;
+            }
+
+            // here, curCount == INITIAL_STRONG_VALUE, which means
+            // there never was a strong-reference, so we can try to
+            // promote this object; we need to do that atomically.
+            while (curCount > 0) {
+                if (android_atomic_cmpxchg(curCount, curCount + 1,
+                        &impl->mStrong) == 0) {
+                    break;
+                }
+                // the strong count has changed on us, we need to re-assert our
+                // situation (e.g.: another thread has inc/decStrong'ed us)
+                curCount = impl->mStrong;
+            }
+
+            if (curCount <= 0) {
+                // promote() failed, some other thread destroyed us in the
+                // meantime (i.e.: strong count reached zero).
+                decWeak(id);
+                return false;
+            }
         } else {
-            // Attempting to revive the object...  this is allowed
-            // if the object DOES have a longer lifetime (so we can safely
-            // call the object with only a weak ref) and the implementation
-            // allows it to happen.
-            allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK
-                  && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
+            // this object has an "extended" life-time, i.e.: it can be
+            // revived from a weak-reference only.
+            // Ask the object's implementation if it agrees to be revived
+            if (!impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)) {
+                // it didn't so give-up.
+                decWeak(id);
+                return false;
+            }
+            // grab a strong-reference, which is always safe due to the
+            // extended life-time.
+            curCount = android_atomic_inc(&impl->mStrong);
         }
-        if (!allow) {
-            decWeak(id);
-            return false;
-        }
-        curCount = android_atomic_inc(&impl->mStrong);
 
         // If the strong reference count has already been incremented by
         // someone else, the implementor of onIncStrongAttempted() is holding
@@ -490,11 +520,23 @@
     ALOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount);
 #endif
 
-    if (curCount == INITIAL_STRONG_VALUE) {
-        android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong);
-        impl->mBase->onFirstRef();
+    // now we need to fix-up the count if it was INITIAL_STRONG_VALUE
+    // this must be done safely, i.e.: handle the case where several threads
+    // were here in attemptIncStrong().
+    curCount = impl->mStrong;
+    while (curCount >= INITIAL_STRONG_VALUE) {
+        ALOG_ASSERT(curCount > INITIAL_STRONG_VALUE,
+                "attemptIncStrong in %p underflowed to INITIAL_STRONG_VALUE",
+                this);
+        if (android_atomic_cmpxchg(curCount, curCount-INITIAL_STRONG_VALUE,
+                &impl->mStrong) == 0) {
+            break;
+        }
+        // the strong-count changed on us, we need to re-assert the situation,
+        // for e.g.: it's possible the fix-up happened in another thread.
+        curCount = impl->mStrong;
     }
-    
+
     return true;
 }
 
diff --git a/libs/utils/VectorImpl.cpp b/libs/utils/VectorImpl.cpp
index c3257bb..70f49de 100644
--- a/libs/utils/VectorImpl.cpp
+++ b/libs/utils/VectorImpl.cpp
@@ -343,6 +343,16 @@
     return new_capacity;
 }
 
+ssize_t VectorImpl::resize(size_t size) {
+    ssize_t result = NO_ERROR;
+    if (size > mCount) {
+        result = insertAt(mCount, size - mCount);
+    } else if (size < mCount) {
+        result = removeItemsAt(size, mCount - size);
+    }
+    return result < 0 ? result : size;
+}
+
 void VectorImpl::release_storage()
 {
     if (mStorage) {
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 0575e35..dd65348 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -105,10 +105,11 @@
 }
 
 
-sp<ISurface> Client::createSurface(
+status_t Client::createSurface(
         const String8& name,
-        uint32_t w, uint32_t h, PixelFormat format,
-        uint32_t flags)
+        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
+        sp<IBinder>* handle,
+        sp<IGraphicBufferProducer>* gbp)
 {
     /*
      * createSurface must be called from the GL thread so that it can
@@ -116,9 +117,11 @@
      */
 
     class MessageCreateLayer : public MessageBase {
-        sp<ISurface> result;
         SurfaceFlinger* flinger;
         Client* client;
+        sp<IBinder>* handle;
+        sp<IGraphicBufferProducer>* gbp;
+        status_t result;
         const String8& name;
         uint32_t w, h;
         PixelFormat format;
@@ -126,21 +129,23 @@
     public:
         MessageCreateLayer(SurfaceFlinger* flinger,
                 const String8& name, Client* client,
-                uint32_t w, uint32_t h, PixelFormat format,
-                uint32_t flags)
-            : flinger(flinger), client(client), name(name),
-              w(w), h(h), format(format), flags(flags)
-        {
+                uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
+                sp<IBinder>* handle,
+                sp<IGraphicBufferProducer>* gbp)
+            : flinger(flinger), client(client),
+              handle(handle), gbp(gbp),
+              name(name), w(w), h(h), format(format), flags(flags) {
         }
-        sp<ISurface> getResult() const { return result; }
+        status_t getResult() const { return result; }
         virtual bool handler() {
-            result = flinger->createLayer(name, client, w, h, format, flags);
+            result = flinger->createLayer(name, client, w, h, format, flags,
+                    handle, gbp);
             return true;
         }
     };
 
     sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
-            name, this, w, h, format, flags);
+            name, this, w, h, format, flags, handle, gbp);
     mFlinger->postMessageSync(msg);
     return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
 }
diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h
index 4f34b86..84e649f 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -52,10 +52,11 @@
 
 private:
     // ISurfaceComposerClient interface
-    virtual sp<ISurface> createSurface(
+    virtual status_t createSurface(
             const String8& name,
-            uint32_t w, uint32_t h,PixelFormat format,
-            uint32_t flags);
+            uint32_t w, uint32_t h,PixelFormat format, uint32_t flags,
+            sp<IBinder>* handle,
+            sp<IGraphicBufferProducer>* gbp);
 
     virtual status_t destroySurface(const sp<IBinder>& handle);
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 44ef0b8..1677c76 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -52,7 +52,8 @@
 
 int32_t Layer::sSequence = 1;
 
-Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client)
+Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
+        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
     :   contentDirty(false),
         sequence(uint32_t(android_atomic_inc(&sSequence))),
         mFlinger(flinger),
@@ -79,18 +80,42 @@
 {
     mCurrentCrop.makeInvalid();
     glGenTextures(1, &mTextureName);
+
+    uint32_t layerFlags = 0;
+    if (flags & ISurfaceComposerClient::eHidden)
+        layerFlags = layer_state_t::eLayerHidden;
+
+    if (flags & ISurfaceComposerClient::eNonPremultiplied)
+        mPremultipliedAlpha = false;
+
+    mName = name;
+
+    mCurrentState.active.w = w;
+    mCurrentState.active.h = h;
+    mCurrentState.active.crop.makeInvalid();
+    mCurrentState.z = 0;
+    mCurrentState.alpha = 0xFF;
+    mCurrentState.layerStack = 0;
+    mCurrentState.flags = layerFlags;
+    mCurrentState.sequence = 0;
+    mCurrentState.transform.set(0, 0);
+    mCurrentState.requested = mCurrentState.active;
+
+    // drawing state & current state are identical
+    mDrawingState = mCurrentState;
 }
 
 void Layer::onFirstRef()
 {
     // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
-    sp<BufferQueue> bq = new SurfaceTextureLayer();
+    sp<BufferQueue> bq = new SurfaceTextureLayer(mFlinger);
     mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true,
             GL_TEXTURE_EXTERNAL_OES, false, bq);
 
     mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
     mSurfaceFlingerConsumer->setFrameAvailableListener(this);
     mSurfaceFlingerConsumer->setSynchronousMode(true);
+    mSurfaceFlingerConsumer->setName(mName);
 
 #ifdef TARGET_DISABLE_TRIPLE_BUFFERING
 #warning "disabling triple buffering"
@@ -103,8 +128,7 @@
     updateTransformHint(hw);
 }
 
-Layer::~Layer()
-{
+Layer::~Layer() {
     sp<Client> c(mClientRef.promote());
     if (c != 0) {
         c->detachLayer(this);
@@ -129,8 +153,9 @@
     mFlinger->signalLayerUpdate();
 }
 
-// called with SurfaceFlinger::mStateLock as soon as the layer is entered
-// in the purgatory list
+// called with SurfaceFlinger::mStateLock from the drawing thread after
+// the layer has been remove from the current state list (and just before
+// it's removed from the drawing state list)
 void Layer::onRemoved() {
     mSurfaceFlingerConsumer->abandon();
 }
@@ -139,39 +164,10 @@
 // set-up
 // ---------------------------------------------------------------------------
 
-void Layer::setName(const String8& name) {
-    mName = name;
-    mSurfaceFlingerConsumer->setName(name);
-}
-
 String8 Layer::getName() const {
     return mName;
 }
 
-void Layer::initStates(uint32_t w, uint32_t h, uint32_t flags)
-{
-    uint32_t layerFlags = 0;
-    if (flags & ISurfaceComposerClient::eHidden)
-        layerFlags = layer_state_t::eLayerHidden;
-
-    if (flags & ISurfaceComposerClient::eNonPremultiplied)
-        mPremultipliedAlpha = false;
-
-    mCurrentState.active.w = w;
-    mCurrentState.active.h = h;
-    mCurrentState.active.crop.makeInvalid();
-    mCurrentState.z = 0;
-    mCurrentState.alpha = 0xFF;
-    mCurrentState.layerStack = 0;
-    mCurrentState.flags = layerFlags;
-    mCurrentState.sequence = 0;
-    mCurrentState.transform.set(0, 0);
-    mCurrentState.requested = mCurrentState.active;
-
-    // drawing state & current state are identical
-    mDrawingState = mCurrentState;
-}
-
 status_t Layer::setBuffers( uint32_t w, uint32_t h,
                             PixelFormat format, uint32_t flags)
 {
@@ -207,59 +203,47 @@
     return NO_ERROR;
 }
 
-sp<ISurface> Layer::createSurface() {
-    /*
-     * This class provides an implementation of BnSurface (the "native" or
-     * "remote" side of the Binder IPC interface ISurface), and mixes in
-     * LayerCleaner to ensure that mFlinger->onLayerDestroyed() is called for
-     * this layer when the BSurface is destroyed.
-     *
-     * The idea is to provide a handle to the Layer through ISurface that
-     * is cleaned up automatically when the last reference to the ISurface
-     * goes away.  (The references will be held on the "proxy" side, while
-     * the Layer exists on the "native" side.)
-     *
-     * The Layer has a reference to an instance of SurfaceFlinger's variant
-     * of GLConsumer, which holds a reference to the BufferQueue.  The
-     * getSurfaceTexture() call returns a Binder interface reference for
-     * the producer interface of the buffer queue associated with the Layer.
-     */
-    class BSurface : public BnSurface, public LayerCleaner {
-        wp<const Layer> mOwner;
-        virtual sp<IGraphicBufferProducer> getSurfaceTexture() const {
-            sp<IGraphicBufferProducer> res;
-            sp<const Layer> that( mOwner.promote() );
-            if (that != NULL) {
-                res = that->mSurfaceFlingerConsumer->getBufferQueue();
-            }
-            return res;
-        }
-    public:
-        BSurface(const sp<SurfaceFlinger>& flinger,
-                const sp<Layer>& layer)
-            : LayerCleaner(flinger, layer), mOwner(layer) { }
-    };
-    sp<ISurface> sur(new BSurface(mFlinger, this));
-    return sur;
-}
-
-wp<IBinder> Layer::getSurfaceTextureBinder() const {
-    return mSurfaceFlingerConsumer->getBufferQueue()->asBinder();
-}
-
-sp<ISurface> Layer::getSurface()
-{
-    sp<ISurface> s;
+sp<IBinder> Layer::getHandle() {
     Mutex::Autolock _l(mLock);
 
     LOG_ALWAYS_FATAL_IF(mHasSurface,
-            "Layer::getSurface() has already been called");
+            "Layer::getHandle() has already been called");
 
     mHasSurface = true;
-    s = createSurface();
-    return s;
+
+    /*
+     * The layer handle is just a BBinder object passed to the client
+     * (remote process) -- we don't keep any reference on our side such that
+     * the dtor is called when the remote side let go of its reference.
+     *
+     * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
+     * this layer when the handle is destroyed.
+     */
+
+    class Handle : public BBinder, public LayerCleaner {
+        wp<const Layer> mOwner;
+    public:
+        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
+            : LayerCleaner(flinger, layer), mOwner(layer) {
+        }
+    };
+
+    return new Handle(mFlinger, this);
 }
 
+sp<BufferQueue> Layer::getBufferQueue() const {
+    return mSurfaceFlingerConsumer->getBufferQueue();
+}
+
+//virtual sp<IGraphicBufferProducer> getSurfaceTexture() const {
+//    sp<IGraphicBufferProducer> res;
+//    sp<const Layer> that( mOwner.promote() );
+//    if (that != NULL) {
+//        res = that->mSurfaceFlingerConsumer->getBufferQueue();
+//    }
+//    return res;
+//}
+
 // ---------------------------------------------------------------------------
 // h/w composer set-up
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 5fb6d8b..6bca941 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -124,16 +124,12 @@
 
     // -----------------------------------------------------------------------
 
-    Layer(SurfaceFlinger* flinger, const sp<Client>& client);
+    Layer(SurfaceFlinger* flinger, const sp<Client>& client,
+            const String8& name, uint32_t w, uint32_t h, uint32_t flags);
     virtual ~Layer();
 
     // the this layer's size and format
-    status_t setBuffers(uint32_t w, uint32_t h, 
-            PixelFormat format, uint32_t flags=0);
-
-    // Creates an ISurface associated with this object.  This may only be
-    // called once. to provide your own ISurface, override createSurface().
-    sp<ISurface> getSurface();
+    status_t setBuffers(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
 
     // modify current state
     bool setPosition(float x, float y);
@@ -154,18 +150,14 @@
     void computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const;
     Rect computeBounds() const;
 
+    sp<IBinder> getHandle();
+    sp<BufferQueue> getBufferQueue() const;
+    String8 getName() const;
+
     // -----------------------------------------------------------------------
 
-    /*
-     * initStates - called just after construction
-     */
-    virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
-
     virtual const char* getTypeId() const { return "Layer"; }
 
-    virtual void setName(const String8& name);
-    String8 getName() const;
-
     virtual void setGeometry(const sp<const DisplayDevice>& hw,
             HWComposer::HWCLayerInterface& layer);
     virtual void setPerFrameData(const sp<const DisplayDevice>& hw,
@@ -277,8 +269,6 @@
     virtual void onRemoved();
 
 
-    virtual wp<IBinder> getSurfaceTextureBinder() const;
-
     // Updates the transform hint in our SurfaceFlingerConsumer to match
     // the current orientation of the display device.
     virtual void updateTransformHint(const sp<const DisplayDevice>& hw) const;
@@ -336,9 +326,6 @@
 
 
 private:
-    // Creates an instance of ISurface for this Layer.
-    virtual sp<ISurface> createSurface();
-
     // Interface implementation for SurfaceFlingerConsumer::FrameAvailableListener
     virtual void onFrameAvailable();
 
@@ -394,7 +381,7 @@
 
     // protected by mLock
     mutable Mutex mLock;
-    // Set to true if an ISurface has been associated with this object.
+    // Set to true once we've returned this surface's handle
     mutable bool mHasSurface;
     const wp<Client> mClientRef;
 };
diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp
index 23decff..36bafdb 100644
--- a/services/surfaceflinger/LayerDim.cpp
+++ b/services/surfaceflinger/LayerDim.cpp
@@ -33,8 +33,9 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
-LayerDim::LayerDim(SurfaceFlinger* flinger, const sp<Client>& client)
-    : Layer(flinger, client) {
+LayerDim::LayerDim(SurfaceFlinger* flinger, const sp<Client>& client,
+        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
+    : Layer(flinger, client, name, w, h, flags) {
 }
 
 LayerDim::~LayerDim() {
@@ -69,19 +70,6 @@
     }
 }
 
-sp<ISurface> LayerDim::createSurface()
-{
-    class BSurface : public BnSurface, public LayerCleaner {
-        virtual sp<IGraphicBufferProducer> getSurfaceTexture() const { return 0; }
-    public:
-        BSurface(const sp<SurfaceFlinger>& flinger,
-                const sp<Layer>& layer)
-            : LayerCleaner(flinger, layer) { }
-    };
-    sp<ISurface> sur(new BSurface(mFlinger, this));
-    return sur;
-}
-
 bool LayerDim::isVisible() const {
     const Layer::State& s(drawingState());
     return !(s.flags & layer_state_t::eLayerHidden) && s.alpha;
diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h
index e1ea9bd..e19bf52 100644
--- a/services/surfaceflinger/LayerDim.h
+++ b/services/surfaceflinger/LayerDim.h
@@ -32,7 +32,8 @@
 class LayerDim : public Layer
 {
 public:    
-                LayerDim(SurfaceFlinger* flinger, const sp<Client>& client);
+                LayerDim(SurfaceFlinger* flinger, const sp<Client>& client,
+                        const String8& name, uint32_t w, uint32_t h, uint32_t flags);
         virtual ~LayerDim();
 
     virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const;
@@ -44,7 +45,6 @@
 
     virtual bool isFixedSize() const      { return true; }
     virtual bool isVisible() const;
-    virtual sp<ISurface> createSurface();
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 5939dc8..edf01f7 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -574,40 +574,7 @@
         const sp<IGraphicBufferProducer>& bufferProducer) const {
     Mutex::Autolock _l(mStateLock);
     sp<IBinder> surfaceTextureBinder(bufferProducer->asBinder());
-
-    // We want to determine whether the IGraphicBufferProducer was created by
-    // SurfaceFlinger.  Check to see if we can find it in the layer list.
-    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
-    size_t count = currentLayers.size();
-    for (size_t i=0 ; i<count ; i++) {
-        const sp<Layer>& layer(currentLayers[i]);
-        // If this is an instance of Layer (as opposed to, say, LayerDim),
-        // we will get the consumer interface of SurfaceFlingerConsumer's
-        // BufferQueue.  If it's the same Binder object as the graphic
-        // buffer producer interface, return success.
-        wp<IBinder> lbcBinder = layer->getSurfaceTextureBinder();
-        if (lbcBinder == surfaceTextureBinder) {
-            return true;
-        }
-    }
-
-    // Check the layers in the purgatory.  This check is here so that if a
-    // GLConsumer gets destroyed before all the clients are done using it,
-    // the error will not be reported as "surface XYZ is not authenticated", but
-    // will instead fail later on when the client tries to use the surface,
-    // which should be reported as "surface XYZ returned an -ENODEV".  The
-    // purgatorized layers are no less authentic than the visible ones, so this
-    // should not cause any harm.
-    size_t purgatorySize =  mLayerPurgatory.size();
-    for (size_t i=0 ; i<purgatorySize ; i++) {
-        const sp<Layer>& layer(mLayerPurgatory.itemAt(i));
-        wp<IBinder> lbcBinder = layer->getSurfaceTextureBinder();
-        if (lbcBinder == surfaceTextureBinder) {
-            return true;
-        }
-    }
-
-    return false;
+    return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
 }
 
 status_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) {
@@ -1677,6 +1644,7 @@
 
 void SurfaceFlinger::addClientLayer(const sp<Client>& client,
         const sp<IBinder>& handle,
+        const sp<IGraphicBufferProducer>& gbc,
         const sp<Layer>& lbc)
 {
     // attach this layer to the client
@@ -1685,45 +1653,22 @@
     // add this layer to the current state list
     Mutex::Autolock _l(mStateLock);
     mCurrentState.layersSortedByZ.add(lbc);
+    mGraphicBufferProducerList.add(gbc->asBinder());
 }
 
 status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer)
 {
     Mutex::Autolock _l(mStateLock);
-    status_t err = purgatorizeLayer_l(layer);
-    if (err == NO_ERROR)
-        setTransactionFlags(eTransactionNeeded);
-    return err;
-}
-
-status_t SurfaceFlinger::removeLayer_l(const sp<Layer>& layer)
-{
     ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
     if (index >= 0) {
+        mLayersPendingRemoval.push(layer);
         mLayersRemoved = true;
+        setTransactionFlags(eTransactionNeeded);
         return NO_ERROR;
     }
     return status_t(index);
 }
 
-status_t SurfaceFlinger::purgatorizeLayer_l(const sp<Layer>& layer)
-{
-    // First add the layer to the purgatory list, which makes sure it won't
-    // go away, then remove it from the main list (through a transaction).
-    ssize_t err = removeLayer_l(layer);
-    if (err >= 0) {
-        mLayerPurgatory.add(layer);
-    }
-
-    mLayersPendingRemoval.push(layer);
-
-    // it's possible that we don't find a layer, because it might
-    // have been destroyed already -- this is not technically an error
-    // from the user because there is a race between Client::destroySurface(),
-    // ~Client() and ~ISurface().
-    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
-}
-
 uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
 {
     return android_atomic_release_load(&mTransactionFlags);
@@ -1924,48 +1869,49 @@
     return flags;
 }
 
-sp<ISurface> SurfaceFlinger::createLayer(
+status_t SurfaceFlinger::createLayer(
         const String8& name,
         const sp<Client>& client,
-        uint32_t w, uint32_t h, PixelFormat format,
-        uint32_t flags)
+        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
+        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
 {
-    sp<Layer> layer;
-    sp<ISurface> surfaceHandle;
-
+    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
     if (int32_t(w|h) < 0) {
         ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
                 int(w), int(h));
-        return surfaceHandle;
+        return BAD_VALUE;
     }
 
-    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
+    status_t result = NO_ERROR;
+
+    sp<Layer> layer;
+
     switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
         case ISurfaceComposerClient::eFXSurfaceNormal:
-            layer = createNormalLayer(client, w, h, flags, format);
+            result = createNormalLayer(client,
+                    name, w, h, flags, format,
+                    handle, gbp, &layer);
             break;
         case ISurfaceComposerClient::eFXSurfaceDim:
-            layer = createDimLayer(client, w, h, flags);
+            result = createDimLayer(client,
+                    name, w, h, flags,
+                    handle, gbp, &layer);
+            break;
+        default:
+            result = BAD_VALUE;
             break;
     }
 
-    if (layer != 0) {
-        layer->initStates(w, h, flags);
-        layer->setName(name);
-        surfaceHandle = layer->getSurface();
-        if (surfaceHandle != 0) {
-            addClientLayer(client, surfaceHandle->asBinder(), layer);
-        }
+    if (result == NO_ERROR) {
+        addClientLayer(client, *handle, *gbp, layer);
         setTransactionFlags(eTransactionNeeded);
     }
-
-    return surfaceHandle;
+    return result;
 }
 
-sp<Layer> SurfaceFlinger::createNormalLayer(
-        const sp<Client>& client,
-        uint32_t w, uint32_t h, uint32_t flags,
-        PixelFormat& format)
+status_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
+        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
+        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
 {
     // initialize the surfaces
     switch (format) {
@@ -1987,63 +1933,48 @@
         format = PIXEL_FORMAT_RGBA_8888;
 #endif
 
-    sp<Layer> layer = new Layer(this, client);
-    status_t err = layer->setBuffers(w, h, format, flags);
-    if (CC_LIKELY(err != NO_ERROR)) {
-        ALOGE("createNormalLayer() failed (%s)", strerror(-err));
-        layer.clear();
+    *outLayer = new Layer(this, client, name, w, h, flags);
+    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
+    if (err == NO_ERROR) {
+        *handle = (*outLayer)->getHandle();
+        *gbp = (*outLayer)->getBufferQueue();
     }
-    return layer;
+
+    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
+    return err;
 }
 
-sp<LayerDim> SurfaceFlinger::createDimLayer(
-        const sp<Client>& client,
-        uint32_t w, uint32_t h, uint32_t flags)
+status_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
+        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
+        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
 {
-    sp<LayerDim> layer = new LayerDim(this, client);
-    return layer;
+    *outLayer = new LayerDim(this, client, name, w, h, flags);
+    *handle = (*outLayer)->getHandle();
+    *gbp = (*outLayer)->getBufferQueue();
+    return NO_ERROR;
 }
 
 status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
 {
-    /*
-     * called by the window manager, when a surface should be marked for
-     * destruction.
-     *
-     * The surface is removed from the current and drawing lists, but placed
-     * in the purgatory queue, so it's not destroyed right-away (we need
-     * to wait for all client's references to go away first).
-     */
-
-    status_t err = NAME_NOT_FOUND;
-    Mutex::Autolock _l(mStateLock);
-    sp<Layer> layer = client->getLayerUser(handle);
-
-    if (layer != 0) {
-        err = purgatorizeLayer_l(layer);
-        if (err == NO_ERROR) {
-            setTransactionFlags(eTransactionNeeded);
-        }
+    // called by the window manager when it wants to remove a Layer
+    status_t err = NO_ERROR;
+    sp<Layer> l(client->getLayerUser(handle));
+    if (l != NULL) {
+        err = removeLayer(l);
+        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
+                "error removing layer=%p (%s)", l.get(), strerror(-err));
     }
     return err;
 }
 
 status_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
 {
-    // called by ~ISurface() when all references are gone
+    // called by ~LayerCleaner() when all references to the IBinder (handle)
+    // are gone
     status_t err = NO_ERROR;
     sp<Layer> l(layer.promote());
     if (l != NULL) {
-        Mutex::Autolock _l(mStateLock);
-        err = removeLayer_l(l);
-        if (err == NAME_NOT_FOUND) {
-            // The surface wasn't in the current list, which means it was
-            // removed already, which means it is in the purgatory,
-            // and need to be removed from there.
-            ssize_t idx = mLayerPurgatory.remove(l);
-            ALOGE_IF(idx < 0,
-                    "layer=%p is not in the purgatory list", l.get());
-        }
+        err = removeLayer(l);
         ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
                 "error removing layer=%p (%s)", l.get(), strerror(-err));
     }
@@ -2355,18 +2286,6 @@
     }
 
     /*
-     * Dump the layers in the purgatory
-     */
-
-    const size_t purgatorySize = mLayerPurgatory.size();
-    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
-    result.append(buffer);
-    for (size_t i=0 ; i<purgatorySize ; i++) {
-        const sp<Layer>& layer(mLayerPurgatory.itemAt(i));
-        layer->shortDump(result, buffer, SIZE);
-    }
-
-    /*
      * Dump Display state
      */
 
@@ -2480,6 +2399,7 @@
 {
     switch (code) {
         case CREATE_CONNECTION:
+        case CREATE_DISPLAY:
         case SET_TRANSACTION_STATE:
         case BOOT_FINISHED:
         case BLANK:
@@ -2498,6 +2418,7 @@
             break;
         }
         case CAPTURE_SCREEN:
+        case CAPTURE_SCREEN_DEPRECATED:
         {
             // codes that require permission check
             IPCThreadState* ipc = IPCThreadState::self();
@@ -2708,15 +2629,19 @@
     glClearColor(0,0,0,1);
     glClear(GL_COLOR_BUFFER_BIT);
 
-    const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ());
+    const LayerVector& layers( mDrawingState.layersSortedByZ );
     const size_t count = layers.size();
     for (size_t i=0 ; i<count ; ++i) {
         const sp<Layer>& layer(layers[i]);
-        const uint32_t z = layer->drawingState().z;
-        if (z >= minLayerZ && z <= maxLayerZ) {
-            if (filtering) layer->setFiltering(true);
-            layer->draw(hw);
-            if (filtering) layer->setFiltering(false);
+        const Layer::State& state(layer->drawingState());
+        if (state.layerStack == hw->getLayerStack()) {
+            if (state.z >= minLayerZ && state.z <= maxLayerZ) {
+                if (layer->isVisible()) {
+                    if (filtering) layer->setFiltering(true);
+                    layer->draw(hw);
+                    if (filtering) layer->setFiltering(false);
+                }
+            }
         }
     }
 
@@ -2781,7 +2706,7 @@
             sp<GraphicBuffer> buf(consumer->getCurrentBuffer());
             sw = buf->getWidth();
             sh = buf->getHeight();
-            size_t size = buf->getStride() * sh * 4;
+            size_t size = sw * sh * 4;
 
             // allocate shared memory large enough to hold the
             // screen capture
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 241a7d6..e6734d2 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -128,6 +128,7 @@
     friend class Client;
     friend class DisplayEventConnection;
     friend class Layer;
+    friend class SurfaceTextureLayer;
 
     // We're reference counted, never destroy SurfaceFlinger directly
     virtual ~SurfaceFlinger();
@@ -257,19 +258,21 @@
     /* ------------------------------------------------------------------------
      * Layer management
      */
-    sp<ISurface> createLayer(const String8& name, const sp<Client>& client,
-            uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
+    status_t createLayer(const String8& name, const sp<Client>& client,
+            uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
+            sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp);
 
-    sp<Layer> createNormalLayer(const sp<Client>& client,
-            uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format);
+    status_t createNormalLayer(const sp<Client>& client, const String8& name,
+            uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
+            sp<IBinder>* outHandle, sp<IGraphicBufferProducer>* outGbp,
+            sp<Layer>* outLayer);
 
-    sp<LayerDim> createDimLayer(const sp<Client>& client,
-            uint32_t w, uint32_t h, uint32_t flags);
+    status_t createDimLayer(const sp<Client>& client, const String8& name,
+            uint32_t w, uint32_t h, uint32_t flags, sp<IBinder>* outHandle,
+            sp<IGraphicBufferProducer>* outGbp, sp<Layer>* outLayer);
 
     // called in response to the window-manager calling
     // ISurfaceComposerClient::destroySurface()
-    // The specified layer is first placed in a purgatory list
-    // until all references from the client are released.
     status_t onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle);
 
     // called when all clients have released all their references to
@@ -281,11 +284,10 @@
     status_t removeLayer(const sp<Layer>& layer);
 
     // add a layer to SurfaceFlinger
-    void addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,
-        const sp<Layer>& lbc);
-
-    status_t removeLayer_l(const sp<Layer>& layer);
-    status_t purgatorizeLayer_l(const sp<Layer>& layer);
+    void addClientLayer(const sp<Client>& client,
+            const sp<IBinder>& handle,
+            const sp<IGraphicBufferProducer>& gbc,
+            const sp<Layer>& lbc);
 
     /* ------------------------------------------------------------------------
      * Boot animation, on/off animations and screen capture
@@ -399,10 +401,10 @@
     State mCurrentState;
     volatile int32_t mTransactionFlags;
     Condition mTransactionCV;
-    SortedVector< sp<Layer> > mLayerPurgatory;
     bool mTransactionPending;
     bool mAnimTransactionPending;
     Vector< sp<Layer> > mLayersPendingRemoval;
+    SortedVector< wp<IBinder> > mGraphicBufferProducerList;
 
     // protected by mStateLock (but we could use another lock)
     bool mLayersRemoved;
diff --git a/services/surfaceflinger/SurfaceTextureLayer.cpp b/services/surfaceflinger/SurfaceTextureLayer.cpp
index 395c8c8..d0f0dae 100644
--- a/services/surfaceflinger/SurfaceTextureLayer.cpp
+++ b/services/surfaceflinger/SurfaceTextureLayer.cpp
@@ -20,17 +20,35 @@
 
 #include <utils/Errors.h>
 
+#include "SurfaceFlinger.h"
 #include "SurfaceTextureLayer.h"
 
 namespace android {
 // ---------------------------------------------------------------------------
 
 
-SurfaceTextureLayer::SurfaceTextureLayer()
-    : BufferQueue(true) {
+SurfaceTextureLayer::SurfaceTextureLayer(const sp<SurfaceFlinger>& flinger)
+    : BufferQueue(true), flinger(flinger) {
 }
 
 SurfaceTextureLayer::~SurfaceTextureLayer() {
+    // remove ourselves from SurfaceFlinger's list. We do this asynchronously
+    // because we don't know where this dtor is called from, it could be
+    // called with the mStateLock held, leading to a dead-lock (it actually
+    // happens).
+    class MessageCleanUpList : public MessageBase {
+        sp<SurfaceFlinger> flinger;
+        wp<IBinder> gbp;
+    public:
+        MessageCleanUpList(const sp<SurfaceFlinger>& flinger, const wp<IBinder>& gbp)
+            : flinger(flinger), gbp(gbp) { }
+        virtual bool handler() {
+            Mutex::Autolock _l(flinger->mStateLock);
+            flinger->mGraphicBufferProducerList.remove(gbp);
+            return true;
+        }
+    };
+    flinger->postMessageAsync( new MessageCleanUpList(flinger, this) );
 }
 
 status_t SurfaceTextureLayer::connect(int api, QueueBufferOutput* output) {
diff --git a/services/surfaceflinger/SurfaceTextureLayer.h b/services/surfaceflinger/SurfaceTextureLayer.h
index a75ccf4..13cff2f 100644
--- a/services/surfaceflinger/SurfaceTextureLayer.h
+++ b/services/surfaceflinger/SurfaceTextureLayer.h
@@ -28,15 +28,16 @@
 // ---------------------------------------------------------------------------
 
 class Layer;
+class SurfaceFlinger;
 
 /*
  * This is a thin wrapper around BufferQueue, used by the Layer class.
  */
-class SurfaceTextureLayer : public BufferQueue
-{
+class SurfaceTextureLayer : public BufferQueue {
+    sp<SurfaceFlinger> flinger;
 public:
-    SurfaceTextureLayer();
-    ~SurfaceTextureLayer();
+    SurfaceTextureLayer(const sp<SurfaceFlinger>& flinger);
+    virtual ~SurfaceTextureLayer();
 
     // After calling the superclass connect(), set or clear synchronous
     // mode appropriately for the specified API.
diff --git a/services/surfaceflinger/tests/surface/Android.mk b/services/surfaceflinger/tests/surface/Android.mk
deleted file mode 100644
index c59060e..0000000
--- a/services/surfaceflinger/tests/surface/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-	surface.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-	libcutils \
-	libutils \
-	libbinder \
-    libui \
-    libgui
-
-LOCAL_MODULE:= test-surface
-
-LOCAL_MODULE_TAGS := tests
-
-include $(BUILD_EXECUTABLE)
diff --git a/services/surfaceflinger/tests/surface/surface.cpp b/services/surfaceflinger/tests/surface/surface.cpp
deleted file mode 100644
index 9c41cc3..0000000
--- a/services/surfaceflinger/tests/surface/surface.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <cutils/memory.h>
-
-#include <utils/Log.h>
-
-#include <binder/IPCThreadState.h>
-#include <binder/ProcessState.h>
-#include <binder/IServiceManager.h>
-
-#include <gui/Surface.h>
-#include <gui/SurfaceComposerClient.h>
-
-using namespace android;
-
-int main(int argc, char** argv)
-{
-    // set up the thread-pool
-    sp<ProcessState> proc(ProcessState::self());
-    ProcessState::self()->startThreadPool();
-
-    // create a client to surfaceflinger
-    sp<SurfaceComposerClient> client = new SurfaceComposerClient();
-    
-    sp<SurfaceControl> surfaceControl = client->createSurface(
-            String8("surface"), 160, 240, PIXEL_FORMAT_RGB_565, 0);
-    SurfaceComposerClient::openGlobalTransaction();
-    surfaceControl->setLayer(100000);
-    SurfaceComposerClient::closeGlobalTransaction();
-
-    // pretend it went cross-process
-    Parcel parcel;
-    SurfaceControl::writeSurfaceToParcel(surfaceControl, &parcel);
-    parcel.setDataPosition(0);
-    sp<Surface> surface = Surface::readFromParcel(parcel);
-    ANativeWindow* window = surface.get();
-
-    printf("window=%p\n", window);
-
-    int err = native_window_set_buffer_count(window, 8);
-    ANativeWindowBuffer* buffer;
-
-    for (int i=0 ; i<8 ; i++) {
-        window->dequeueBuffer(window, &buffer);
-        printf("buffer %d: %p\n", i, buffer);
-    }
-
-    printf("test complete. CTRL+C to finish.\n");
-
-    IPCThreadState::self()->joinThreadPool();
-    return 0;
-}