am b14f325a: am 289b9b62: Add ANativeWindow API for directly drawing to the surface bits.

Merge commit 'b14f325a0118ffce286155caaabaae149653462c'

* commit 'b14f325a0118ffce286155caaabaae149653462c':
  Add ANativeWindow API for directly drawing to the surface bits.
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 63934bb..329226e 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -336,6 +336,7 @@
                             ((RootViewSurfaceTaker)view).willYouTakeTheSurface();
                     if (mSurfaceHolderCallback != null) {
                         mSurfaceHolder = new TakenSurfaceHolder();
+                        mSurfaceHolder.setFormat(PixelFormat.UNKNOWN);
                     }
                 }
                 Resources resources = mView.getContext().getResources();
@@ -650,7 +651,7 @@
             // object is not initialized to its backing store, but soon it
             // will be (assuming the window is visible).
             attachInfo.mSurface = mSurface;
-            attachInfo.mTranslucentWindow = lp.format != PixelFormat.OPAQUE;
+            attachInfo.mTranslucentWindow = PixelFormat.formatHasAlpha(lp.format);
             attachInfo.mHasWindowFocus = false;
             attachInfo.mWindowVisibility = viewVisibility;
             attachInfo.mRecomputeGlobalAttributes = false;
@@ -816,8 +817,6 @@
             if (mSurfaceHolder != null) {
                 mSurfaceHolder.mSurfaceLock.lock();
                 mDrawingAllowed = true;
-                lp.format = mSurfaceHolder.getRequestedFormat();
-                lp.type = mSurfaceHolder.getRequestedType();
             }
 
             boolean hwIntialized = false;
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index af61b80..54a9c2a 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -21,7 +21,8 @@
 #include <dlfcn.h>
 
 #include <android_runtime/AndroidRuntime.h>
-#include <android/native_activity.h>
+#include <android_runtime/android_view_Surface.h>
+#include <android_runtime/android_app_NativeActivity.h>
 #include <surfaceflinger/Surface.h>
 #include <ui/egl/android_natives.h>
 #include <ui/InputTransport.h>
@@ -31,7 +32,6 @@
 #include "android_os_MessageQueue.h"
 #include "android_view_InputChannel.h"
 #include "android_view_KeyEvent.h"
-#include "android_view_Surface.h"
 
 namespace android
 {
@@ -46,6 +46,48 @@
 
 // ------------------------------------------------------------------------
 
+struct ActivityWork {
+    int32_t cmd;
+    int32_t arg1;
+    int32_t arg2;
+};
+
+enum {
+    CMD_DEF_KEY = 1,
+    CMD_SET_WINDOW_FORMAT,
+    CMD_SET_WINDOW_FLAGS,
+};
+
+static void write_work(int fd, int32_t cmd, int32_t arg1=0, int32_t arg2=0) {
+    ActivityWork work;
+    work.cmd = cmd;
+    work.arg1 = arg1;
+    work.arg2 = arg2;
+    
+restart:
+    int res = write(fd, &work, sizeof(work));
+    if (res < 0 && errno == EINTR) {
+        goto restart;
+    }
+    
+    if (res == sizeof(work)) return;
+    
+    if (res < 0) LOGW("Failed writing to work fd: %s", strerror(errno));
+    else LOGW("Truncated writing to work fd: %d", res);
+}
+
+static bool read_work(int fd, ActivityWork* outWork) {
+    int res = read(fd, outWork, sizeof(ActivityWork));
+    // no need to worry about EINTR, poll loop will just come back again.
+    if (res == sizeof(ActivityWork)) return true;
+    
+    if (res < 0) LOGW("Failed reading work fd: %s", strerror(errno));
+    else LOGW("Truncated reading work fd: %d", res);
+    return false;
+}
+
+// ------------------------------------------------------------------------
+
 /*
  * Specialized input queue that allows unhandled key events to be dispatched
  * back to the native activity's Java framework code.
@@ -59,8 +101,7 @@
         mLock.lock();
         LOGI("Default key: pending=%d write=%d\n", mPendingKeys.size(), mWorkWrite);
         if (mPendingKeys.size() <= 0 && mWorkWrite >= 0) {
-            int8_t cmd = 1;
-            write(mWorkWrite, &cmd, sizeof(cmd));
+            write_work(mWorkWrite, CMD_DEF_KEY);
         }
         mPendingKeys.add(keyEvent);
         mLock.unlock();
@@ -90,9 +131,9 @@
 /*
  * Native state for interacting with the NativeActivity class.
  */
-struct NativeCode {
+struct NativeCode : public ANativeActivity {
     NativeCode(void* _dlhandle, ANativeActivity_createFunc* _createFunc) {
-        memset(&activity, sizeof(activity), 0);
+        memset((ANativeActivity*)this, sizeof(ANativeActivity), 0);
         memset(&callbacks, sizeof(callbacks), 0);
         dlhandle = _dlhandle;
         createActivityFunc = _createFunc;
@@ -103,8 +144,11 @@
     }
     
     ~NativeCode() {
-        if (activity.env != NULL && activity.clazz != NULL) {
-            activity.env->DeleteGlobalRef(activity.clazz);
+        if (callbacks.onDestroy != NULL) {
+            callbacks.onDestroy(this);
+        }
+        if (env != NULL && clazz != NULL) {
+            env->DeleteGlobalRef(clazz);
         }
         if (pollLoop != NULL && mainWorkRead >= 0) {
             pollLoop->removeCallback(mainWorkRead);
@@ -114,9 +158,6 @@
         }
         setSurface(NULL);
         setInputChannel(NULL);
-        if (callbacks.onDestroy != NULL) {
-            callbacks.onDestroy(&activity);
-        }
         if (mainWorkRead >= 0) close(mainWorkRead);
         if (mainWorkWrite >= 0) close(mainWorkWrite);
         if (dlhandle != NULL) {
@@ -129,7 +170,7 @@
     
     void setSurface(jobject _surface) {
         if (_surface != NULL) {
-            nativeWindow = android_Surface_getNativeWindow(activity.env, _surface);
+            nativeWindow = android_Surface_getNativeWindow(env, _surface);
         } else {
             nativeWindow = NULL;
         }
@@ -138,14 +179,14 @@
     status_t setInputChannel(jobject _channel) {
         if (inputChannel != NULL) {
             delete nativeInputQueue;
-            activity.env->DeleteGlobalRef(inputChannel);
+            env->DeleteGlobalRef(inputChannel);
         }
         inputChannel = NULL;
         nativeInputQueue = NULL;
         if (_channel != NULL) {
-            inputChannel = activity.env->NewGlobalRef(_channel);
+            inputChannel = env->NewGlobalRef(_channel);
             sp<InputChannel> ic =
-                    android_view_InputChannel_getInputChannel(activity.env, _channel);
+                    android_view_InputChannel_getInputChannel(env, _channel);
             if (ic != NULL) {
                 nativeInputQueue = new MyInputQueue(ic, mainWorkWrite);
                 if (nativeInputQueue->getConsumer().initialize() != android::OK) {
@@ -160,7 +201,6 @@
         return OK;
     }
     
-    ANativeActivity activity;
     ANativeActivityCallbacks callbacks;
     
     void* dlhandle;
@@ -179,6 +219,18 @@
     sp<PollLoop> pollLoop;
 };
 
+void android_NativeActivity_setWindowFormat(
+        ANativeActivity* activity, int32_t format) {
+    NativeCode* code = static_cast<NativeCode*>(activity);
+    write_work(code->mainWorkWrite, CMD_SET_WINDOW_FORMAT, format);
+}
+
+void android_NativeActivity_setWindowFlags(
+        ANativeActivity* activity, int32_t values, int32_t mask) {
+    NativeCode* code = static_cast<NativeCode*>(activity);
+    write_work(code->mainWorkWrite, CMD_SET_WINDOW_FLAGS, values, mask);
+}
+
 // ------------------------------------------------------------------------
 
 /*
@@ -186,19 +238,40 @@
  */
 static bool mainWorkCallback(int fd, int events, void* data) {
     NativeCode* code = (NativeCode*)data;
-    if ((events & POLLIN) != 0) {
-        KeyEvent* keyEvent;
-        while ((keyEvent=code->nativeInputQueue->getNextEvent()) != NULL) {
-            jobject inputEventObj = android_view_KeyEvent_fromNative(
-                    code->activity.env, keyEvent);
-            code->activity.env->CallVoidMethod(code->activity.clazz,
-                    gNativeActivityClassInfo.dispatchUnhandledKeyEvent, inputEventObj);
-            int32_t res = code->nativeInputQueue->getConsumer().sendFinishedSignal();
-            if (res != OK) {
-                LOGW("Failed to send finished signal on channel '%s'.  status=%d",
-                        code->nativeInputQueue->getConsumer().getChannel()->getName().string(), res);
+    if ((events & POLLIN) == 0) {
+        return true;
+    }
+    
+    ActivityWork work;
+    if (!read_work(code->mainWorkRead, &work)) {
+        return true;
+    }
+    switch (work.cmd) {
+        case CMD_DEF_KEY: {
+            KeyEvent* keyEvent;
+            while ((keyEvent=code->nativeInputQueue->getNextEvent()) != NULL) {
+                jobject inputEventObj = android_view_KeyEvent_fromNative(
+                        code->env, keyEvent);
+                code->env->CallVoidMethod(code->clazz,
+                        gNativeActivityClassInfo.dispatchUnhandledKeyEvent, inputEventObj);
+                int32_t res = code->nativeInputQueue->getConsumer().sendFinishedSignal();
+                if (res != OK) {
+                    LOGW("Failed to send finished signal on channel '%s'.  status=%d",
+                            code->nativeInputQueue->getConsumer().getChannel()->getName().string(), res);
+                }
             }
-        }
+        } break;
+        case CMD_SET_WINDOW_FORMAT: {
+            code->env->CallVoidMethod(code->clazz,
+                    gNativeActivityClassInfo.setWindowFormat, work.arg1);
+        } break;
+        case CMD_SET_WINDOW_FLAGS: {
+            code->env->CallVoidMethod(code->clazz,
+                    gNativeActivityClassInfo.setWindowFlags, work.arg1, work.arg2);
+        } break;
+        default:
+            LOGW("Unknown work command: %d", work.cmd);
+            break;
     }
     
     return true;
@@ -243,28 +316,28 @@
         code->mainWorkWrite = msgpipe[1];
         code->pollLoop->setCallback(code->mainWorkRead, POLLIN, mainWorkCallback, code);
         
-        code->activity.callbacks = &code->callbacks;
-        if (env->GetJavaVM(&code->activity.vm) < 0) {
+        code->ANativeActivity::callbacks = &code->callbacks;
+        if (env->GetJavaVM(&code->vm) < 0) {
             LOGW("NativeActivity GetJavaVM failed");
             delete code;
             return 0;
         }
-        code->activity.env = env;
-        code->activity.clazz = env->NewGlobalRef(clazz);
+        code->env = env;
+        code->clazz = env->NewGlobalRef(clazz);
         
         const char* dirStr = env->GetStringUTFChars(internalDataDir, NULL);
         code->internalDataPath = dirStr;
-        code->activity.internalDataPath = code->internalDataPath.string();
+        code->internalDataPath = code->internalDataPath.string();
         env->ReleaseStringUTFChars(path, dirStr);
     
         dirStr = env->GetStringUTFChars(externalDataDir, NULL);
         code->externalDataPath = dirStr;
-        code->activity.externalDataPath = code->externalDataPath.string();
+        code->externalDataPath = code->externalDataPath.string();
         env->ReleaseStringUTFChars(path, dirStr);
     
-        code->activity.sdkVersion = sdkVersion;
+        code->sdkVersion = sdkVersion;
         
-        code->createActivityFunc(&code->activity, NULL, 0);
+        code->createActivityFunc(code, NULL, 0);
     }
     
     return (jint)code;
@@ -285,7 +358,7 @@
     if (handle != 0) {
         NativeCode* code = (NativeCode*)handle;
         if (code->callbacks.onStart != NULL) {
-            code->callbacks.onStart(&code->activity);
+            code->callbacks.onStart(code);
         }
     }
 }
@@ -296,7 +369,7 @@
     if (handle != 0) {
         NativeCode* code = (NativeCode*)handle;
         if (code->callbacks.onResume != NULL) {
-            code->callbacks.onResume(&code->activity);
+            code->callbacks.onResume(code);
         }
     }
 }
@@ -308,7 +381,7 @@
         NativeCode* code = (NativeCode*)handle;
         if (code->callbacks.onSaveInstanceState != NULL) {
             size_t len = 0;
-            code->callbacks.onSaveInstanceState(&code->activity, &len);
+            code->callbacks.onSaveInstanceState(code, &len);
         }
     }
 }
@@ -319,7 +392,7 @@
     if (handle != 0) {
         NativeCode* code = (NativeCode*)handle;
         if (code->callbacks.onPause != NULL) {
-            code->callbacks.onPause(&code->activity);
+            code->callbacks.onPause(code);
         }
     }
 }
@@ -330,7 +403,7 @@
     if (handle != 0) {
         NativeCode* code = (NativeCode*)handle;
         if (code->callbacks.onStop != NULL) {
-            code->callbacks.onStop(&code->activity);
+            code->callbacks.onStop(code);
         }
     }
 }
@@ -341,7 +414,7 @@
     if (handle != 0) {
         NativeCode* code = (NativeCode*)handle;
         if (code->callbacks.onLowMemory != NULL) {
-            code->callbacks.onLowMemory(&code->activity);
+            code->callbacks.onLowMemory(code);
         }
     }
 }
@@ -352,7 +425,7 @@
     if (handle != 0) {
         NativeCode* code = (NativeCode*)handle;
         if (code->callbacks.onWindowFocusChanged != NULL) {
-            code->callbacks.onWindowFocusChanged(&code->activity, focused ? 1 : 0);
+            code->callbacks.onWindowFocusChanged(code, focused ? 1 : 0);
         }
     }
 }
@@ -364,7 +437,7 @@
         NativeCode* code = (NativeCode*)handle;
         code->setSurface(surface);
         if (code->nativeWindow != NULL && code->callbacks.onNativeWindowCreated != NULL) {
-            code->callbacks.onNativeWindowCreated(&code->activity,
+            code->callbacks.onNativeWindowCreated(code,
                     code->nativeWindow.get());
         }
     }
@@ -380,11 +453,11 @@
         code->setSurface(surface);
         if (oldNativeWindow != code->nativeWindow) {
             if (oldNativeWindow != NULL && code->callbacks.onNativeWindowDestroyed != NULL) {
-                code->callbacks.onNativeWindowDestroyed(&code->activity,
+                code->callbacks.onNativeWindowDestroyed(code,
                         oldNativeWindow.get());
             }
             if (code->nativeWindow != NULL && code->callbacks.onNativeWindowCreated != NULL) {
-                code->callbacks.onNativeWindowCreated(&code->activity,
+                code->callbacks.onNativeWindowCreated(code,
                         code->nativeWindow.get());
             }
         }
@@ -397,7 +470,7 @@
     if (handle != 0) {
         NativeCode* code = (NativeCode*)handle;
         if (code->nativeWindow != NULL && code->callbacks.onNativeWindowDestroyed != NULL) {
-            code->callbacks.onNativeWindowDestroyed(&code->activity,
+            code->callbacks.onNativeWindowDestroyed(code,
                     code->nativeWindow.get());
         }
         code->setSurface(NULL);
@@ -416,7 +489,7 @@
             return;
         }
         if (code->callbacks.onInputQueueCreated != NULL) {
-            code->callbacks.onInputQueueCreated(&code->activity,
+            code->callbacks.onInputQueueCreated(code,
                     code->nativeInputQueue);
         }
     }
@@ -429,7 +502,7 @@
         NativeCode* code = (NativeCode*)handle;
         if (code->nativeInputQueue != NULL
                 && code->callbacks.onInputQueueDestroyed != NULL) {
-            code->callbacks.onInputQueueDestroyed(&code->activity,
+            code->callbacks.onInputQueueDestroyed(code,
                     code->nativeInputQueue);
         }
         code->setInputChannel(NULL);
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index a82abc93..7305032 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -33,7 +33,7 @@
 
 #include "jni.h"
 #include <android_runtime/AndroidRuntime.h>
-#include "android_view_Surface.h"
+#include <android_runtime/android_view_Surface.h>
 #include <utils/misc.h>
 
 
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index 866c038..941ed63 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -16,6 +16,7 @@
 */
 
 #include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/android_view_Surface.h>
 #include <utils/misc.h>
 
 #include <EGL/egl.h>
@@ -25,8 +26,6 @@
 #include <SkBitmap.h>
 #include <SkPixelRef.h>
 
-#include "android_view_Surface.h"
-
 namespace android {
 
 static jclass gDisplay_class;
diff --git a/include/android_runtime/android_app_NativeActivity.h b/include/android_runtime/android_app_NativeActivity.h
new file mode 100644
index 0000000..f808328
--- /dev/null
+++ b/include/android_runtime/android_app_NativeActivity.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+#ifndef _ANDROID_APP_NATIVEACTIVITY_H
+#define _ANDROID_APP_NATIVEACTIVITY_H
+
+#include <android/native_activity.h>
+
+#include "jni.h"
+
+namespace android {
+
+extern void android_NativeActivity_setWindowFormat(
+        ANativeActivity* activity, int32_t format);
+
+extern void android_NativeActivity_setWindowFlags(
+        ANativeActivity* activity, int32_t values, int32_t mask);
+
+
+} // namespace android
+
+#endif // _ANDROID_APP_NATIVEACTIVITY_H
diff --git a/core/jni/android_view_Surface.h b/include/android_runtime/android_view_Surface.h
similarity index 100%
rename from core/jni/android_view_Surface.h
rename to include/android_runtime/android_view_Surface.h
diff --git a/include/ui/Rect.h b/include/ui/Rect.h
index a213c09..4e65a2d 100644
--- a/include/ui/Rect.h
+++ b/include/ui/Rect.h
@@ -20,31 +20,28 @@
 #include <utils/TypeHelpers.h>
 #include <ui/Point.h>
 
+#include <android/rect.h>
+
 namespace android {
 
-class Rect
+class Rect : public ARect
 {
 public:
-    int left;
-    int top;
-    int right;
-    int bottom;
-
-    typedef int value_type;
+    typedef int32_t value_type;
 
     // we don't provide copy-ctor and operator= on purpose
     // because we want the compiler generated versions
 
     inline Rect() {
     }
-    inline Rect(int w, int h)
-        : left(0), top(0), right(w), bottom(h) {
+    inline Rect(int32_t w, int32_t h) {
+        left = top = 0; right = w; bottom = h;
     }
-    inline Rect(int l, int t, int r, int b)
-        : left(l), top(t), right(r), bottom(b) {
+    inline Rect(int32_t l, int32_t t, int32_t r, int32_t b) {
+        left = l; top = t; right = r; bottom = b;
     }
-    inline Rect(const Point& lt, const Point& rb) 
-        : left(lt.x), top(lt.y), right(rb.x), bottom(rb.y) {
+    inline Rect(const Point& lt, const Point& rb) {
+        left = lt.x; top = lt.y; right = rb.x; bottom = rb.y;
     }
 
     void makeInvalid();
@@ -68,12 +65,12 @@
     }
 
     // rectangle's width
-    inline int width() const {
+    inline int32_t width() const {
         return right-left;
     }
     
     // rectangle's height
-    inline int height() const {
+    inline int32_t height() const {
         return bottom-top;
     }
 
@@ -136,12 +133,12 @@
     const Rect operator + (const Point& rhs) const;
     const Rect operator - (const Point& rhs) const;
 
-    void translate(int dx, int dy) { // legacy, don't use.
+    void translate(int32_t dx, int32_t dy) { // legacy, don't use.
         offsetBy(dx, dy);
     }
  
-    Rect&   offsetTo(int x, int y);
-    Rect&   offsetBy(int x, int y);
+    Rect&   offsetTo(int32_t x, int32_t y);
+    Rect&   offsetBy(int32_t x, int32_t y);
     bool    intersect(const Rect& with, Rect* result) const;
 };
 
diff --git a/libs/ui/Rect.cpp b/libs/ui/Rect.cpp
index 66b9576..5694e00 100644
--- a/libs/ui/Rect.cpp
+++ b/libs/ui/Rect.cpp
@@ -18,11 +18,11 @@
 
 namespace android {
 
-static inline int min(int a, int b) {
+static inline int32_t min(int32_t a, int32_t b) {
     return (a<b) ? a : b;
 }
 
-static inline int max(int a, int b) {
+static inline int32_t max(int32_t a, int32_t b) {
     return (a>b) ? a : b;
 }
 
@@ -53,7 +53,7 @@
     return false;
 }
 
-Rect& Rect::offsetTo(int x, int y)
+Rect& Rect::offsetTo(int32_t x, int32_t y)
 {
     right -= left - x;
     bottom -= top - y;
@@ -62,7 +62,7 @@
     return *this;
 }
 
-Rect& Rect::offsetBy(int x, int y)
+Rect& Rect::offsetBy(int32_t x, int32_t y)
 {
     left += x;
     top  += y;
diff --git a/native/android/Android.mk b/native/android/Android.mk
index 376c64f..509a379 100644
--- a/native/android/Android.mk
+++ b/native/android/Android.mk
@@ -6,17 +6,18 @@
 # our source files
 #
 LOCAL_SRC_FILES:= \
-    activity.cpp \
     input.cpp \
     looper.cpp \
+    native_activity.cpp \
     native_window.cpp
 
 LOCAL_SHARED_LIBRARIES := \
-    libandroid_runtime \
     libcutils \
     libutils \
     libbinder \
-    libui
+    libui \
+    libsurfaceflinger_client \
+    libandroid_runtime
 
 LOCAL_C_INCLUDES += \
     frameworks/base/native/include \
diff --git a/native/android/activity.cpp b/native/android/activity.cpp
deleted file mode 100644
index e69de29..0000000
--- a/native/android/activity.cpp
+++ /dev/null
diff --git a/native/android/native_activity.cpp b/native/android/native_activity.cpp
new file mode 100644
index 0000000..509cc33
--- /dev/null
+++ b/native/android/native_activity.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "native_activity"
+#include <utils/Log.h>
+
+#include <android_runtime/android_app_NativeActivity.h>
+
+using namespace android;
+
+void ANativeActivity_setWindowFormat(ANativeActivity* activity, int32_t format) {
+	android_NativeActivity_setWindowFormat(activity, format);
+}
+
+void ANativeActivity_setWindowFlags(ANativeActivity* activity,
+		uint32_t addFlags, uint32_t removeFlags) {
+	android_NativeActivity_setWindowFlags(activity, addFlags, addFlags|removeFlags);
+}
diff --git a/native/android/native_window.cpp b/native/android/native_window.cpp
index 448cbfc..bada078 100644
--- a/native/android/native_window.cpp
+++ b/native/android/native_window.cpp
@@ -17,10 +17,27 @@
 #define LOG_TAG "Surface"
 #include <utils/Log.h>
 
-#include <android/native_window.h>
+#include <android/native_window_jni.h>
 #include <surfaceflinger/Surface.h>
+#include <android_runtime/android_view_Surface.h>
 
-using android::Surface;
+using namespace android;
+
+ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface) {
+    sp<ANativeWindow> win = android_Surface_getNativeWindow(env, surface);
+    if (win != NULL) {
+        win->incStrong((void*)ANativeWindow_acquire);
+    }
+    return win.get();
+}
+
+void ANativeWindow_acquire(ANativeWindow* window) {
+    window->incStrong((void*)ANativeWindow_acquire);
+}
+
+void ANativeWindow_release(ANativeWindow* window) {
+    window->decStrong((void*)ANativeWindow_acquire);
+}
 
 static int32_t getWindowProp(ANativeWindow* window, int what) {
     int value;
@@ -41,7 +58,40 @@
 }
 
 int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window, int32_t width,
-        int32_t height, int32_t format) {
-    native_window_set_buffers_geometry(window, width, height, format);
+        int32_t height) {
+    native_window_set_buffers_geometry(window, width, height, 0);
     return 0;
 }
+
+int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer,
+        ARect* inOutDirtyBounds) {
+    Region dirtyRegion;
+    Region* dirtyParam = NULL;
+    if (inOutDirtyBounds != NULL) {
+        dirtyRegion.set(*(Rect*)inOutDirtyBounds);
+        dirtyParam = &dirtyRegion;
+    }
+    
+    Surface::SurfaceInfo info;
+    status_t res = static_cast<Surface*>(window)->lock(&info, dirtyParam);
+    if (res != OK) {
+        return -1;
+    }
+    
+    outBuffer->width = (int32_t)info.w;
+    outBuffer->height = (int32_t)info.h;
+    outBuffer->stride = (int32_t)info.s;
+    outBuffer->format = (int32_t)info.format;
+    outBuffer->bits = info.bits;
+    
+    if (inOutDirtyBounds != NULL) {
+        *inOutDirtyBounds = dirtyRegion.getBounds();
+    }
+    
+    return 0;
+}
+
+int32_t ANativeWindow_unlockAndPost(ANativeWindow* window) {
+    status_t res = static_cast<Surface*>(window)->unlockAndPost();
+    return res == android::OK ? 0 : -1;
+}
diff --git a/native/glue/threaded_app/threaded_app.c b/native/glue/threaded_app/threaded_app.c
index c9cae8b..16c905c 100644
--- a/native/glue/threaded_app/threaded_app.c
+++ b/native/glue/threaded_app/threaded_app.c
@@ -51,7 +51,7 @@
     return -1;
 }
 
-void android_app_exec_cmd(struct android_app* android_app, int8_t cmd) {
+int32_t android_app_exec_cmd(struct android_app* android_app, int8_t cmd) {
     switch (cmd) {
         case APP_CMD_INPUT_CHANGED:
             LOGI("APP_CMD_INPUT_CHANGED\n");
@@ -93,6 +93,8 @@
             android_app->destroyRequested = 1;
             break;
     }
+    
+    return android_app->destroyRequested ? 0 : 1;
 }
 
 static void* android_app_entry(void* param) {
diff --git a/native/include/android/native_activity.h b/native/include/android/native_activity.h
index a31c5af..d0ff052 100644
--- a/native/include/android/native_activity.h
+++ b/native/include/android/native_activity.h
@@ -192,6 +192,11 @@
  */
 extern ANativeActivity_createFunc ANativeActivity_onCreate;
 
+void ANativeActivity_setWindowFormat(ANativeActivity* activity, int32_t format);
+
+void ANativeActivity_setWindowFlags(ANativeActivity* activity,
+        uint32_t addFlags, uint32_t removeFlags);
+
 #ifdef __cplusplus
 };
 #endif
diff --git a/native/include/android/native_window.h b/native/include/android/native_window.h
index 678ba3d..7599d7e 100644
--- a/native/include/android/native_window.h
+++ b/native/include/android/native_window.h
@@ -14,10 +14,11 @@
  * limitations under the License.
  */
 
-
 #ifndef ANDROID_NATIVE_WINDOW_H
 #define ANDROID_NATIVE_WINDOW_H
 
+#include <android/rect.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -34,6 +35,27 @@
 struct ANativeWindow;
 typedef struct ANativeWindow ANativeWindow;
 
+typedef struct ANativeWindow_Buffer {
+    int32_t width;
+    int32_t height;
+    int32_t stride;
+    int32_t format;
+    void* bits;
+    
+    uint32_t reserved[6];
+} ANativeWindow_Buffer;
+
+/**
+ * Acquire a reference on the given ANativeWindow object.  This prevents the object
+ * from being deleted until the reference is removed.
+ */
+void ANativeWindow_acquire(ANativeWindow* window);
+
+/**
+ * Remove a reference that was previously acquired with ANativeWindow_acquire().
+ */
+void ANativeWindow_release(ANativeWindow* window);
+
 /*
  * Return the current width in pixels of the window surface.  Returns a
  * negative value on error.
@@ -60,13 +82,22 @@
  * window's physical size, then it buffer will be scaled to match that size
  * when compositing it to the screen.
  *
- * The format may be one of the window format constants above.
- *
- * For all of these parameters, if 0 is supplied than the window's base
+ * For all of these parameters, if 0 is supplied then the window's base
  * value will come back in force.
  */
-int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window, int32_t width,
-        int32_t height, int32_t format);
+int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window, int32_t width, int32_t height);
+
+/**
+ * Lock the window's next drawing surface for writing.
+ */
+int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer,
+        ARect* inOutDirtyBounds);
+
+/**
+ * Unlock the window's drawing surface after previously locking it,
+ * posting the new buffer to the display.
+ */
+int32_t ANativeWindow_unlockAndPost(ANativeWindow* window);
 
 #ifdef __cplusplus
 };
diff --git a/native/include/android/native_window_jni.h b/native/include/android/native_window_jni.h
new file mode 100644
index 0000000..b9e72ef
--- /dev/null
+++ b/native/include/android/native_window_jni.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_NATIVE_WINDOW_JNI_H
+#define ANDROID_NATIVE_WINDOW_JNI_H
+
+#include <android/native_window.h>
+
+#include <jni.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Return the ANativeWindow associated with a Java Surface object,
+ * for interacting with it through native code.  This acquires a reference
+ * on the ANativeWindow that is returned; be sure to use ANativeWindow_release()
+ * when done with it so that it doesn't leak.
+ */
+ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // ANDROID_NATIVE_WINDOW_H
diff --git a/native/include/android/rect.h b/native/include/android/rect.h
new file mode 100644
index 0000000..3e81f53
--- /dev/null
+++ b/native/include/android/rect.h
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+
+#ifndef ANDROID_RECT_H
+#define ANDROID_RECT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct ARect {
+    int32_t left;
+    int32_t top;
+    int32_t right;
+    int32_t bottom;
+} ARect;
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // ANDROID_RECT_H
diff --git a/native/include/android/window.h b/native/include/android/window.h
new file mode 100644
index 0000000..2ab192b
--- /dev/null
+++ b/native/include/android/window.h
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+
+#ifndef ANDROID_WINDOW_H
+#define ANDROID_WINDOW_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Window flags, as per the Java API at android.view.WindowManager.LayoutParams.
+ */
+enum {
+    AWINDOW_FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001,
+    AWINDOW_FLAG_DIM_BEHIND                 = 0x00000002,
+    AWINDOW_FLAG_BLUR_BEHIND                = 0x00000004,
+    AWINDOW_FLAG_NOT_FOCUSABLE              = 0x00000008,
+    AWINDOW_FLAG_NOT_TOUCHABLE              = 0x00000010,
+    AWINDOW_FLAG_NOT_TOUCH_MODAL            = 0x00000020,
+    AWINDOW_FLAG_TOUCHABLE_WHEN_WAKING      = 0x00000040,
+    AWINDOW_FLAG_KEEP_SCREEN_ON             = 0x00000080,
+    AWINDOW_FLAG_LAYOUT_IN_SCREEN           = 0x00000100,
+    AWINDOW_FLAG_LAYOUT_NO_LIMITS           = 0x00000200,
+    AWINDOW_FLAG_FULLSCREEN                 = 0x00000400,
+    AWINDOW_FLAG_FORCE_NOT_FULLSCREEN       = 0x00000800,
+    AWINDOW_FLAG_DITHER                     = 0x00001000,
+    AWINDOW_FLAG_SECURE                     = 0x00002000,
+    AWINDOW_FLAG_SCALED                     = 0x00004000,
+    AWINDOW_FLAG_IGNORE_CHEEK_PRESSES       = 0x00008000,
+    AWINDOW_FLAG_LAYOUT_INSET_DECOR         = 0x00010000,
+    AWINDOW_FLAG_ALT_FOCUSABLE_IM           = 0x00020000,
+    AWINDOW_FLAG_WATCH_OUTSIDE_TOUCH        = 0x00040000,
+    AWINDOW_FLAG_SHOW_WHEN_LOCKED           = 0x00080000,
+    AWINDOW_FLAG_SHOW_WALLPAPER             = 0x00100000,
+    AWINDOW_FLAG_TURN_SCREEN_ON             = 0x00200000,
+    AWINDOW_FLAG_DISMISS_KEYGUARD           = 0x00400000,
+};
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // ANDROID_WINDOW_H
diff --git a/native/include/android_glue/threaded_app.h b/native/include/android_glue/threaded_app.h
index 80de3bf..491389b 100644
--- a/native/include/android_glue/threaded_app.h
+++ b/native/include/android_glue/threaded_app.h
@@ -52,10 +52,6 @@
     // APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below.
     int activityState;
 
-    // This is non-zero when the application's NativeActivity is being
-    // destroyed and waiting for the app thread to complete.
-    int destroyRequested;
-
     // -------------------------------------------------
     // Below are "private" implementation of the glue code.
 
@@ -67,6 +63,10 @@
 
     pthread_t thread;
 
+    // This is non-zero when the application's NativeActivity is being
+    // destroyed and waiting for the app thread to complete.
+    int destroyRequested;
+
     int running;
     int destroyed;
     AInputQueue* pendingInputQueue;
@@ -158,8 +158,11 @@
 /**
  * Call with the command returned by android_app_read_cmd() to do the
  * default processing of the given command.
+ *
+ * Important: returns 0 if the app should exit.  You must ALWAYS check for
+ * a zero return and, if found, exit your android_main() function.
  */
-void android_app_exec_cmd(struct android_app* android_app, int8_t cmd);
+int32_t android_app_exec_cmd(struct android_app* android_app, int8_t cmd);
 
 /**
  * This is the function that application code must implement, representing