Merge "Support for getting the background color"
diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h
index f8c3216..ca17082 100644
--- a/include/utils/RefBase.h
+++ b/include/utils/RefBase.h
@@ -119,6 +119,7 @@
     // used to override the RefBase destruction.
     class Destroyer {
         friend class RefBase;
+        friend class weakref_type;
     public:
         virtual ~Destroyer();
     private:
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index e1a85f3..a4c5b36 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -32,6 +32,7 @@
     virtual void SetUp() {
         mST = new SurfaceTexture(123);
         mSTC = new SurfaceTextureClient(mST);
+        mANW = mSTC;
 
         // We need a valid GL context so we can test updateTexImage()
         // This initializes EGL and create a dummy GL context with a
@@ -69,6 +70,8 @@
     virtual void TearDown() {
         mST.clear();
         mSTC.clear();
+        mANW.clear();
+
         eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
         eglDestroyContext(mEglDisplay, mEglContext);
         eglDestroySurface(mEglDisplay, mEglSurface);
@@ -86,6 +89,8 @@
 
     sp<SurfaceTexture> mST;
     sp<SurfaceTextureClient> mSTC;
+    sp<ANativeWindow> mANW;
+
     EGLDisplay mEglDisplay;
     EGLSurface mEglSurface;
     EGLContext mEglContext;
@@ -97,31 +102,26 @@
 }
 
 TEST_F(SurfaceTextureClientTest, QueuesToWindowCompositorIsFalse) {
-    sp<ANativeWindow> anw(mSTC);
     int result = -123;
-    int err = anw->query(anw.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
+    int err = mANW->query(mANW.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
             &result);
     EXPECT_EQ(NO_ERROR, err);
     EXPECT_EQ(0, result);
 }
 
 TEST_F(SurfaceTextureClientTest, ConcreteTypeIsSurfaceTextureClient) {
-    sp<ANativeWindow> anw(mSTC);
     int result = -123;
-    int err = anw->query(anw.get(), NATIVE_WINDOW_CONCRETE_TYPE, &result);
+    int err = mANW->query(mANW.get(), NATIVE_WINDOW_CONCRETE_TYPE, &result);
     EXPECT_EQ(NO_ERROR, err);
     EXPECT_EQ(NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT, result);
 }
 
 TEST_F(SurfaceTextureClientTest, ANativeWindowLockFails) {
-    sp<ANativeWindow> anw(mSTC);
     ANativeWindow_Buffer buf;
-    ASSERT_EQ(BAD_VALUE, ANativeWindow_lock(anw.get(), &buf, NULL));
+    ASSERT_EQ(BAD_VALUE, ANativeWindow_lock(mANW.get(), &buf, NULL));
 }
 
 TEST_F(SurfaceTextureClientTest, EglCreateWindowSurfaceSucceeds) {
-    sp<ANativeWindow> anw(mSTC);
-
     EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     ASSERT_EQ(EGL_SUCCESS, eglGetError());
     ASSERT_NE(EGL_NO_DISPLAY, dpy);
@@ -147,7 +147,7 @@
             &numConfigs));
     ASSERT_EQ(EGL_SUCCESS, eglGetError());
 
-    EGLSurface eglSurface = eglCreateWindowSurface(dpy, myConfig, anw.get(),
+    EGLSurface eglSurface = eglCreateWindowSurface(dpy, myConfig, mANW.get(),
             NULL);
     EXPECT_NE(EGL_NO_SURFACE, eglSurface);
     EXPECT_EQ(EGL_SUCCESS, eglGetError());
@@ -156,269 +156,246 @@
 }
 
 TEST_F(SurfaceTextureClientTest, BufferGeometryInvalidSizesFail) {
-    sp<ANativeWindow> anw(mSTC);
-
-    EXPECT_GT(OK, native_window_set_buffers_geometry(anw.get(), -1,  0,  0));
-    EXPECT_GT(OK, native_window_set_buffers_geometry(anw.get(),  0, -1,  0));
-    EXPECT_GT(OK, native_window_set_buffers_geometry(anw.get(),  0,  0, -1));
-    EXPECT_GT(OK, native_window_set_buffers_geometry(anw.get(), -1, -1,  0));
-    EXPECT_GT(OK, native_window_set_buffers_geometry(anw.get(),  0,  8,  0));
-    EXPECT_GT(OK, native_window_set_buffers_geometry(anw.get(),  8,  0,  0));
+    EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), -1,  0,  0));
+    EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(),  0, -1,  0));
+    EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(),  0,  0, -1));
+    EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), -1, -1,  0));
+    EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(),  0,  8,  0));
+    EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(),  8,  0,  0));
 }
 
 TEST_F(SurfaceTextureClientTest, DefaultGeometryValues) {
-    sp<ANativeWindow> anw(mSTC);
     ANativeWindowBuffer* buf;
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
     EXPECT_EQ(1, buf->width);
     EXPECT_EQ(1, buf->height);
     EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
 }
 
 TEST_F(SurfaceTextureClientTest, BufferGeometryCanBeSet) {
-    sp<ANativeWindow> anw(mSTC);
     ANativeWindowBuffer* buf;
-    EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 16, 8, PIXEL_FORMAT_RGB_565));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
+    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, PIXEL_FORMAT_RGB_565));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
     EXPECT_EQ(16, buf->width);
     EXPECT_EQ(8, buf->height);
     EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
 }
 
 TEST_F(SurfaceTextureClientTest, BufferGeometryDefaultSizeSetFormat) {
-    sp<ANativeWindow> anw(mSTC);
     ANativeWindowBuffer* buf;
-    EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 0, 0, PIXEL_FORMAT_RGB_565));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
+    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, PIXEL_FORMAT_RGB_565));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
     EXPECT_EQ(1, buf->width);
     EXPECT_EQ(1, buf->height);
     EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
 }
 
 TEST_F(SurfaceTextureClientTest, BufferGeometrySetSizeDefaultFormat) {
-    sp<ANativeWindow> anw(mSTC);
     ANativeWindowBuffer* buf;
-    EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 16, 8, 0));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
+    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
     EXPECT_EQ(16, buf->width);
     EXPECT_EQ(8, buf->height);
     EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
 }
 
 TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeUnset) {
-    sp<ANativeWindow> anw(mSTC);
     ANativeWindowBuffer* buf;
-    EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 16, 8, 0));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
+    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
     EXPECT_EQ(16, buf->width);
     EXPECT_EQ(8, buf->height);
     EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf));
-    EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 0, 0, 0));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
+    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, 0));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
     EXPECT_EQ(1, buf->width);
     EXPECT_EQ(1, buf->height);
     EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
 }
 
 TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeChangedWithoutFormat) {
-    sp<ANativeWindow> anw(mSTC);
     ANativeWindowBuffer* buf;
-    EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 0, 0, PIXEL_FORMAT_RGB_565));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
+    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, PIXEL_FORMAT_RGB_565));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
     EXPECT_EQ(1, buf->width);
     EXPECT_EQ(1, buf->height);
     EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf));
-    EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 16, 8, 0));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
+    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
     EXPECT_EQ(16, buf->width);
     EXPECT_EQ(8, buf->height);
     EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
 }
 
 TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSize) {
-    sp<ANativeWindow> anw(mSTC);
     sp<SurfaceTexture> st(mST);
     ANativeWindowBuffer* buf;
     EXPECT_EQ(OK, st->setDefaultBufferSize(16, 8));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
     EXPECT_EQ(16, buf->width);
     EXPECT_EQ(8, buf->height);
     EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
 }
 
 TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeAfterDequeue) {
-    sp<ANativeWindow> anw(mSTC);
-    sp<SurfaceTexture> st(mST);
     ANativeWindowBuffer* buf[2];
-    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 4));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
+    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
     EXPECT_NE(buf[0], buf[1]);
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[0]));
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[1]));
-    EXPECT_EQ(OK, st->setDefaultBufferSize(16, 8));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0]));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1]));
+    EXPECT_EQ(OK, mST->setDefaultBufferSize(16, 8));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
     EXPECT_NE(buf[0], buf[1]);
     EXPECT_EQ(16, buf[0]->width);
     EXPECT_EQ(16, buf[1]->width);
     EXPECT_EQ(8, buf[0]->height);
     EXPECT_EQ(8, buf[1]->height);
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[0]));
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[1]));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0]));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1]));
 }
 
 TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeVsGeometry) {
-    sp<ANativeWindow> anw(mSTC);
-    sp<SurfaceTexture> st(mST);
     ANativeWindowBuffer* buf[2];
-    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 4));
-    EXPECT_EQ(OK, st->setDefaultBufferSize(16, 8));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
+    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
+    EXPECT_EQ(OK, mST->setDefaultBufferSize(16, 8));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
     EXPECT_NE(buf[0], buf[1]);
     EXPECT_EQ(16, buf[0]->width);
     EXPECT_EQ(16, buf[1]->width);
     EXPECT_EQ(8, buf[0]->height);
     EXPECT_EQ(8, buf[1]->height);
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[0]));
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[1]));
-    EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 12, 24, 0));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0]));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1]));
+    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 12, 24, 0));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
     EXPECT_NE(buf[0], buf[1]);
     EXPECT_EQ(12, buf[0]->width);
     EXPECT_EQ(12, buf[1]->width);
     EXPECT_EQ(24, buf[0]->height);
     EXPECT_EQ(24, buf[1]->height);
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[0]));
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[1]));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0]));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1]));
 }
 
 TEST_F(SurfaceTextureClientTest, SurfaceTextureTooManyUpdateTexImage) {
-    sp<ANativeWindow> anw(mSTC);
-    sp<SurfaceTexture> st(mST);
     android_native_buffer_t* buf[3];
-    ASSERT_EQ(OK, st->setSynchronousMode(false));
-    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 4));
+    ASSERT_EQ(OK, mST->setSynchronousMode(false));
+    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
 
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
-    EXPECT_EQ(OK, st->updateTexImage());
-    EXPECT_EQ(OK, st->updateTexImage());
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
+    EXPECT_EQ(OK, mST->updateTexImage());
+    EXPECT_EQ(OK, mST->updateTexImage());
 
-    ASSERT_EQ(OK, st->setSynchronousMode(true));
-    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 3));
+    ASSERT_EQ(OK, mST->setSynchronousMode(true));
+    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
 
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
 
-    EXPECT_EQ(OK, st->updateTexImage());
-    EXPECT_EQ(OK, st->updateTexImage());
-    EXPECT_EQ(OK, st->updateTexImage());
+    EXPECT_EQ(OK, mST->updateTexImage());
+    EXPECT_EQ(OK, mST->updateTexImage());
+    EXPECT_EQ(OK, mST->updateTexImage());
 }
 
 TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeSlowRetire) {
-    sp<ANativeWindow> anw(mSTC);
-    sp<SurfaceTexture> st(mST);
     android_native_buffer_t* buf[3];
-    ASSERT_EQ(OK, st->setSynchronousMode(true));
-    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 4));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
+    ASSERT_EQ(OK, mST->setSynchronousMode(true));
+    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
     EXPECT_NE(buf[0], buf[1]);
     EXPECT_NE(buf[1], buf[2]);
     EXPECT_NE(buf[2], buf[0]);
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[2]));
-    EXPECT_EQ(OK, st->updateTexImage());
-    EXPECT_EQ(st->getCurrentBuffer().get(), buf[0]);
-    EXPECT_EQ(OK, st->updateTexImage());
-    EXPECT_EQ(st->getCurrentBuffer().get(), buf[1]);
-    EXPECT_EQ(OK, st->updateTexImage());
-    EXPECT_EQ(st->getCurrentBuffer().get(), buf[2]);
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2]));
+    EXPECT_EQ(OK, mST->updateTexImage());
+    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]);
+    EXPECT_EQ(OK, mST->updateTexImage());
+    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
+    EXPECT_EQ(OK, mST->updateTexImage());
+    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[2]);
 }
 
 TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeFastRetire) {
-    sp<ANativeWindow> anw(mSTC);
-    sp<SurfaceTexture> st(mST);
     android_native_buffer_t* buf[3];
-    ASSERT_EQ(OK, st->setSynchronousMode(true));
-    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 4));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
+    ASSERT_EQ(OK, mST->setSynchronousMode(true));
+    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
     EXPECT_NE(buf[0], buf[1]);
     EXPECT_NE(buf[1], buf[2]);
     EXPECT_NE(buf[2], buf[0]);
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
-    EXPECT_EQ(OK, st->updateTexImage());
-    EXPECT_EQ(st->getCurrentBuffer().get(), buf[0]);
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
-    EXPECT_EQ(OK, st->updateTexImage());
-    EXPECT_EQ(st->getCurrentBuffer().get(), buf[1]);
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[2]));
-    EXPECT_EQ(OK, st->updateTexImage());
-    EXPECT_EQ(st->getCurrentBuffer().get(), buf[2]);
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
+    EXPECT_EQ(OK, mST->updateTexImage());
+    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]);
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
+    EXPECT_EQ(OK, mST->updateTexImage());
+    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2]));
+    EXPECT_EQ(OK, mST->updateTexImage());
+    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[2]);
 }
 
 TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeDQQR) {
-    sp<ANativeWindow> anw(mSTC);
-    sp<SurfaceTexture> st(mST);
     android_native_buffer_t* buf[3];
-    ASSERT_EQ(OK, st->setSynchronousMode(true));
-    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 3));
+    ASSERT_EQ(OK, mST->setSynchronousMode(true));
+    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
 
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
-    EXPECT_EQ(OK, st->updateTexImage());
-    EXPECT_EQ(st->getCurrentBuffer().get(), buf[0]);
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
+    EXPECT_EQ(OK, mST->updateTexImage());
+    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]);
 
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
     EXPECT_NE(buf[0], buf[1]);
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
-    EXPECT_EQ(OK, st->updateTexImage());
-    EXPECT_EQ(st->getCurrentBuffer().get(), buf[1]);
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
+    EXPECT_EQ(OK, mST->updateTexImage());
+    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
 
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
     EXPECT_NE(buf[1], buf[2]);
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[2]));
-    EXPECT_EQ(OK, st->updateTexImage());
-    EXPECT_EQ(st->getCurrentBuffer().get(), buf[2]);
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2]));
+    EXPECT_EQ(OK, mST->updateTexImage());
+    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[2]);
 }
 
 // XXX: We currently have no hardware that properly handles dequeuing the
 // buffer that is currently bound to the texture.
 TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeDequeueCurrent) {
-    sp<ANativeWindow> anw(mSTC);
-    sp<SurfaceTexture> st(mST);
     android_native_buffer_t* buf[3];
     android_native_buffer_t* firstBuf;
-    ASSERT_EQ(OK, st->setSynchronousMode(true));
-    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 3));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &firstBuf));
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), firstBuf));
-    EXPECT_EQ(OK, st->updateTexImage());
-    EXPECT_EQ(st->getCurrentBuffer().get(), firstBuf);
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[2]));
+    ASSERT_EQ(OK, mST->setSynchronousMode(true));
+    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &firstBuf));
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), firstBuf));
+    EXPECT_EQ(OK, mST->updateTexImage());
+    EXPECT_EQ(mST->getCurrentBuffer().get(), firstBuf);
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2]));
     EXPECT_NE(buf[0], buf[1]);
     EXPECT_NE(buf[1], buf[2]);
     EXPECT_NE(buf[2], buf[0]);
@@ -426,41 +403,36 @@
 }
 
 TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeMinUndequeued) {
-    sp<ANativeWindow> anw(mSTC);
-    sp<SurfaceTexture> st(mST);
     android_native_buffer_t* buf[3];
-    ASSERT_EQ(OK, st->setSynchronousMode(true));
-    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 3));
+    ASSERT_EQ(OK, mST->setSynchronousMode(true));
+    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
 
-    // We should be able to dequeue all the buffers before we've queued any.
-    EXPECT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
-    EXPECT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
-    EXPECT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
+    // We should be able to dequeue all the buffers before we've queued mANWy.
+    EXPECT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
+    EXPECT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
+    EXPECT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
 
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[2]));
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2]));
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
 
-    EXPECT_EQ(OK, st->updateTexImage());
-    EXPECT_EQ(st->getCurrentBuffer().get(), buf[1]);
+    EXPECT_EQ(OK, mST->updateTexImage());
+    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
 
-    EXPECT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
+    EXPECT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
 
     // Once we've queued a buffer, however we should not be able to dequeue more
     // than (buffer-count - MIN_UNDEQUEUED_BUFFERS), which is 2 in this case.
-    EXPECT_EQ(-EBUSY, anw->dequeueBuffer(anw.get(), &buf[1]));
+    EXPECT_EQ(-EBUSY, mANW->dequeueBuffer(mANW.get(), &buf[1]));
 
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[0]));
-    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[2]));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0]));
+    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2]));
 }
 
 // XXX: This is not expected to pass until the synchronization hacks are removed
 // from the SurfaceTexture class.
 TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeWaitRetire) {
-    sp<ANativeWindow> anw(mSTC);
-    sp<SurfaceTexture> st(mST);
-
     class MyThread : public Thread {
-        sp<SurfaceTexture> st;
+        sp<SurfaceTexture> mST;
         EGLContext ctx;
         EGLSurface sur;
         EGLDisplay dpy;
@@ -470,14 +442,14 @@
             eglMakeCurrent(dpy, sur, sur, ctx);
             usleep(20000);
             Mutex::Autolock _l(mLock);
-            st->updateTexImage();
+            mST->updateTexImage();
             mBufferRetired = true;
             eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
             return false;
         }
     public:
-        MyThread(const sp<SurfaceTexture>& st)
-            : st(st), mBufferRetired(false) {
+        MyThread(const sp<SurfaceTexture>& mST)
+            : mST(mST), mBufferRetired(false) {
             ctx = eglGetCurrentContext();
             sur = eglGetCurrentSurface(EGL_DRAW);
             dpy = eglGetCurrentDisplay();
@@ -493,37 +465,35 @@
     };
 
     android_native_buffer_t* buf[3];
-    ASSERT_EQ(OK, st->setSynchronousMode(true));
-    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 3));
+    ASSERT_EQ(OK, mST->setSynchronousMode(true));
+    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
     // dequeue/queue/update so we have a current buffer
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
-    st->updateTexImage();
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
+    mST->updateTexImage();
 
-    MyThread* thread = new MyThread(st);
+    MyThread* thread = new MyThread(mST);
     sp<Thread> threadBase(thread);
 
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
     thread->run();
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
-    //ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
-    //ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[2]));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
+    //ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
+    //ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2]));
     thread->bufferDequeued();
     thread->requestExitAndWait();
 }
 
 TEST_F(SurfaceTextureClientTest, GetTransformMatrixReturnsVerticalFlip) {
-    sp<ANativeWindow> anw(mSTC);
-    sp<SurfaceTexture> st(mST);
     android_native_buffer_t* buf[3];
     float mtx[16] = {};
-    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 4));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
-    ASSERT_EQ(OK, st->updateTexImage());
-    st->getTransformMatrix(mtx);
+    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
+    ASSERT_EQ(OK, mST->updateTexImage());
+    mST->getTransformMatrix(mtx);
 
     EXPECT_EQ(1.f, mtx[0]);
     EXPECT_EQ(0.f, mtx[1]);
@@ -547,16 +517,14 @@
 }
 
 TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffers) {
-    sp<ANativeWindow> anw(mSTC);
-    sp<SurfaceTexture> st(mST);
     android_native_buffer_t* buf[3];
     float mtx[16] = {};
-    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 4));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
-    ASSERT_EQ(OK, st->updateTexImage());
-    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 6)); // frees buffers
-    st->getTransformMatrix(mtx);
+    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
+    ASSERT_EQ(OK, mST->updateTexImage());
+    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 6)); // frees buffers
+    mST->getTransformMatrix(mtx);
 
     EXPECT_EQ(1.f, mtx[0]);
     EXPECT_EQ(0.f, mtx[1]);
@@ -580,8 +548,6 @@
 }
 
 TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffersWithCrop) {
-    sp<ANativeWindow> anw(mSTC);
-    sp<SurfaceTexture> st(mST);
     android_native_buffer_t* buf[3];
     float mtx[16] = {};
     android_native_rect_t crop;
@@ -590,14 +556,14 @@
     crop.right = 5;
     crop.bottom = 5;
 
-    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 4));
-    ASSERT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 8, 8, 0));
-    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
-    ASSERT_EQ(OK, native_window_set_crop(anw.get(), &crop));
-    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
-    ASSERT_EQ(OK, st->updateTexImage());
-    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 6)); // frees buffers
-    st->getTransformMatrix(mtx);
+    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
+    ASSERT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 8, 8, 0));
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
+    ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &crop));
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
+    ASSERT_EQ(OK, mST->updateTexImage());
+    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 6)); // frees buffers
+    mST->getTransformMatrix(mtx);
 
     // This accounts for the 1 texel shrink for each edge that's included in the
     // transform matrix to avoid texturing outside the crop region.
@@ -622,4 +588,29 @@
     EXPECT_EQ(1.f, mtx[15]);
 }
 
+// This test verifies that the buffer format can be queried immediately after
+// it is set.
+TEST_F(SurfaceTextureClientTest, DISABLED_QueryFormatAfterSettingWorks) {
+    sp<ANativeWindow> anw(mSTC);
+    int fmts[] = {
+        // RGBA_8888 should not come first, as it's the default
+        HAL_PIXEL_FORMAT_RGBX_8888,
+        HAL_PIXEL_FORMAT_RGBA_8888,
+        HAL_PIXEL_FORMAT_RGB_888,
+        HAL_PIXEL_FORMAT_RGB_565,
+        HAL_PIXEL_FORMAT_BGRA_8888,
+        HAL_PIXEL_FORMAT_RGBA_5551,
+        HAL_PIXEL_FORMAT_RGBA_4444,
+        HAL_PIXEL_FORMAT_YV12,
+    };
+
+    const int numFmts = (sizeof(fmts) / sizeof(fmts[0]));
+    for (int i = 0; i < numFmts; i++) {
+      int fmt = -1;
+      ASSERT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 0, 0, fmts[i]));
+      ASSERT_EQ(OK, anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt));
+      EXPECT_EQ(fmts[i], fmt);
+    }
+}
+
 } // namespace android
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index 56c1702..50af3bb 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -46,8 +46,6 @@
     }
 
     virtual void SetUp() {
-        EGLBoolean returnValue;
-
         mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
         ASSERT_EQ(EGL_SUCCESS, eglGetError());
         ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
@@ -59,9 +57,8 @@
         RecordProperty("EglVersionMajor", majorVersion);
         RecordProperty("EglVersionMajor", minorVersion);
 
-        EGLConfig myConfig = {0};
         EGLint numConfigs = 0;
-        EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &myConfig,
+        EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mGlConfig,
                 1, &numConfigs));
         ASSERT_EQ(EGL_SUCCESS, eglGetError());
 
@@ -88,12 +85,12 @@
             ASSERT_TRUE(mSurfaceControl->isValid());
 
             ASSERT_EQ(NO_ERROR, mComposerClient->openTransaction());
-            ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(30000));
+            ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
             ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
             ASSERT_EQ(NO_ERROR, mComposerClient->closeTransaction());
 
             sp<ANativeWindow> window = mSurfaceControl->getSurface();
-            mEglSurface = eglCreateWindowSurface(mEglDisplay, myConfig,
+            mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
                     window.get(), NULL);
         } else {
             EGLint pbufferAttribs[] = {
@@ -101,13 +98,13 @@
                 EGL_HEIGHT, getSurfaceHeight(),
                 EGL_NONE };
 
-            mEglSurface = eglCreatePbufferSurface(mEglDisplay, myConfig,
+            mEglSurface = eglCreatePbufferSurface(mEglDisplay, mGlConfig,
                     pbufferAttribs);
         }
         ASSERT_EQ(EGL_SUCCESS, eglGetError());
         ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
 
-        mEglContext = eglCreateContext(mEglDisplay, myConfig, EGL_NO_CONTEXT,
+        mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT,
                 getContextAttribs());
         ASSERT_EQ(EGL_SUCCESS, eglGetError());
         ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
@@ -329,6 +326,7 @@
     EGLDisplay mEglDisplay;
     EGLSurface mEglSurface;
     EGLContext mEglContext;
+    EGLConfig  mGlConfig;
 };
 
 // XXX: Code above this point should live elsewhere
@@ -401,6 +399,18 @@
         glBindTexture(GL_TEXTURE_EXTERNAL_OES, TEX_ID);
         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
 
+        // XXX: These calls are not needed for GL_TEXTURE_EXTERNAL_OES as
+        // they're setting the defautls for that target, but when hacking things
+        // to use GL_TEXTURE_2D they are needed to achieve the same behavior.
+        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+
         GLfloat texMatrix[16];
         mST->getTransformMatrix(texMatrix);
         glUniformMatrix4fv(mTexMatrixHandle, 1, GL_FALSE, texMatrix);
@@ -474,12 +484,26 @@
     }
 }
 
+void fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride) {
+    const size_t PIXEL_SIZE = 4;
+    for (int x = 0; x < w; x++) {
+        for (int y = 0; y < h; y++) {
+            off_t offset = (y * stride + x) * PIXEL_SIZE;
+            for (int c = 0; c < 4; c++) {
+                int parityX = (x / (1 << (c+2))) & 1;
+                int parityY = (y / (1 << (c+2))) & 1;
+                buf[offset + c] = (parityX ^ parityY) ? 231 : 35;
+            }
+        }
+    }
+}
+
 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) {
-    const int yuvTexWidth = 64;
-    const int yuvTexHeight = 66;
+    const int texWidth = 64;
+    const int texHeight = 66;
 
     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
-            yuvTexWidth, yuvTexHeight, HAL_PIXEL_FORMAT_YV12));
+            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
 
@@ -493,7 +517,7 @@
     // Fill the buffer with the a checkerboard pattern
     uint8_t* img = NULL;
     buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
-    fillYV12Buffer(img, yuvTexWidth, yuvTexHeight, buf->getStride());
+    fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
     buf->unlock();
     ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
 
@@ -523,11 +547,11 @@
 // I just copied them from the npot test above and haven't bothered to figure
 // out the correct values.
 TEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromCpuFilledYV12BufferPow2) {
-    const int yuvTexWidth = 64;
-    const int yuvTexHeight = 64;
+    const int texWidth = 64;
+    const int texHeight = 64;
 
     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
-            yuvTexWidth, yuvTexHeight, HAL_PIXEL_FORMAT_YV12));
+            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
 
@@ -541,7 +565,7 @@
     // Fill the buffer with the a checkerboard pattern
     uint8_t* img = NULL;
     buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
-    fillYV12Buffer(img, yuvTexWidth, yuvTexHeight, buf->getStride());
+    fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
     buf->unlock();
     ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
 
@@ -567,11 +591,11 @@
 }
 
 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) {
-    const int yuvTexWidth = 64;
-    const int yuvTexHeight = 66;
+    const int texWidth = 64;
+    const int texHeight = 66;
 
     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
-            yuvTexWidth, yuvTexHeight, HAL_PIXEL_FORMAT_YV12));
+            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
 
@@ -579,8 +603,8 @@
         {4, 6, 22, 36},
         {0, 6, 22, 36},
         {4, 0, 22, 36},
-        {4, 6, yuvTexWidth, 36},
-        {4, 6, 22, yuvTexHeight},
+        {4, 6, texWidth, 36},
+        {4, 6, 22, texHeight},
     };
 
     for (int i = 0; i < 5; i++) {
@@ -599,7 +623,7 @@
 
         uint8_t* img = NULL;
         buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
-        fillYV12BufferRect(img, yuvTexWidth, yuvTexHeight, buf->getStride(), crop);
+        fillYV12BufferRect(img, texWidth, texHeight, buf->getStride(), crop);
         buf->unlock();
         ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
 
@@ -625,6 +649,189 @@
     }
 }
 
+// XXX: This test is disabled because there are currently no drivers that can
+// handle RGBA textures with the GL_TEXTURE_EXTERNAL_OES target.
+TEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromCpuFilledRGBABufferNpot) {
+    const int texWidth = 64;
+    const int texHeight = 66;
+
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    android_native_buffer_t* anb;
+    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+    ASSERT_TRUE(anb != NULL);
+
+    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+    ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
+
+    // Fill the buffer with the a checkerboard pattern
+    uint8_t* img = NULL;
+    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
+    fillRGBA8Buffer(img, texWidth, texHeight, buf->getStride());
+    buf->unlock();
+    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
+
+    mST->updateTexImage();
+
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    drawTexture();
+
+    EXPECT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
+    EXPECT_TRUE(checkPixel(63,  0, 231, 231, 231, 231));
+    EXPECT_TRUE(checkPixel(63, 63, 231, 231, 231, 231));
+    EXPECT_TRUE(checkPixel( 0, 63,  35,  35,  35,  35));
+
+    EXPECT_TRUE(checkPixel(15, 10,  35, 231, 231, 231));
+    EXPECT_TRUE(checkPixel(24, 63,  35, 231, 231,  35));
+    EXPECT_TRUE(checkPixel(19, 40,  87, 179,  35,  35));
+    EXPECT_TRUE(checkPixel(38, 30, 231,  35,  35,  35));
+    EXPECT_TRUE(checkPixel(42, 54,  35,  35,  35, 231));
+    EXPECT_TRUE(checkPixel(37, 33,  35, 231, 231, 231));
+    EXPECT_TRUE(checkPixel(31,  8, 231,  35,  35, 231));
+    EXPECT_TRUE(checkPixel(36, 47, 231,  35, 231, 231));
+    EXPECT_TRUE(checkPixel(24, 63,  35, 231, 231,  35));
+    EXPECT_TRUE(checkPixel(48,  3, 231, 231,  35,  35));
+    EXPECT_TRUE(checkPixel(54, 50,  35, 231, 231, 231));
+    EXPECT_TRUE(checkPixel(24, 25, 191, 191, 231, 231));
+    EXPECT_TRUE(checkPixel(10,  9,  93,  93, 231, 231));
+    EXPECT_TRUE(checkPixel(29,  4,  35,  35,  35, 231));
+    EXPECT_TRUE(checkPixel(56, 31,  35, 231, 231,  35));
+    EXPECT_TRUE(checkPixel(58, 55,  35,  35, 231, 231));
+}
+
+// XXX: This test is disabled because there are currently no drivers that can
+// handle RGBA textures with the GL_TEXTURE_EXTERNAL_OES target.
+TEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromCpuFilledRGBABufferPow2) {
+    const int texWidth = 64;
+    const int texHeight = 64;
+
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    android_native_buffer_t* anb;
+    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+    ASSERT_TRUE(anb != NULL);
+
+    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+    ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
+
+    // Fill the buffer with the a checkerboard pattern
+    uint8_t* img = NULL;
+    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
+    fillRGBA8Buffer(img, texWidth, texHeight, buf->getStride());
+    buf->unlock();
+    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
+
+    mST->updateTexImage();
+
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    drawTexture();
+
+    EXPECT_TRUE(checkPixel( 0,  0, 231, 231, 231, 231));
+    EXPECT_TRUE(checkPixel(63,  0,  35,  35,  35,  35));
+    EXPECT_TRUE(checkPixel(63, 63, 231, 231, 231, 231));
+    EXPECT_TRUE(checkPixel( 0, 63,  35,  35,  35,  35));
+
+    EXPECT_TRUE(checkPixel(12, 46, 231, 231, 231,  35));
+    EXPECT_TRUE(checkPixel(16,  1, 231, 231,  35, 231));
+    EXPECT_TRUE(checkPixel(21, 12, 231,  35,  35, 231));
+    EXPECT_TRUE(checkPixel(26, 51, 231,  35, 231,  35));
+    EXPECT_TRUE(checkPixel( 5, 32,  35, 231, 231,  35));
+    EXPECT_TRUE(checkPixel(13,  8,  35, 231, 231, 231));
+    EXPECT_TRUE(checkPixel(46,  3,  35,  35, 231,  35));
+    EXPECT_TRUE(checkPixel(30, 33,  35,  35,  35,  35));
+    EXPECT_TRUE(checkPixel( 6, 52, 231, 231,  35,  35));
+    EXPECT_TRUE(checkPixel(55, 33,  35, 231,  35, 231));
+    EXPECT_TRUE(checkPixel(16, 29,  35,  35, 231, 231));
+    EXPECT_TRUE(checkPixel( 1, 30,  35,  35,  35, 231));
+    EXPECT_TRUE(checkPixel(41, 37,  35,  35, 231, 231));
+    EXPECT_TRUE(checkPixel(46, 29, 231, 231,  35,  35));
+    EXPECT_TRUE(checkPixel(15, 25,  35, 231,  35, 231));
+    EXPECT_TRUE(checkPixel( 3, 52,  35, 231,  35,  35));
+}
+
+// XXX: This test is disabled because there are currently no drivers that can
+// handle RGBA textures with the GL_TEXTURE_EXTERNAL_OES target.
+TEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromGLFilledRGBABufferPow2) {
+    const int texWidth = 64;
+    const int texHeight = 64;
+
+    mST->setDefaultBufferSize(texWidth, texHeight);
+
+    // Do the producer side of things
+    EGLSurface stcEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
+            mANW.get(), NULL);
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
+
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, stcEglSurface, stcEglSurface,
+            mEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    glClearColor(0.6, 0.6, 0.6, 0.6);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glEnable(GL_SCISSOR_TEST);
+    glScissor(4, 4, 4, 4);
+    glClearColor(1.0, 0.0, 0.0, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glScissor(24, 48, 4, 4);
+    glClearColor(0.0, 1.0, 0.0, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glScissor(37, 17, 4, 4);
+    glClearColor(0.0, 0.0, 1.0, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    eglSwapBuffers(mEglDisplay, stcEglSurface);
+
+    // Do the consumer side of things
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+            mEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    glDisable(GL_SCISSOR_TEST);
+
+    mST->updateTexImage();
+
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    drawTexture();
+
+    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
+
+    EXPECT_TRUE(checkPixel( 4,  7, 255,   0,   0, 255));
+    EXPECT_TRUE(checkPixel(25, 51,   0, 255,   0, 255));
+    EXPECT_TRUE(checkPixel(40, 19,   0,   0, 255, 255));
+    EXPECT_TRUE(checkPixel(29, 51, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 5, 32, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(13,  8, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(46,  3, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(30, 33, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 6, 52, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(55, 33, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(16, 29, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 1, 30, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(41, 37, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(46, 29, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(15, 25, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153));
+}
+
 /*
  * This test is for testing GL -> GL texture streaming via SurfaceTexture.  It
  * contains functionality to create a producer thread that will perform GL
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index c748228..15bb1d2 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -335,10 +335,17 @@
 
     pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
     if (gDoSchedulingGroup) {
+        // set_sched_policy does not support tid == 0
+        int policy_tid;
+        if (tid == 0) {
+            policy_tid = androidGetTid();
+        } else {
+            policy_tid = tid;
+        }
         if (pri >= ANDROID_PRIORITY_BACKGROUND) {
-            rc = set_sched_policy(tid, SP_BACKGROUND);
+            rc = set_sched_policy(policy_tid, SP_BACKGROUND);
         } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
-            rc = set_sched_policy(tid, SP_FOREGROUND);
+            rc = set_sched_policy(policy_tid, SP_FOREGROUND);
         }
     }