diff options
author | Dianne Hackborn <hackbod@google.com> | 2010-06-30 18:35:14 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2010-07-01 14:43:23 -0700 |
commit | 54a181b1a2b1517a9479b21fbf7705a688232faf (patch) | |
tree | 90bf20d8f5f818d357c677cb713e964b920dea67 | |
parent | 65c83b906d01c3c1493d0547757dbb16d4c3722a (diff) | |
download | frameworks_base-54a181b1a2b1517a9479b21fbf7705a688232faf.zip frameworks_base-54a181b1a2b1517a9479b21fbf7705a688232faf.tar.gz frameworks_base-54a181b1a2b1517a9479b21fbf7705a688232faf.tar.bz2 |
Make real API for native code to get its window.
Added implementation to use ANativeWindow and provide
it to a NativeActivity.
Change-Id: I890d71b6e15d4af71e6cf81b327961d7061ec1c2
-rw-r--r-- | core/java/android/app/NativeActivity.java | 25 | ||||
-rw-r--r-- | core/jni/android_app_NativeActivity.cpp | 78 | ||||
-rw-r--r-- | core/jni/android_view_Surface.cpp | 3 | ||||
-rw-r--r-- | core/jni/android_view_Surface.h | 31 | ||||
-rw-r--r-- | core/jni/com_google_android_gles_jni_EGLImpl.cpp | 11 | ||||
-rw-r--r-- | native/android/Android.mk | 3 | ||||
-rw-r--r-- | native/android/native_window.cpp | 41 | ||||
-rw-r--r-- | native/include/android/native_activity.h | 31 | ||||
-rw-r--r-- | native/include/android/native_window.h | 17 |
9 files changed, 185 insertions, 55 deletions
diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java index d43368b..161161c 100644 --- a/core/java/android/app/NativeActivity.java +++ b/core/java/android/app/NativeActivity.java @@ -5,12 +5,14 @@ import dalvik.system.PathClassLoader; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.graphics.PixelFormat; import android.os.Bundle; import android.os.Looper; import android.os.MessageQueue; import android.view.InputChannel; import android.view.InputQueue; import android.view.KeyEvent; +import android.view.Surface; import android.view.SurfaceHolder; import android.view.View; @@ -41,10 +43,10 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback, private native void onStopNative(int handle); private native void onLowMemoryNative(int handle); private native void onWindowFocusChangedNative(int handle, boolean focused); - private native void onSurfaceCreatedNative(int handle, SurfaceHolder holder); - private native void onSurfaceChangedNative(int handle, SurfaceHolder holder, + private native void onSurfaceCreatedNative(int handle, Surface surface); + private native void onSurfaceChangedNative(int handle, Surface surface, int format, int width, int height); - private native void onSurfaceDestroyedNative(int handle, SurfaceHolder holder); + private native void onSurfaceDestroyedNative(int handle); private native void onInputChannelCreatedNative(int handle, InputChannel channel); private native void onInputChannelDestroyedNative(int handle, InputChannel channel); @@ -55,6 +57,7 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback, getWindow().takeSurface(this); getWindow().takeInputQueue(this); + getWindow().setFormat(PixelFormat.RGB_565); try { ai = getPackageManager().getActivityInfo( @@ -98,7 +101,7 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback, protected void onDestroy() { mDestroyed = true; if (mCurSurfaceHolder != null) { - onSurfaceDestroyedNative(mNativeHandle, mCurSurfaceHolder); + onSurfaceDestroyedNative(mNativeHandle); mCurSurfaceHolder = null; } if (mCurInputQueue != null) { @@ -158,21 +161,21 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback, public void surfaceCreated(SurfaceHolder holder) { if (!mDestroyed) { mCurSurfaceHolder = holder; - onSurfaceCreatedNative(mNativeHandle, holder); + onSurfaceCreatedNative(mNativeHandle, holder.getSurface()); } } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if (!mDestroyed) { mCurSurfaceHolder = holder; - onSurfaceChangedNative(mNativeHandle, holder, format, width, height); + onSurfaceChangedNative(mNativeHandle, holder.getSurface(), format, width, height); } } public void surfaceDestroyed(SurfaceHolder holder) { mCurSurfaceHolder = null; if (!mDestroyed) { - onSurfaceDestroyedNative(mNativeHandle, holder); + onSurfaceDestroyedNative(mNativeHandle); } } @@ -196,4 +199,12 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback, decor.dispatchKeyEvent(event); } } + + void setWindowFlags(int flags, int mask) { + getWindow().setFlags(flags, mask); + } + + void setWindowFormat(int format) { + getWindow().setFormat(format); + } } diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp index dd59d63..49b9609 100644 --- a/core/jni/android_app_NativeActivity.cpp +++ b/core/jni/android_app_NativeActivity.cpp @@ -22,6 +22,8 @@ #include <android_runtime/AndroidRuntime.h> #include <android/native_activity.h> +#include <surfaceflinger/Surface.h> +#include <ui/egl/android_natives.h> #include <ui/InputTransport.h> #include <utils/PollLoop.h> @@ -29,6 +31,7 @@ #include "android_os_MessageQueue.h" #include "android_view_InputChannel.h" #include "android_view_KeyEvent.h" +#include "android_view_Surface.h" namespace android { @@ -37,8 +40,16 @@ static struct { jclass clazz; jmethodID dispatchUnhandledKeyEvent; + jmethodID setWindowFlags; + jmethodID setWindowFormat; } gNativeActivityClassInfo; +// ------------------------------------------------------------------------ + +/* + * Specialized input queue that allows unhandled key events to be dispatched + * back to the native activity's Java framework code. + */ struct MyInputQueue : AInputQueue { explicit MyInputQueue(const android::sp<android::InputChannel>& channel, int workWrite) : AInputQueue(channel), mWorkWrite(workWrite) { @@ -74,13 +85,18 @@ struct MyInputQueue : AInputQueue { Vector<KeyEvent*> mPendingKeys; }; +// ------------------------------------------------------------------------ + +/* + * Native state for interacting with the NativeActivity class. + */ struct NativeCode { NativeCode(void* _dlhandle, ANativeActivity_createFunc* _createFunc) { memset(&activity, sizeof(activity), 0); memset(&callbacks, sizeof(callbacks), 0); dlhandle = _dlhandle; createActivityFunc = _createFunc; - surface = NULL; + nativeWindow = NULL; inputChannel = NULL; nativeInputQueue = NULL; mainWorkRead = mainWorkWrite = -1; @@ -104,18 +120,18 @@ struct NativeCode { if (mainWorkRead >= 0) close(mainWorkRead); if (mainWorkWrite >= 0) close(mainWorkWrite); if (dlhandle != NULL) { - dlclose(dlhandle); + // for now don't unload... we probably should clean this + // up and only keep one open dlhandle per proc, since there + // is really no benefit to unloading the code. + //dlclose(dlhandle); } } void setSurface(jobject _surface) { - if (surface != NULL) { - activity.env->DeleteGlobalRef(surface); - } if (_surface != NULL) { - surface = activity.env->NewGlobalRef(_surface); + nativeWindow = android_Surface_getNativeWindow(activity.env, _surface); } else { - surface = NULL; + nativeWindow = NULL; } } @@ -150,7 +166,7 @@ struct NativeCode { void* dlhandle; ANativeActivity_createFunc* createActivityFunc; - jobject surface; + sp<ANativeWindow> nativeWindow; jobject inputChannel; struct MyInputQueue* nativeInputQueue; @@ -160,6 +176,11 @@ struct NativeCode { sp<PollLoop> pollLoop; }; +// ------------------------------------------------------------------------ + +/* + * Callback for handling native events on the application's main thread. + */ static bool mainWorkCallback(int fd, int events, void* data) { NativeCode* code = (NativeCode*)data; if ((events & POLLIN) != 0) { @@ -180,6 +201,8 @@ static bool mainWorkCallback(int fd, int events, void* data) { return true; } +// ------------------------------------------------------------------------ + static jint loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jobject messageQueue) { @@ -323,9 +346,9 @@ onSurfaceCreated_native(JNIEnv* env, jobject clazz, jint handle, jobject surface if (handle != 0) { NativeCode* code = (NativeCode*)handle; code->setSurface(surface); - if (code->callbacks.onSurfaceCreated != NULL) { - code->callbacks.onSurfaceCreated(&code->activity, - (ASurfaceHolder*)code->surface); + if (code->nativeWindow != NULL && code->callbacks.onNativeWindowCreated != NULL) { + code->callbacks.onNativeWindowCreated(&code->activity, + code->nativeWindow.get()); } } } @@ -336,9 +359,13 @@ onSurfaceChanged_native(JNIEnv* env, jobject clazz, jint handle, jobject surface { if (handle != 0) { NativeCode* code = (NativeCode*)handle; - if (code->surface != NULL && code->callbacks.onSurfaceChanged != NULL) { - code->callbacks.onSurfaceChanged(&code->activity, - (ASurfaceHolder*)code->surface, format, width, height); + sp<ANativeWindow> oldNativeWindow = code->nativeWindow; + code->setSurface(surface); + if (oldNativeWindow != code->nativeWindow) { + if (code->nativeWindow != NULL && code->callbacks.onNativeWindowChanged != NULL) { + code->callbacks.onNativeWindowChanged(&code->activity, + code->nativeWindow.get()); + } } } } @@ -348,9 +375,9 @@ onSurfaceDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject surfa { if (handle != 0) { NativeCode* code = (NativeCode*)handle; - if (code->surface != NULL && code->callbacks.onSurfaceDestroyed != NULL) { - code->callbacks.onSurfaceDestroyed(&code->activity, - (ASurfaceHolder*)code->surface); + if (code->nativeWindow != NULL && code->callbacks.onNativeWindowDestroyed != NULL) { + code->callbacks.onNativeWindowDestroyed(&code->activity, + code->nativeWindow.get()); } code->setSurface(NULL); } @@ -398,9 +425,9 @@ static const JNINativeMethod g_methods[] = { { "onStopNative", "(I)V", (void*)onStop_native }, { "onLowMemoryNative", "(I)V", (void*)onLowMemory_native }, { "onWindowFocusChangedNative", "(IZ)V", (void*)onWindowFocusChanged_native }, - { "onSurfaceCreatedNative", "(ILandroid/view/SurfaceHolder;)V", (void*)onSurfaceCreated_native }, - { "onSurfaceChangedNative", "(ILandroid/view/SurfaceHolder;III)V", (void*)onSurfaceChanged_native }, - { "onSurfaceDestroyedNative", "(ILandroid/view/SurfaceHolder;)V", (void*)onSurfaceDestroyed_native }, + { "onSurfaceCreatedNative", "(ILandroid/view/Surface;)V", (void*)onSurfaceCreated_native }, + { "onSurfaceChangedNative", "(ILandroid/view/Surface;III)V", (void*)onSurfaceChanged_native }, + { "onSurfaceDestroyedNative", "(I)V", (void*)onSurfaceDestroyed_native }, { "onInputChannelCreatedNative", "(ILandroid/view/InputChannel;)V", (void*)onInputChannelCreated_native }, { "onInputChannelDestroyedNative", "(ILandroid/view/InputChannel;)V", (void*)onInputChannelDestroyed_native }, }; @@ -421,11 +448,18 @@ int register_android_app_NativeActivity(JNIEnv* env) //LOGD("register_android_app_NativeActivity"); FIND_CLASS(gNativeActivityClassInfo.clazz, kNativeActivityPathName); - + GET_METHOD_ID(gNativeActivityClassInfo.dispatchUnhandledKeyEvent, gNativeActivityClassInfo.clazz, "dispatchUnhandledKeyEvent", "(Landroid/view/KeyEvent;)V"); - + + GET_METHOD_ID(gNativeActivityClassInfo.setWindowFlags, + gNativeActivityClassInfo.clazz, + "setWindowFlags", "(II)V"); + GET_METHOD_ID(gNativeActivityClassInfo.setWindowFormat, + gNativeActivityClassInfo.clazz, + "setWindowFormat", "(I)V"); + return AndroidRuntime::registerNativeMethods( env, kNativeActivityPathName, g_methods, NELEM(g_methods)); diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index cef5c10..a82abc9 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -33,6 +33,7 @@ #include "jni.h" #include <android_runtime/AndroidRuntime.h> +#include "android_view_Surface.h" #include <utils/misc.h> @@ -179,7 +180,7 @@ static sp<Surface> getSurface(JNIEnv* env, jobject clazz) return result; } -EGLNativeWindowType android_Surface_getEGLNativeWindow( +sp<ANativeWindow> android_Surface_getNativeWindow( JNIEnv* env, jobject clazz) { return getSurface(env, clazz).get(); } diff --git a/core/jni/android_view_Surface.h b/core/jni/android_view_Surface.h new file mode 100644 index 0000000..c37932e --- /dev/null +++ b/core/jni/android_view_Surface.h @@ -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. + */ + +#ifndef _ANDROID_VIEW_SURFACE_H +#define _ANDROID_VIEW_SURFACE_H + +#include <android/native_window.h> + +#include "jni.h" + +namespace android { + +extern sp<ANativeWindow> android_Surface_getNativeWindow( + JNIEnv* env, jobject clazz); + +} // namespace android + +#endif // _ANDROID_VIEW_SURFACE_H diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp index d5cde48..866c038 100644 --- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp +++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp @@ -25,10 +25,9 @@ #include <SkBitmap.h> #include <SkPixelRef.h> -namespace android { +#include "android_view_Surface.h" -extern EGLNativeWindowType android_Surface_getEGLNativeWindow( - JNIEnv* env, jobject clazz); +namespace android { static jclass gDisplay_class; static jclass gContext_class; @@ -325,7 +324,7 @@ static jint jni_eglCreateWindowSurface(JNIEnv *_env, jobject _this, jobject disp } EGLDisplay dpy = getDisplay(_env, display); EGLContext cnf = getConfig(_env, config); - EGLNativeWindowType window = 0; + sp<ANativeWindow> window; if (native_window == NULL) { not_valid_surface: doThrow(_env, "java/lang/IllegalArgumentException", @@ -333,12 +332,12 @@ not_valid_surface: return 0; } - window = android_Surface_getEGLNativeWindow(_env, native_window); + window = android_Surface_getNativeWindow(_env, native_window); if (window == NULL) goto not_valid_surface; jint* base = beginNativeAttribList(_env, attrib_list); - EGLSurface sur = eglCreateWindowSurface(dpy, cnf, window, base); + EGLSurface sur = eglCreateWindowSurface(dpy, cnf, window.get(), base); endNativeAttributeList(_env, attrib_list, base); return (jint)sur; } diff --git a/native/android/Android.mk b/native/android/Android.mk index 8c621b6..fe8ed00 100644 --- a/native/android/Android.mk +++ b/native/android/Android.mk @@ -7,7 +7,8 @@ include $(CLEAR_VARS) # LOCAL_SRC_FILES:= \ activity.cpp \ - input.cpp + input.cpp \ + native_window.cpp LOCAL_SHARED_LIBRARIES := \ libandroid_runtime \ diff --git a/native/android/native_window.cpp b/native/android/native_window.cpp new file mode 100644 index 0000000..7a6eb6d --- /dev/null +++ b/native/android/native_window.cpp @@ -0,0 +1,41 @@ +/* + * 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 "Surface" +#include <utils/Log.h> + +#include <android/native_window.h> +#include <surfaceflinger/Surface.h> + +using android::Surface; + +static int32_t getWindowProp(ANativeWindow* window, int what) { + int value; + int res = window->query(window, what, &value); + return res < 0 ? res : value; +} + +int32_t ANativeWindow_getWidth(ANativeWindow* window) { + return getWindowProp(window, NATIVE_WINDOW_WIDTH); +} + +int32_t ANativeWindow_getHeight(ANativeWindow* window) { + return getWindowProp(window, NATIVE_WINDOW_HEIGHT); +} + +int32_t ANativeWindow_getFormat(ANativeWindow* window) { + return getWindowProp(window, NATIVE_WINDOW_FORMAT); +} diff --git a/native/include/android/native_activity.h b/native/include/android/native_activity.h index c5c8f9d..d23e40f 100644 --- a/native/include/android/native_activity.h +++ b/native/include/android/native_activity.h @@ -24,15 +24,12 @@ #include <jni.h> #include <android/input.h> +#include <android/native_window.h> #ifdef __cplusplus extern "C" { #endif -// Temporary until native surface API is defined. -struct ASurfaceHolder; -typedef struct ASurfaceHolder ASurfaceHolder; - struct ANativeActivityCallbacks; /** @@ -129,30 +126,28 @@ typedef struct ANativeActivityCallbacks { void (*onWindowFocusChanged)(ANativeActivity* activity, int hasFocus); /** - * The drawing surface for this native activity has been created. You - * can use the given surface object to start drawing. NOTE: surface - * drawing API is not yet defined. + * The drawing window for this native activity has been created. You + * can use the given native window object to start drawing. */ - void (*onSurfaceCreated)(ANativeActivity* activity, ASurfaceHolder* surface); + void (*onNativeWindowCreated)(ANativeActivity* activity, ANativeWindow* window); /** - * The drawing surface for this native activity has changed. The surface - * given here is guaranteed to be the same as the one last given to - * onSurfaceCreated. This is simply to inform you about interesting - * changed to that surface. + * The drawing window for this native activity has changed. During this time, + * old ANativeWindow object is still valid but no longer active and drawing + * should switch to the new ANativeWindow given here. After returning from + * this function, you must not touch the old window. */ - void (*onSurfaceChanged)(ANativeActivity* activity, ASurfaceHolder* surface, - int format, int width, int height); + void (*onNativeWindowChanged)(ANativeActivity* activity, ANativeWindow* window); /** - * The drawing surface for this native activity is going to be destroyed. - * You MUST ensure that you do not touch the surface object after returning - * from this function: in the common case of drawing to the surface from + * The drawing window for this native activity is going to be destroyed. + * You MUST ensure that you do not touch the window object after returning + * from this function: in the common case of drawing to the window from * another thread, that means the implementation of this callback must * properly synchronize with the other thread to stop its drawing before * returning from here. */ - void (*onSurfaceDestroyed)(ANativeActivity* activity, ASurfaceHolder* surface); + void (*onNativeWindowDestroyed)(ANativeActivity* activity, ANativeWindow* window); /** * The input queue for this native activity's window has been created. diff --git a/native/include/android/native_window.h b/native/include/android/native_window.h index e6d5fea..b3f47b2 100644 --- a/native/include/android/native_window.h +++ b/native/include/android/native_window.h @@ -25,6 +25,23 @@ extern "C" { struct ANativeWindow; typedef struct ANativeWindow ANativeWindow; +/* + * Return the current width in pixels of the window surface. Returns a + * negative value on error. + */ +int32_t ANativeWindow_getWidth(ANativeWindow* window); + +/* + * Return the current height in pixels of the window surface. Returns a + * negative value on error. + */ +int32_t ANativeWindow_getHeight(ANativeWindow* window); + +/* + * Return the current pixel format of the window surface. Returns a + * negative value on error. + */ +int32_t ANativeWindow_getFormat(ANativeWindow* window); #ifdef __cplusplus }; |