am 74323fd1: Update NativeActivity to allow direct surface access.

This commit is contained in:
Dianne Hackborn
2010-05-18 18:23:47 -07:00
committed by Android Git Automerger
4 changed files with 261 additions and 21 deletions

View File

@@ -26284,6 +26284,8 @@
deprecated="not deprecated"
visibility="public"
>
<implements name="android.view.SurfaceHolder.Callback">
</implements>
<constructor name="NativeActivity"
type="android.app.NativeActivity"
static="false"
@@ -26292,6 +26294,51 @@
visibility="public"
>
</constructor>
<method name="surfaceChanged"
return="void"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
<parameter name="holder" type="android.view.SurfaceHolder">
</parameter>
<parameter name="format" type="int">
</parameter>
<parameter name="width" type="int">
</parameter>
<parameter name="height" type="int">
</parameter>
</method>
<method name="surfaceCreated"
return="void"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
<parameter name="holder" type="android.view.SurfaceHolder">
</parameter>
</method>
<method name="surfaceDestroyed"
return="void"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
<parameter name="holder" type="android.view.SurfaceHolder">
</parameter>
</method>
<field name="META_DATA_LIB_NAME"
type="java.lang.String"
transient="false"

View File

@@ -6,6 +6,7 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.SurfaceHolder;
import java.io.File;
@@ -13,7 +14,7 @@ import java.io.File;
* Convenience for implementing an activity that will be implemented
* purely in native code. That is, a game (or game-like thing).
*/
public class NativeActivity extends Activity {
public class NativeActivity extends Activity implements SurfaceHolder.Callback {
public static final String META_DATA_LIB_NAME = "android.app.lib_name";
private int mNativeHandle;
@@ -28,12 +29,18 @@ public class NativeActivity extends Activity {
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,
int format, int width, int height);
private native void onSurfaceDestroyedNative(int handle, SurfaceHolder holder);
@Override
protected void onCreate(Bundle savedInstanceState) {
String libname = "main";
ActivityInfo ai;
getWindow().takeSurface(this);
try {
ai = getPackageManager().getActivityInfo(
getIntent().getComponent(), PackageManager.GET_META_DATA);
@@ -78,12 +85,6 @@ public class NativeActivity extends Activity {
super.onDestroy();
}
@Override
public void onLowMemory() {
super.onLowMemory();
onLowMemoryNative(mNativeHandle);
}
@Override
protected void onPause() {
super.onPause();
@@ -114,9 +115,27 @@ public class NativeActivity extends Activity {
onStopNative(mNativeHandle);
}
@Override
public void onLowMemory() {
super.onLowMemory();
onLowMemoryNative(mNativeHandle);
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
onWindowFocusChangedNative(mNativeHandle, hasFocus);
}
public void surfaceCreated(SurfaceHolder holder) {
onSurfaceCreatedNative(mNativeHandle, holder);
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
onSurfaceChangedNative(mNativeHandle, holder, format, width, height);
}
public void surfaceDestroyed(SurfaceHolder holder) {
onSurfaceDestroyedNative(mNativeHandle, holder);
}
}

View File

@@ -27,13 +27,41 @@ namespace android
{
struct NativeCode {
NativeCode(void* _dlhandle, android_activity_create_t* _createFunc) {
memset(&activity, sizeof(activity), 0);
memset(&callbacks, sizeof(callbacks), 0);
dlhandle = _dlhandle;
createActivityFunc = _createFunc;
surface = NULL;
}
~NativeCode() {
if (callbacks.onDestroy != NULL) {
callbacks.onDestroy(&activity);
}
if (dlhandle != NULL) {
dlclose(dlhandle);
}
}
void setSurface(jobject _surface) {
if (surface != NULL) {
activity.env->DeleteGlobalRef(surface);
}
if (_surface != NULL) {
surface = activity.env->NewGlobalRef(_surface);
} else {
surface = NULL;
}
}
android_activity_t activity;
android_activity_callbacks_t callbacks;
void* dlhandle;
android_activity_create_t* createActivityFunc;
void* clientContext;
jobject surface;
};
static jint
@@ -47,18 +75,13 @@ loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path)
env->ReleaseStringUTFChars(path, pathStr);
if (handle != NULL) {
code = new NativeCode();
code->dlhandle = handle;
code->createActivityFunc = (android_activity_create_t*)
dlsym(handle, "android_onCreateActivity");
code = new NativeCode(handle, (android_activity_create_t*)
dlsym(handle, "android_onCreateActivity"));
if (code->createActivityFunc == NULL) {
LOGW("android_onCreateActivity not found");
delete code;
dlclose(handle);
return 0;
}
memset(&code->activity, sizeof(code->activity), 0);
memset(&code->callbacks, sizeof(code->callbacks), 0);
code->activity.callbacks = &code->callbacks;
code->activity.env = env;
code->activity.clazz = clazz;
@@ -73,10 +96,6 @@ unloadNativeCode_native(JNIEnv* env, jobject clazz, jint handle)
{
if (handle != 0) {
NativeCode* code = (NativeCode*)handle;
if (code->callbacks.onDestroy != NULL) {
code->callbacks.onDestroy(&code->activity);
}
dlclose(code->dlhandle);
delete code;
}
}
@@ -159,6 +178,45 @@ onWindowFocusChanged_native(JNIEnv* env, jobject clazz, jint handle, jboolean fo
}
}
static void
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,
(android_surface_t*)code->surface);
}
}
}
static void
onSurfaceChanged_native(JNIEnv* env, jobject clazz, jint handle, jobject surface,
jint format, jint width, jint height)
{
if (handle != 0) {
NativeCode* code = (NativeCode*)handle;
if (code->surface != NULL && code->callbacks.onSurfaceChanged != NULL) {
code->callbacks.onSurfaceChanged(&code->activity,
(android_surface_t*)code->surface, format, width, height);
}
}
}
static void
onSurfaceDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject surface)
{
if (handle != 0) {
NativeCode* code = (NativeCode*)handle;
if (code->surface != NULL && code->callbacks.onSurfaceDestroyed != NULL) {
code->callbacks.onSurfaceDestroyed(&code->activity,
(android_surface_t*)code->surface);
}
code->setSurface(NULL);
}
}
static const JNINativeMethod g_methods[] = {
{ "loadNativeCode", "(Ljava/lang/String;)I", (void*)loadNativeCode_native },
{ "unloadNativeCode", "(I)V", (void*)unloadNativeCode_native },
@@ -169,6 +227,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 },
};
static const char* const kNativeActivityPathName = "android/app/NativeActivity";

View File

@@ -27,32 +27,145 @@
extern "C" {
#endif
// Temporary until native surface API is defined.
struct android_surface_t;
typedef struct android_surface_t android_surface_t;
struct android_activity_callbacks_t;
/**
* This structure defines the native side of an android.app.NativeActivity.
* It is created by the framework, and handed to the application's native
* code as it is being launched.
*/
typedef struct android_activity_t {
/**
* Pointer to the callback function table of the native application.
* You can set the functions here to your own callbacks. The callbacks
* pointer itself here should not be changed; it is allocated and managed
* for you by the framework.
*/
struct android_activity_callbacks_t* callbacks;
/**
* JNI context for the main thread of the app.
*/
JNIEnv* env;
/**
* The NativeActivity Java class.
*/
jobject clazz;
/**
* This is the native instance of the application. It is not used by
* the framework, but can be set by the application to its own instance
* state.
*/
void* instance;
} android_activity_t;
/**
* These are the callbacks the framework makes into a native application.
* All of these callbacks happen on the main thread of the application.
* By default, all callbacks are NULL; set to a pointer to your own function
* to have it called.
*/
typedef struct android_activity_callbacks_t {
/**
* NativeActivity has started. See Java documentation for Activity.onStart()
* for more information.
*/
void (*onStart)(android_activity_t* activity);
/**
* NativeActivity has resumed. See Java documentation for Activity.onResume()
* for more information.
*/
void (*onResume)(android_activity_t* activity);
/**
* Framework is asking NativeActivity to save its current instance state.
* See Java documentation for Activity.onSaveInstanceState() for more
* information. The returned pointer needs to be created with malloc();
* the framework will call free() on it for you. You also must fill in
* outSize with the number of bytes in the allocation. Note that the
* saved state will be persisted, so it can not contain any active
* entities (pointers to memory, file descriptors, etc).
*/
void* (*onSaveInstanceState)(android_activity_t* activity, size_t* outSize);
/**
* NativeActivity has paused. See Java documentation for Activity.onPause()
* for more information.
*/
void (*onPause)(android_activity_t* activity);
/**
* NativeActivity has stopped. See Java documentation for Activity.onStop()
* for more information.
*/
void (*onStop)(android_activity_t* activity);
/**
* NativeActivity is being destroyed. See Java documentation for Activity.onDestroy()
* for more information.
*/
void (*onDestroy)(android_activity_t* activity);
void (*onLowMemory)(android_activity_t* activity);
/**
* Focus has changed in this NativeActivity's window. This is often used,
* for example, to pause a game when it loses input focus.
*/
void (*onWindowFocusChanged)(android_activity_t* 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.
*/
void (*onSurfaceCreated)(android_activity_t* activity, android_surface_t* surface);
/**
* 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.
*/
void (*onSurfaceChanged)(android_activity_t* activity, android_surface_t* surface,
int format, int width, int height);
/**
* 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
* 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)(android_activity_t* activity, android_surface_t* surface);
/**
* The system is running low on memory. Use this callback to release
* resources you do not need, to help the system avoid killing more
* important processes.
*/
void (*onLowMemory)(android_activity_t* activity);
} android_activity_callbacks_t;
/**
* This is the function that must be in the native code to instantiate the
* application's native activity. It is called with the activity instance (see
* above); if the code is being instantiated from a previously saved instance,
* the savedState will be non-NULL and point to the saved data.
*/
typedef void android_activity_create_t(android_activity_t* activity,
void* savedState, size_t savedStateSize);
/**
* The name of the function that NativeInstance looks for when launching its
* native code.
*/
extern android_activity_create_t android_onCreateActivity;
#ifdef __cplusplus