NativeActivity.java revision a95e4cb62f3642cb190d032dbf7dc40d9ecc6973
169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornpackage android.app; 269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornimport dalvik.system.PathClassLoader; 469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornimport android.content.pm.ActivityInfo; 669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornimport android.content.pm.ApplicationInfo; 769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornimport android.content.pm.PackageManager; 869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornimport android.os.Bundle; 9a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackbornimport android.view.InputChannel; 10a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackbornimport android.view.InputConsumer; 1174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornimport android.view.SurfaceHolder; 1269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 1369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornimport java.io.File; 1469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 1569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn/** 1669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn * Convenience for implementing an activity that will be implemented 1769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn * purely in native code. That is, a game (or game-like thing). 1869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn */ 19a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackbornpublic class NativeActivity extends Activity implements SurfaceHolder.Callback, 20a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn InputConsumer.Callback { 2169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn public static final String META_DATA_LIB_NAME = "android.app.lib_name"; 2269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 2369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn private int mNativeHandle; 2469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 2569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn private native int loadNativeCode(String path); 2669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn private native void unloadNativeCode(int handle); 2769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 2869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn private native void onStartNative(int handle); 2969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn private native void onResumeNative(int handle); 3069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn private native void onSaveInstanceStateNative(int handle); 3169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn private native void onPauseNative(int handle); 3269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn private native void onStopNative(int handle); 3369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn private native void onLowMemoryNative(int handle); 3469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn private native void onWindowFocusChangedNative(int handle, boolean focused); 3574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn private native void onSurfaceCreatedNative(int handle, SurfaceHolder holder); 3674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn private native void onSurfaceChangedNative(int handle, SurfaceHolder holder, 3774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn int format, int width, int height); 3874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn private native void onSurfaceDestroyedNative(int handle, SurfaceHolder holder); 39a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn private native void onInputChannelCreatedNative(int handle, InputChannel channel); 40a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn private native void onInputChannelDestroyedNative(int handle, InputChannel channel); 4169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 4269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn @Override 4369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn protected void onCreate(Bundle savedInstanceState) { 4469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn String libname = "main"; 4569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn ActivityInfo ai; 4669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 4774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn getWindow().takeSurface(this); 48a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn getWindow().takeInputChannel(this); 4974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn 5069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn try { 5169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn ai = getPackageManager().getActivityInfo( 5269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn getIntent().getComponent(), PackageManager.GET_META_DATA); 5369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn if (ai.metaData != null) { 5469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn String ln = ai.metaData.getString(META_DATA_LIB_NAME); 5569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn if (ln != null) libname = ln; 5669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn } 5769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn } catch (PackageManager.NameNotFoundException e) { 5869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn throw new RuntimeException("Error getting activity info", e); 5969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn } 6069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 6169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn String path = null; 6269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 6369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn if ((ai.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) == 0) { 6469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn // If the application does not have (Java) code, then no ClassLoader 6569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn // has been set up for it. We will need to do our own search for 6669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn // the native code. 6769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn path = ai.applicationInfo.dataDir + "/lib/" + System.mapLibraryName(libname); 6869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn if (!(new File(path)).exists()) { 6969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn path = null; 7069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn } 7169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn } 7269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 7369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn if (path == null) { 7469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn path = ((PathClassLoader)getClassLoader()).findLibrary(libname); 7569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn } 7669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 7769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn if (path == null) { 7869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn throw new IllegalArgumentException("Unable to find native library: " + libname); 7969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn } 8069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 8169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn mNativeHandle = loadNativeCode(path); 8269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn if (mNativeHandle == 0) { 8369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn throw new IllegalArgumentException("Unable to load native library: " + path); 8469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn } 8569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn super.onCreate(savedInstanceState); 8669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn } 8769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 8869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn @Override 8969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn protected void onDestroy() { 9069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn unloadNativeCode(mNativeHandle); 9169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn super.onDestroy(); 9269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn } 9369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 9469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn @Override 9569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn protected void onPause() { 9669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn super.onPause(); 9769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn onPauseNative(mNativeHandle); 9869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn } 9969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 10069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn @Override 10169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn protected void onResume() { 10269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn super.onResume(); 10369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn onResumeNative(mNativeHandle); 10469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn } 10569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 10669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn @Override 10769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn protected void onSaveInstanceState(Bundle outState) { 10869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn super.onSaveInstanceState(outState); 10969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn onSaveInstanceStateNative(mNativeHandle); 11069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn } 11169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 11269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn @Override 11369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn protected void onStart() { 11469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn super.onStart(); 11569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn onStartNative(mNativeHandle); 11669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn } 11769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 11869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn @Override 11969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn protected void onStop() { 12069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn super.onStop(); 12169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn onStopNative(mNativeHandle); 12269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn } 12369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 12469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn @Override 12574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn public void onLowMemory() { 12674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn super.onLowMemory(); 12774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn onLowMemoryNative(mNativeHandle); 12874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn } 12974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn 13074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn @Override 13169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn public void onWindowFocusChanged(boolean hasFocus) { 13269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn super.onWindowFocusChanged(hasFocus); 13369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn onWindowFocusChangedNative(mNativeHandle, hasFocus); 13469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn } 13574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn 13674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn public void surfaceCreated(SurfaceHolder holder) { 13774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn onSurfaceCreatedNative(mNativeHandle, holder); 13874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn } 13974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn 14074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 14174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn onSurfaceChangedNative(mNativeHandle, holder, format, width, height); 14274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn } 14374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn 14474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn public void surfaceDestroyed(SurfaceHolder holder) { 14574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn onSurfaceDestroyedNative(mNativeHandle, holder); 14674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn } 147a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn 148a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn public void onInputConsumerCreated(InputConsumer consumer) { 149a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn onInputChannelCreatedNative(mNativeHandle, consumer.getInputChannel()); 150a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn } 151a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn 152a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn public void onInputConsumerDestroyed(InputConsumer consumer) { 153a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn onInputChannelDestroyedNative(mNativeHandle, consumer.getInputChannel()); 154a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn } 15569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn} 156