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