Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b269735c authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android Git Automerger
Browse files

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

parents d7289efb 4a30bcf7
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -27842,6 +27842,8 @@
 deprecated="not deprecated"
 visibility="public"
>
<implements name="android.view.SurfaceHolder.Callback">
</implements>
<constructor name="NativeActivity"
 type="android.app.NativeActivity"
 static="false"
@@ -27850,6 +27852,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"
+26 −7
Original line number Diff line number Diff line
@@ -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);
    }
}
+74 −13
Original line number Diff line number Diff line
@@ -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";
+114 −1
Original line number Diff line number Diff line
@@ -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