summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2010-08-04 11:12:40 -0700
committerDianne Hackborn <hackbod@google.com>2010-08-11 00:29:59 -0700
commit08d5b8fad8d46ccb64db2fdcb4d66972ec87bf48 (patch)
tree7e2e67603ec8a2ca164548301b65a2b733df76a0 /core
parent091c5238a00ca51dc69b8b09459e6ac88e1eb077 (diff)
downloadframeworks_base-08d5b8fad8d46ccb64db2fdcb4d66972ec87bf48.zip
frameworks_base-08d5b8fad8d46ccb64db2fdcb4d66972ec87bf48.tar.gz
frameworks_base-08d5b8fad8d46ccb64db2fdcb4d66972ec87bf48.tar.bz2
More native work.
Implement save/restore of state, and add native APIs for configuration information. Change-Id: I2a3ddc2ba605db58d7c8b2b31b9215fb323f90b5
Diffstat (limited to 'core')
-rw-r--r--core/java/android/app/NativeActivity.java41
-rw-r--r--core/java/android/content/res/Resources.java2
-rw-r--r--core/java/com/android/internal/app/PlatLogoActivity.java34
-rw-r--r--core/jni/Android.mk3
-rw-r--r--core/jni/AndroidRuntime.cpp2
-rw-r--r--core/jni/android_app_NativeActivity.cpp50
-rw-r--r--core/jni/android_content_res_Configuration.cpp118
-rw-r--r--core/res/AndroidManifest.xml3
-rw-r--r--core/res/res/drawable-nodpi/platlogo.jpgbin0 -> 102076 bytes
9 files changed, 240 insertions, 13 deletions
diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java
index eaf0675..4dc88b3 100644
--- a/core/java/android/app/NativeActivity.java
+++ b/core/java/android/app/NativeActivity.java
@@ -10,6 +10,7 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
+import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Bundle;
@@ -32,12 +33,27 @@ import java.lang.ref.WeakReference;
/**
* Convenience for implementing an activity that will be implemented
- * purely in native code. That is, a game (or game-like thing).
+ * purely in native code. That is, a game (or game-like thing). There
+ * is no need to derive from this class; you can simply declare it in your
+ * manifest, and use the NDK APIs from there.
+ *
+ * <p>A typical manifest would look like:
+ *
+ * {@sample development/ndk/platforms/android-9/samples/native-activity/AndroidManifest.xml
+ * manifest}
+ *
+ * <p>A very simple example of native code that is run by NativeActivity
+ * follows. This reads input events from the user and uses OpenGLES to
+ * draw into the native activity's window.
+ *
+ * {@sample development/ndk/platforms/android-9/samples/native-activity/jni/main.c all}
*/
public class NativeActivity extends Activity implements SurfaceHolder.Callback2,
InputQueue.Callback, OnGlobalLayoutListener {
public static final String META_DATA_LIB_NAME = "android.app.lib_name";
+ public static final String KEY_NATIVE_SAVED_STATE = "android:native_state";
+
private NativeContentView mNativeContentView;
private InputMethodManager mIMM;
private InputMethodCallback mInputMethodCallback;
@@ -59,14 +75,15 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2,
private native int loadNativeCode(String path, MessageQueue queue,
String internalDataPath, String externalDataPath, int sdkVersion,
- AssetManager assetMgr);
+ AssetManager assetMgr, byte[] savedState);
private native void unloadNativeCode(int handle);
private native void onStartNative(int handle);
private native void onResumeNative(int handle);
- private native void onSaveInstanceStateNative(int handle);
+ private native byte[] onSaveInstanceStateNative(int handle);
private native void onPauseNative(int handle);
private native void onStopNative(int handle);
+ private native void onConfigurationChangedNative(int handle);
private native void onLowMemoryNative(int handle);
private native void onWindowFocusChangedNative(int handle, boolean focused);
private native void onSurfaceCreatedNative(int handle, Surface surface);
@@ -165,10 +182,13 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2,
throw new IllegalArgumentException("Unable to find native library: " + libname);
}
+ byte[] nativeSavedState = savedInstanceState != null
+ ? savedInstanceState.getByteArray(KEY_NATIVE_SAVED_STATE) : null;
+
mNativeHandle = loadNativeCode(path, Looper.myQueue(),
getFilesDir().toString(),
Environment.getExternalStorageAppFilesDirectory(ai.packageName).toString(),
- Build.VERSION.SDK_INT, getAssets());
+ Build.VERSION.SDK_INT, getAssets(), nativeSavedState);
if (mNativeHandle == 0) {
throw new IllegalArgumentException("Unable to load native library: " + path);
@@ -206,7 +226,10 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2,
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
- onSaveInstanceStateNative(mNativeHandle);
+ byte[] state = onSaveInstanceStateNative(mNativeHandle);
+ if (state != null) {
+ outState.putByteArray(KEY_NATIVE_SAVED_STATE, state);
+ }
}
@Override
@@ -222,6 +245,14 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2,
}
@Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ if (!mDestroyed) {
+ onConfigurationChangedNative(mNativeHandle);
+ }
+ }
+
+ @Override
public void onLowMemory() {
super.onLowMemory();
if (!mDestroyed) {
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 0608cc0..9bb3b75 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1288,7 +1288,7 @@ public class Resources {
height = mMetrics.widthPixels;
}
int keyboardHidden = mConfiguration.keyboardHidden;
- if (keyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO
+ if (keyboardHidden == Configuration.KEYBOARDHIDDEN_NO
&& mConfiguration.hardKeyboardHidden
== Configuration.HARDKEYBOARDHIDDEN_YES) {
keyboardHidden = Configuration.KEYBOARDHIDDEN_SOFT;
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
new file mode 100644
index 0000000..ce5959d
--- /dev/null
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.ImageView;
+
+public class PlatLogoActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ ImageView content = new ImageView(this);
+ content.setImageResource(com.android.internal.R.drawable.platlogo);
+ content.setScaleType(ImageView.ScaleType.FIT_CENTER);
+
+ setContentView(content);
+ }
+}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 5c37c7c..efdc399 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -135,7 +135,8 @@ LOCAL_SRC_FILES:= \
android_backup_BackupDataOutput.cpp \
android_backup_FileBackupHelperBase.cpp \
android_backup_BackupHelperDispatcher.cpp \
- android_content_res_ObbScanner.cpp
+ android_content_res_ObbScanner.cpp \
+ android_content_res_Configuration.cpp
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 7fe56a7..62ca2ef 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -167,6 +167,7 @@ extern int register_android_view_InputQueue(JNIEnv* env);
extern int register_android_view_KeyEvent(JNIEnv* env);
extern int register_android_view_MotionEvent(JNIEnv* env);
extern int register_android_content_res_ObbScanner(JNIEnv* env);
+extern int register_android_content_res_Configuration(JNIEnv* env);
static AndroidRuntime* gCurRuntime = NULL;
@@ -1340,6 +1341,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_view_MotionEvent),
REG_JNI(register_android_content_res_ObbScanner),
+ REG_JNI(register_android_content_res_Configuration),
};
/*
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index 1feb3b3..0932473 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -600,7 +600,7 @@ static bool mainWorkCallback(int fd, int events, void* data) {
static jint
loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jobject messageQueue,
jstring internalDataDir, jstring externalDataDir, int sdkVersion,
- jobject jAssetMgr)
+ jobject jAssetMgr, jbyteArray savedState)
{
LOG_TRACE("loadNativeCode_native");
@@ -666,7 +666,18 @@ loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jobject messageQ
code->assetManager = assetManagerForJavaObject(env, jAssetMgr);
- code->createActivityFunc(code, NULL, 0);
+ jbyte* rawSavedState = NULL;
+ jsize rawSavedSize = 0;
+ if (savedState != NULL) {
+ rawSavedState = env->GetByteArrayElements(savedState, NULL);
+ rawSavedSize = env->GetArrayLength(savedState);
+ }
+
+ code->createActivityFunc(code, rawSavedState, rawSavedSize);
+
+ if (rawSavedState != NULL) {
+ env->ReleaseByteArrayElements(savedState, rawSavedState, 0);
+ }
}
return (jint)code;
@@ -706,17 +717,31 @@ onResume_native(JNIEnv* env, jobject clazz, jint handle)
}
}
-static void
+static jbyteArray
onSaveInstanceState_native(JNIEnv* env, jobject clazz, jint handle)
{
LOG_TRACE("onSaveInstanceState_native");
+
+ jbyteArray array = NULL;
+
if (handle != 0) {
NativeCode* code = (NativeCode*)handle;
if (code->callbacks.onSaveInstanceState != NULL) {
size_t len = 0;
- code->callbacks.onSaveInstanceState(code, &len);
+ jbyte* state = (jbyte*)code->callbacks.onSaveInstanceState(code, &len);
+ if (len > 0) {
+ array = env->NewByteArray(len);
+ if (array != NULL) {
+ env->SetByteArrayRegion(array, 0, len, state);
+ }
+ }
+ if (state != NULL) {
+ free(state);
+ }
}
}
+
+ return array;
}
static void
@@ -744,6 +769,18 @@ onStop_native(JNIEnv* env, jobject clazz, jint handle)
}
static void
+onConfigurationChanged_native(JNIEnv* env, jobject clazz, jint handle)
+{
+ LOG_TRACE("onConfigurationChanged_native");
+ if (handle != 0) {
+ NativeCode* code = (NativeCode*)handle;
+ if (code->callbacks.onConfigurationChanged != NULL) {
+ code->callbacks.onConfigurationChanged(code);
+ }
+ }
+}
+
+static void
onLowMemory_native(JNIEnv* env, jobject clazz, jint handle)
{
LOG_TRACE("onLowMemory_native");
@@ -934,14 +971,15 @@ finishPreDispatchKeyEvent_native(JNIEnv* env, jobject clazz, jint handle,
}
static const JNINativeMethod g_methods[] = {
- { "loadNativeCode", "(Ljava/lang/String;Landroid/os/MessageQueue;Ljava/lang/String;Ljava/lang/String;ILandroid/content/res/AssetManager;)I",
+ { "loadNativeCode", "(Ljava/lang/String;Landroid/os/MessageQueue;Ljava/lang/String;Ljava/lang/String;ILandroid/content/res/AssetManager;[B)I",
(void*)loadNativeCode_native },
{ "unloadNativeCode", "(I)V", (void*)unloadNativeCode_native },
{ "onStartNative", "(I)V", (void*)onStart_native },
{ "onResumeNative", "(I)V", (void*)onResume_native },
- { "onSaveInstanceStateNative", "(I)V", (void*)onSaveInstanceState_native },
+ { "onSaveInstanceStateNative", "(I)[B", (void*)onSaveInstanceState_native },
{ "onPauseNative", "(I)V", (void*)onPause_native },
{ "onStopNative", "(I)V", (void*)onStop_native },
+ { "onConfigurationChangedNative", "(I)V", (void*)onConfigurationChanged_native },
{ "onLowMemoryNative", "(I)V", (void*)onLowMemory_native },
{ "onWindowFocusChangedNative", "(IZ)V", (void*)onWindowFocusChanged_native },
{ "onSurfaceCreatedNative", "(ILandroid/view/Surface;)V", (void*)onSurfaceCreated_native },
diff --git a/core/jni/android_content_res_Configuration.cpp b/core/jni/android_content_res_Configuration.cpp
new file mode 100644
index 0000000..28a43ab
--- /dev/null
+++ b/core/jni/android_content_res_Configuration.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Configuration"
+
+#include <utils/Log.h>
+#include "utils/misc.h"
+
+#include "jni.h"
+#include <android_runtime/android_content_res_Configuration.h>
+#include "android_runtime/AndroidRuntime.h"
+
+namespace android {
+
+static struct {
+ jclass clazz;
+
+ jfieldID mcc;
+ jfieldID mnc;
+ jfieldID locale;
+ jfieldID screenLayout;
+ jfieldID touchscreen;
+ jfieldID keyboard;
+ jfieldID keyboardHidden;
+ jfieldID hardKeyboardHidden;
+ jfieldID navigation;
+ jfieldID navigationHidden;
+ jfieldID orientation;
+ jfieldID uiMode;
+} gConfigurationClassInfo;
+
+void android_Configuration_getFromJava(
+ JNIEnv* env, jobject clazz, struct AConfiguration* out) {
+ out->mcc = env->GetIntField(clazz, gConfigurationClassInfo.mcc);
+ out->mnc = env->GetIntField(clazz, gConfigurationClassInfo.mnc);
+ out->screenLayout = env->GetIntField(clazz, gConfigurationClassInfo.screenLayout);
+ out->touchscreen = env->GetIntField(clazz, gConfigurationClassInfo.touchscreen);
+ out->keyboard = env->GetIntField(clazz, gConfigurationClassInfo.keyboard);
+ out->navigation = env->GetIntField(clazz, gConfigurationClassInfo.navigation);
+
+ out->inputFlags = env->GetIntField(clazz, gConfigurationClassInfo.keyboardHidden);
+ int hardKeyboardHidden = env->GetIntField(clazz, gConfigurationClassInfo.hardKeyboardHidden);
+ if (out->inputFlags == ACONFIGURATION_KEYSHIDDEN_NO
+ && hardKeyboardHidden == 2) {
+ out->inputFlags = ACONFIGURATION_KEYSHIDDEN_SOFT;
+ }
+ out->inputFlags |= env->GetIntField(clazz, gConfigurationClassInfo.navigationHidden)
+ << ResTable_config::SHIFT_NAVHIDDEN;
+
+ out->orientation = env->GetIntField(clazz, gConfigurationClassInfo.orientation);
+ out->uiMode = env->GetIntField(clazz, gConfigurationClassInfo.uiMode);
+}
+
+/*
+ * JNI registration.
+ */
+static JNINativeMethod gMethods[] = {
+ /* name, signature, funcPtr */
+ //{ "getObbInfo_native", "(Ljava/lang/String;Landroid/content/res/ObbInfo;)Z",
+ // (void*) android_content_res_ObbScanner_getObbInfo },
+};
+
+#define FIND_CLASS(var, className) \
+ var = env->FindClass(className); \
+ LOG_FATAL_IF(! var, "Unable to find class " className); \
+ var = jclass(env->NewGlobalRef(var));
+
+#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
+ var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
+ LOG_FATAL_IF(! var, "Unable to find field " fieldName);
+
+int register_android_content_res_Configuration(JNIEnv* env)
+{
+ FIND_CLASS(gConfigurationClassInfo.clazz, "android/content/res/Configuration");
+
+ GET_FIELD_ID(gConfigurationClassInfo.mcc, gConfigurationClassInfo.clazz,
+ "mcc", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.mnc, gConfigurationClassInfo.clazz,
+ "mnc", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.locale, gConfigurationClassInfo.clazz,
+ "locale", "Ljava/util/Locale;");
+ GET_FIELD_ID(gConfigurationClassInfo.screenLayout, gConfigurationClassInfo.clazz,
+ "screenLayout", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.touchscreen, gConfigurationClassInfo.clazz,
+ "touchscreen", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.keyboard, gConfigurationClassInfo.clazz,
+ "keyboard", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.keyboardHidden, gConfigurationClassInfo.clazz,
+ "keyboardHidden", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.hardKeyboardHidden, gConfigurationClassInfo.clazz,
+ "hardKeyboardHidden", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.navigation, gConfigurationClassInfo.clazz,
+ "navigation", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.navigationHidden, gConfigurationClassInfo.clazz,
+ "navigationHidden", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.orientation, gConfigurationClassInfo.clazz,
+ "orientation", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.uiMode, gConfigurationClassInfo.clazz,
+ "uiMode", "I");
+
+ return AndroidRuntime::registerNativeMethods(env, "android/content/res/Configuration", gMethods,
+ NELEM(gMethods));
+}
+
+}; // namespace android
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 82f822f..19b30cc 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1275,6 +1275,9 @@
android:finishOnCloseSystemDialogs="true"
android:excludeFromRecents="true">
</activity>
+ <activity android:name="com.android.internal.app.PlatLogoActivity"
+ android:theme="@style/Theme.NoTitleBar.Fullscreen">
+ </activity>
<activity android:name="com.android.internal.app.DisableCarModeActivity"
android:theme="@style/Theme.NoDisplay"
android:excludeFromRecents="true">
diff --git a/core/res/res/drawable-nodpi/platlogo.jpg b/core/res/res/drawable-nodpi/platlogo.jpg
new file mode 100644
index 0000000..0e7780c
--- /dev/null
+++ b/core/res/res/drawable-nodpi/platlogo.jpg
Binary files differ