diff options
author | Dianne Hackborn <hackbod@google.com> | 2010-07-09 11:44:11 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2010-07-09 16:58:19 -0700 |
commit | 289b9b62372ef52a06113b83dfb870e2c2fb325a (patch) | |
tree | e444446a331fdbe9b936a0c2570a609675468d05 | |
parent | 2aaa9e9fc5ddc05cedbe530c7a41eca0e3a62b7a (diff) | |
download | frameworks_base-289b9b62372ef52a06113b83dfb870e2c2fb325a.zip frameworks_base-289b9b62372ef52a06113b83dfb870e2c2fb325a.tar.gz frameworks_base-289b9b62372ef52a06113b83dfb870e2c2fb325a.tar.bz2 |
Add ANativeWindow API for directly drawing to the surface bits.
Also other cleanup and fixes:
- We now properly set the default window format to 565.
- New APIs to set the window format and flags from native code.
- Tweaked glue for simpler handling of the "destroy" message.
- Um, other stuff.
Change-Id: Id7790a21a2fa9a19b91854d225324a7c1e7c6ade
-rw-r--r-- | core/java/android/view/ViewRoot.java | 5 | ||||
-rw-r--r-- | core/jni/android_app_NativeActivity.cpp | 171 | ||||
-rw-r--r-- | core/jni/android_view_Surface.cpp | 2 | ||||
-rw-r--r-- | core/jni/com_google_android_gles_jni_EGLImpl.cpp | 3 | ||||
-rw-r--r-- | include/android_runtime/android_app_NativeActivity.h | 35 | ||||
-rw-r--r-- | include/android_runtime/android_view_Surface.h (renamed from core/jni/android_view_Surface.h) | 0 | ||||
-rw-r--r-- | include/ui/Rect.h | 33 | ||||
-rw-r--r-- | libs/ui/Rect.cpp | 8 | ||||
-rw-r--r-- | native/android/Android.mk | 7 | ||||
-rw-r--r-- | native/android/activity.cpp | 0 | ||||
-rw-r--r-- | native/android/native_activity.cpp | 31 | ||||
-rw-r--r-- | native/android/native_window.cpp | 58 | ||||
-rw-r--r-- | native/glue/threaded_app/threaded_app.c | 4 | ||||
-rw-r--r-- | native/include/android/native_activity.h | 5 | ||||
-rw-r--r-- | native/include/android/native_window.h | 43 | ||||
-rw-r--r-- | native/include/android/native_window_jni.h | 40 | ||||
-rw-r--r-- | native/include/android/rect.h | 36 | ||||
-rw-r--r-- | native/include/android/window.h | 58 | ||||
-rw-r--r-- | native/include/android_glue/threaded_app.h | 13 |
19 files changed, 456 insertions, 96 deletions
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index e980b17..fb45971 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -452,6 +452,7 @@ public final class ViewRoot extends Handler implements ViewParent, ((RootViewSurfaceTaker)view).willYouTakeTheSurface(); if (mSurfaceHolderCallback != null) { mSurfaceHolder = new TakenSurfaceHolder(); + mSurfaceHolder.setFormat(PixelFormat.UNKNOWN); } } Resources resources = mView.getContext().getResources(); @@ -754,7 +755,7 @@ public final class ViewRoot extends Handler implements ViewParent, // 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; @@ -926,8 +927,6 @@ public final class ViewRoot extends Handler implements ViewParent, if (mSurfaceHolder != null) { mSurfaceHolder.mSurfaceLock.lock(); mDrawingAllowed = true; - lp.format = mSurfaceHolder.getRequestedFormat(); - lp.type = mSurfaceHolder.getRequestedType(); } boolean initialized = 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 @@ static struct { // ------------------------------------------------------------------------ +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 @@ struct MyInputQueue : AInputQueue { 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 @@ struct MyInputQueue : AInputQueue { /* * 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 @@ struct NativeCode { } ~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 @@ struct NativeCode { } 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 @@ struct NativeCode { 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 @@ struct NativeCode { 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 @@ struct NativeCode { return OK; } - ANativeActivity activity; ANativeActivityCallbacks callbacks; void* dlhandle; @@ -179,6 +219,18 @@ struct NativeCode { 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 @@ struct NativeCode { */ 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 @@ loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jobject messageQ 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 @@ onStart_native(JNIEnv* env, jobject clazz, jint handle) 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 @@ onResume_native(JNIEnv* env, jobject clazz, jint handle) 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 @@ onSaveInstanceState_native(JNIEnv* env, jobject clazz, jint handle) 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 @@ onPause_native(JNIEnv* env, jobject clazz, jint handle) 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 @@ onStop_native(JNIEnv* env, jobject clazz, jint handle) 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 @@ onLowMemory_native(JNIEnv* env, jobject clazz, jint handle) 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 @@ onWindowFocusChanged_native(JNIEnv* env, jobject clazz, jint handle, jboolean fo 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 @@ onSurfaceCreated_native(JNIEnv* env, jobject clazz, jint handle, jobject surface 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 @@ onSurfaceChanged_native(JNIEnv* env, jobject clazz, jint handle, jobject surface 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 @@ onSurfaceDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject surfa 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 @@ onInputChannelCreated_native(JNIEnv* env, jobject clazz, jint handle, jobject ch return; } if (code->callbacks.onInputQueueCreated != NULL) { - code->callbacks.onInputQueueCreated(&code->activity, + code->callbacks.onInputQueueCreated(code, code->nativeInputQueue); } } @@ -429,7 +502,7 @@ onInputChannelDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject 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 a82abc9..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 index c37932e..c37932e 100644 --- a/core/jni/android_view_Surface.h +++ b/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 @@ public: } // 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 @@ public: 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 @@ bool Rect::operator < (const Rect& rhs) const 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 @@ Rect& Rect::offsetTo(int x, int y) 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 @@ include $(CLEAR_VARS) # 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_getFormat(ANativeWindow* window) { } 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 @@ int8_t android_app_read_cmd(struct android_app* android_app) { 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 @@ void android_app_exec_cmd(struct android_app* android_app, int8_t cmd) { 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 @@ typedef void ANativeActivity_createFunc(ANativeActivity* activity, */ 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 @@ enum { 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 @@ int32_t ANativeWindow_getFormat(ANativeWindow* window); * 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 @@ struct android_app { // 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 @@ struct android_app { 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 @@ int8_t android_app_read_cmd(struct android_app* android_app); /** * 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 |