Merge "Fix issue #3126018: No way to specify NativeActivity's native method" into gingerbread

This commit is contained in:
Dianne Hackborn
2010-10-24 18:33:36 -07:00
committed by Android (Google) Code Review
4 changed files with 58 additions and 11 deletions

View File

@@ -23853,11 +23853,11 @@
<parameter name="holder" type="android.view.SurfaceHolder"> <parameter name="holder" type="android.view.SurfaceHolder">
</parameter> </parameter>
</method> </method>
<field name="KEY_NATIVE_SAVED_STATE" <field name="META_DATA_FUNC_NAME"
type="java.lang.String" type="java.lang.String"
transient="false" transient="false"
volatile="false" volatile="false"
value="&quot;android:native_state&quot;" value="&quot;android.app.func_name&quot;"
static="true" static="true"
final="true" final="true"
deprecated="not deprecated" deprecated="not deprecated"

View File

@@ -5,7 +5,6 @@ import com.android.internal.view.IInputMethodSession;
import android.content.Context; import android.content.Context;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.AssetManager; import android.content.res.AssetManager;
import android.content.res.Configuration; import android.content.res.Configuration;
@@ -48,9 +47,22 @@ import java.lang.ref.WeakReference;
*/ */
public class NativeActivity extends Activity implements SurfaceHolder.Callback2, public class NativeActivity extends Activity implements SurfaceHolder.Callback2,
InputQueue.Callback, OnGlobalLayoutListener { InputQueue.Callback, OnGlobalLayoutListener {
/**
* Optional meta-that can be in the manifest for this component, specifying
* the name of the native shared library to load. If not specified,
* "main" is used.
*/
public static final String META_DATA_LIB_NAME = "android.app.lib_name"; public static final String META_DATA_LIB_NAME = "android.app.lib_name";
public static final String KEY_NATIVE_SAVED_STATE = "android:native_state"; /**
* Optional meta-that can be in the manifest for this component, specifying
* the name of the main entry point for this native activity in the
* {@link #META_DATA_LIB_NAME} native code. If not specified,
* "ANativeActivity_onCreate" is used.
*/
public static final String META_DATA_FUNC_NAME = "android.app.func_name";
private static final String KEY_NATIVE_SAVED_STATE = "android:native_state";
private NativeContentView mNativeContentView; private NativeContentView mNativeContentView;
private InputMethodManager mIMM; private InputMethodManager mIMM;
@@ -71,7 +83,7 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2,
private boolean mDestroyed; private boolean mDestroyed;
private native int loadNativeCode(String path, MessageQueue queue, private native int loadNativeCode(String path, String funcname, MessageQueue queue,
String internalDataPath, String externalDataPath, int sdkVersion, String internalDataPath, String externalDataPath, int sdkVersion,
AssetManager assetMgr, byte[] savedState); AssetManager assetMgr, byte[] savedState);
private native void unloadNativeCode(int handle); private native void unloadNativeCode(int handle);
@@ -131,6 +143,7 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2,
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
String libname = "main"; String libname = "main";
String funcname = "ANativeActivity_onCreate";
ActivityInfo ai; ActivityInfo ai;
mIMM = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); mIMM = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
@@ -155,6 +168,8 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2,
if (ai.metaData != null) { if (ai.metaData != null) {
String ln = ai.metaData.getString(META_DATA_LIB_NAME); String ln = ai.metaData.getString(META_DATA_LIB_NAME);
if (ln != null) libname = ln; if (ln != null) libname = ln;
ln = ai.metaData.getString(META_DATA_FUNC_NAME);
if (ln != null) funcname = ln;
} }
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException("Error getting activity info", e); throw new RuntimeException("Error getting activity info", e);
@@ -175,7 +190,7 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2,
byte[] nativeSavedState = savedInstanceState != null byte[] nativeSavedState = savedInstanceState != null
? savedInstanceState.getByteArray(KEY_NATIVE_SAVED_STATE) : null; ? savedInstanceState.getByteArray(KEY_NATIVE_SAVED_STATE) : null;
mNativeHandle = loadNativeCode(path, Looper.myQueue(), mNativeHandle = loadNativeCode(path, funcname, Looper.myQueue(),
getFilesDir().toString(), getFilesDir().toString(),
Environment.getExternalStorageAppFilesDirectory(ai.packageName).toString(), Environment.getExternalStorageAppFilesDirectory(ai.packageName).toString(),
Build.VERSION.SDK_INT, getAssets(), nativeSavedState); Build.VERSION.SDK_INT, getAssets(), nativeSavedState);

View File

@@ -626,7 +626,8 @@ static int mainWorkCallback(int fd, int events, void* data) {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
static jint static jint
loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jobject messageQueue, loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName,
jobject messageQueue,
jstring internalDataDir, jstring externalDataDir, int sdkVersion, jstring internalDataDir, jstring externalDataDir, int sdkVersion,
jobject jAssetMgr, jbyteArray savedState) jobject jAssetMgr, jbyteArray savedState)
{ {
@@ -640,8 +641,11 @@ loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jobject messageQ
env->ReleaseStringUTFChars(path, pathStr); env->ReleaseStringUTFChars(path, pathStr);
if (handle != NULL) { if (handle != NULL) {
const char* funcStr = env->GetStringUTFChars(funcName, NULL);
code = new NativeCode(handle, (ANativeActivity_createFunc*) code = new NativeCode(handle, (ANativeActivity_createFunc*)
dlsym(handle, "ANativeActivity_onCreate")); dlsym(handle, funcStr));
env->ReleaseStringUTFChars(funcName, funcStr);
if (code->createActivityFunc == NULL) { if (code->createActivityFunc == NULL) {
LOGW("ANativeActivity_onCreate not found"); LOGW("ANativeActivity_onCreate not found");
delete code; delete code;
@@ -999,7 +1003,7 @@ finishPreDispatchKeyEvent_native(JNIEnv* env, jobject clazz, jint handle,
} }
static const JNINativeMethod g_methods[] = { static const JNINativeMethod g_methods[] = {
{ "loadNativeCode", "(Ljava/lang/String;Landroid/os/MessageQueue;Ljava/lang/String;Ljava/lang/String;ILandroid/content/res/AssetManager;[B)I", { "loadNativeCode", "(Ljava/lang/String;Ljava/lang/String;Landroid/os/MessageQueue;Ljava/lang/String;Ljava/lang/String;ILandroid/content/res/AssetManager;[B)I",
(void*)loadNativeCode_native }, (void*)loadNativeCode_native },
{ "unloadNativeCode", "(I)V", (void*)unloadNativeCode_native }, { "unloadNativeCode", "(I)V", (void*)unloadNativeCode_native },
{ "onStartNative", "(I)V", (void*)onStart_native }, { "onStartNative", "(I)V", (void*)onStart_native },

View File

@@ -223,18 +223,34 @@ typedef void ANativeActivity_createFunc(ANativeActivity* activity,
/** /**
* The name of the function that NativeInstance looks for when launching its * The name of the function that NativeInstance looks for when launching its
* native code. * native code. This is the default function that is used, you can specify
* "android.app.func_name" string meta-data in your manifest to use a different
* function.
*/ */
extern ANativeActivity_createFunc ANativeActivity_onCreate; extern ANativeActivity_createFunc ANativeActivity_onCreate;
/** /**
* Finish the given activity. Its finish() method will be called, causing it * Finish the given activity. Its finish() method will be called, causing it
* to be stopped and destroyed. * to be stopped and destroyed. Note that this method can be called from
* *any* thread; it will send a message to the main thread of the process
* where the Java finish call will take place.
*/ */
void ANativeActivity_finish(ANativeActivity* activity); void ANativeActivity_finish(ANativeActivity* activity);
/**
* Change the window format of the given activity. Calls getWindow().setFormat()
* of the given activity. Note that this method can be called from
* *any* thread; it will send a message to the main thread of the process
* where the Java finish call will take place.
*/
void ANativeActivity_setWindowFormat(ANativeActivity* activity, int32_t format); void ANativeActivity_setWindowFormat(ANativeActivity* activity, int32_t format);
/**
* Change the window flags of the given activity. Calls getWindow().setFlags()
* of the given activity. Note that this method can be called from
* *any* thread; it will send a message to the main thread of the process
* where the Java finish call will take place. See window.h for flag constants.
*/
void ANativeActivity_setWindowFlags(ANativeActivity* activity, void ANativeActivity_setWindowFlags(ANativeActivity* activity,
uint32_t addFlags, uint32_t removeFlags); uint32_t addFlags, uint32_t removeFlags);
@@ -247,6 +263,12 @@ enum {
ANATIVEACTIVITY_SHOW_SOFT_INPUT_FORCED = 0x0002, ANATIVEACTIVITY_SHOW_SOFT_INPUT_FORCED = 0x0002,
}; };
/**
* Show the IME while in the given activity. Calls InputMethodManager.showSoftInput()
* for the given activity. Note that this method can be called from
* *any* thread; it will send a message to the main thread of the process
* where the Java finish call will take place.
*/
void ANativeActivity_showSoftInput(ANativeActivity* activity, uint32_t flags); void ANativeActivity_showSoftInput(ANativeActivity* activity, uint32_t flags);
/** /**
@@ -258,6 +280,12 @@ enum {
ANATIVEACTIVITY_HIDE_SOFT_INPUT_NOT_ALWAYS = 0x0002, ANATIVEACTIVITY_HIDE_SOFT_INPUT_NOT_ALWAYS = 0x0002,
}; };
/**
* Hide the IME while in the given activity. Calls InputMethodManager.hideSoftInput()
* for the given activity. Note that this method can be called from
* *any* thread; it will send a message to the main thread of the process
* where the Java finish call will take place.
*/
void ANativeActivity_hideSoftInput(ANativeActivity* activity, uint32_t flags); void ANativeActivity_hideSoftInput(ANativeActivity* activity, uint32_t flags);
#ifdef __cplusplus #ifdef __cplusplus