summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2010-06-30 18:35:14 -0700
committerDianne Hackborn <hackbod@google.com>2010-07-01 14:43:23 -0700
commit54a181b1a2b1517a9479b21fbf7705a688232faf (patch)
tree90bf20d8f5f818d357c677cb713e964b920dea67
parent65c83b906d01c3c1493d0547757dbb16d4c3722a (diff)
downloadframeworks_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.java25
-rw-r--r--core/jni/android_app_NativeActivity.cpp78
-rw-r--r--core/jni/android_view_Surface.cpp3
-rw-r--r--core/jni/android_view_Surface.h31
-rw-r--r--core/jni/com_google_android_gles_jni_EGLImpl.cpp11
-rw-r--r--native/android/Android.mk3
-rw-r--r--native/android/native_window.cpp41
-rw-r--r--native/include/android/native_activity.h31
-rw-r--r--native/include/android/native_window.h17
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
};