am 74323fd1: Update NativeActivity to allow direct surface access.
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user