Merge "Add support for the PointerLocation overlay." into gingerbread
diff --git a/Android.mk b/Android.mk
index b6f25047..b1f43f8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -121,6 +121,7 @@
core/java/android/os/storage/IMountService.aidl \
core/java/android/os/storage/IMountServiceListener.aidl \
core/java/android/os/storage/IMountShutdownObserver.aidl \
+ core/java/android/os/storage/IObbActionListener.aidl \
core/java/android/os/INetworkManagementService.aidl \
core/java/android/os/INetStatService.aidl \
core/java/android/os/IPermissionController.aidl \
diff --git a/api/current.xml b/api/current.xml
index 841aa21..65a8a8e 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -26460,6 +26460,17 @@
<parameter name="holder" type="android.view.SurfaceHolder">
</parameter>
</method>
+<field name="KEY_NATIVE_SAVED_STATE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android:native_state""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="META_DATA_LIB_NAME"
type="java.lang.String"
transient="false"
@@ -129520,6 +129531,8 @@
>
<parameter name="filename" type="java.lang.String">
</parameter>
+<exception name="IllegalArgumentException" type="java.lang.IllegalArgumentException">
+</exception>
</method>
<method name="mountObb"
return="boolean"
@@ -129550,6 +129563,8 @@
</parameter>
<parameter name="force" type="boolean">
</parameter>
+<exception name="IllegalArgumentException" type="java.lang.IllegalArgumentException">
+</exception>
</method>
</class>
</package>
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.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 @@
/**
* 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 @@
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 @@
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 @@
@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 @@
}
@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 @@
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/android/os/storage/IMountService.aidl b/core/java/android/os/storage/IMountService.aidl
index ca7efe7..5c69214 100644
--- a/core/java/android/os/storage/IMountService.aidl
+++ b/core/java/android/os/storage/IMountService.aidl
@@ -19,6 +19,7 @@
import android.os.storage.IMountServiceListener;
import android.os.storage.IMountShutdownObserver;
+import android.os.storage.IObbActionListener;
/** WARNING! Update IMountService.h and IMountService.cpp if you change this file.
* In particular, the ordering of the methods below must match the
@@ -156,14 +157,20 @@
/**
* Mounts an Opaque Binary Blob (OBB) with the specified decryption key and only
* allows the calling process's UID access to the contents.
+ *
+ * MountService will call back to the supplied IObbActionListener to inform
+ * it of the terminal state of the call.
*/
- int mountObb(String filename, String key);
+ void mountObb(String filename, String key, IObbActionListener token);
/**
* Unmounts an Opaque Binary Blob (OBB). When the force flag is specified, any
* program using it will be forcibly killed to unmount the image.
+ *
+ * MountService will call back to the supplied IObbActionListener to inform
+ * it of the terminal state of the call.
*/
- int unmountObb(String filename, boolean force);
+ void unmountObb(String filename, boolean force, IObbActionListener token);
/**
* Checks whether the specified Opaque Binary Blob (OBB) is mounted somewhere.
diff --git a/core/java/android/os/storage/IObbActionListener.aidl b/core/java/android/os/storage/IObbActionListener.aidl
new file mode 100644
index 0000000..78d7a9e
--- /dev/null
+++ b/core/java/android/os/storage/IObbActionListener.aidl
@@ -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 android.os.storage;
+
+/**
+ * Callback class for receiving events from MountService about
+ * Opaque Binary Blobs (OBBs).
+ *
+ * @hide - Applications should use android.os.storage.StorageManager
+ * to interact with OBBs.
+ */
+interface IObbActionListener {
+ /**
+ * Return from an OBB action result.
+ *
+ * @param filename the path to the OBB the operation was performed on
+ * @param returnCode status of the operation
+ */
+ void onObbResult(String filename, String status);
+}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 96bf2d5..cb1794f 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -16,28 +16,14 @@
package android.os.storage;
-import android.content.Context;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Looper;
-import android.os.Parcelable;
-import android.os.ParcelFileDescriptor;
-import android.os.Process;
-import android.os.RemoteException;
import android.os.Handler;
+import android.os.Looper;
import android.os.Message;
+import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.storage.IMountService;
-import android.os.storage.IMountServiceListener;
import android.util.Log;
-import android.util.SparseArray;
-import java.io.FileDescriptor;
-import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
/**
* StorageManager is the interface to the systems storage service.
@@ -87,6 +73,17 @@
}
/**
+ * Binder listener for OBB action results.
+ */
+ private final ObbActionBinderListener mObbActionListener = new ObbActionBinderListener();
+ private class ObbActionBinderListener extends IObbActionListener.Stub {
+ @Override
+ public void onObbResult(String filename, String status) throws RemoteException {
+ Log.i(TAG, "filename = " + filename + ", result = " + status);
+ }
+ }
+
+ /**
* Private base class for messages sent between the callback thread
* and the target looper handler.
*/
@@ -299,12 +296,23 @@
}
/**
- * Mount an OBB file.
+ * Mount an Opaque Binary Blob (OBB) file. If a <code>key</code> is
+ * specified, it is supplied to the mounting process to be used in any
+ * encryption used in the OBB.
+ * <p>
+ * <em>Note:</em> you can only mount OBB files for which the OBB tag on the
+ * file matches a package ID that is owned by the calling program's UID.
+ * That is, shared UID applications can obtain access to any other
+ * application's OBB that shares its UID.
+ *
+ * @param filename the path to the OBB file
+ * @param key decryption key
+ * @return whether the mount call was successfully queued or not
*/
public boolean mountObb(String filename, String key) {
try {
- return mMountService.mountObb(filename, key)
- == StorageResultCode.OperationSucceeded;
+ mMountService.mountObb(filename, key, mObbActionListener);
+ return true;
} catch (RemoteException e) {
Log.e(TAG, "Failed to mount OBB", e);
}
@@ -313,12 +321,24 @@
}
/**
- * Mount an OBB file.
+ * Unmount an Opaque Binary Blob (OBB) file. If the <code>force</code> flag
+ * is true, it will kill any application needed to unmount the given OBB.
+ * <p>
+ * <em>Note:</em> you can only mount OBB files for which the OBB tag on the
+ * file matches a package ID that is owned by the calling program's UID.
+ * That is, shared UID applications can obtain access to any other
+ * application's OBB that shares its UID.
+ *
+ * @param filename path to the OBB file
+ * @param force whether to kill any programs using this in order to unmount
+ * it
+ * @return whether the unmount call was successfully queued or not
+ * @throws IllegalArgumentException when OBB is not already mounted
*/
- public boolean unmountObb(String filename, boolean force) {
+ public boolean unmountObb(String filename, boolean force) throws IllegalArgumentException {
try {
- return mMountService.unmountObb(filename, force)
- == StorageResultCode.OperationSucceeded;
+ mMountService.unmountObb(filename, force, mObbActionListener);
+ return true;
} catch (RemoteException e) {
Log.e(TAG, "Failed to mount OBB", e);
}
@@ -326,7 +346,13 @@
return false;
}
- public boolean isObbMounted(String filename) {
+ /**
+ * Check whether an Opaque Binary Blob (OBB) is mounted or not.
+ *
+ * @param filename path to OBB image
+ * @return true if OBB is mounted; false if not mounted or on error
+ */
+ public boolean isObbMounted(String filename) throws IllegalArgumentException {
try {
return mMountService.isObbMounted(filename);
} catch (RemoteException e) {
@@ -337,13 +363,21 @@
}
/**
- * Check the mounted path of an OBB file.
+ * Check the mounted path of an Opaque Binary Blob (OBB) file. This will
+ * give you the path to where you can obtain access to the internals of the
+ * OBB.
+ *
+ * @param filename path to OBB image
+ * @return absolute path to mounted OBB image data or <code>null</code> if
+ * not mounted or exception encountered trying to read status
*/
public String getMountedObbPath(String filename) {
try {
return mMountService.getMountedObbPath(filename);
} catch (RemoteException e) {
Log.e(TAG, "Failed to find mounted path for OBB", e);
+ } catch (IllegalArgumentException e) {
+ Log.d(TAG, "Couldn't read OBB file", e);
}
return null;
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index ff34f4a..0999598 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -312,7 +312,7 @@
* MotionEvent has no getRawX(int) method; simulate it pending future API approval.
*/
private static float getRawX(MotionEvent event, int pointerIndex) {
- float offset = event.getX() - event.getRawX();
+ float offset = event.getRawX() - event.getX();
return event.getX(pointerIndex) + offset;
}
@@ -320,7 +320,7 @@
* MotionEvent has no getRawY(int) method; simulate it pending future API approval.
*/
private static float getRawY(MotionEvent event, int pointerIndex) {
- float offset = event.getY() - event.getRawY();
+ float offset = event.getRawY() - event.getY();
return event.getY(pointerIndex) + offset;
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 8007710..b8623e7 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1358,14 +1358,14 @@
* Width as measured during measure pass.
* {@hide}
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "measurement")
protected int mMeasuredWidth;
/**
* Height as measured during measure pass.
* {@hide}
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "measurement")
protected int mMeasuredHeight;
/**
@@ -1575,28 +1575,28 @@
* to the left edge of this view.
* {@hide}
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
protected int mLeft;
/**
* The distance in pixels from the left edge of this view's parent
* to the right edge of this view.
* {@hide}
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
protected int mRight;
/**
* The distance in pixels from the top edge of this view's parent
* to the top edge of this view.
* {@hide}
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
protected int mTop;
/**
* The distance in pixels from the top edge of this view's parent
* to the bottom edge of this view.
* {@hide}
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
protected int mBottom;
/**
@@ -1604,14 +1604,14 @@
* horizontally.
* {@hide}
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "scrolling")
protected int mScrollX;
/**
* The offset, in pixels, by which the content of this view is scrolled
* vertically.
* {@hide}
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "scrolling")
protected int mScrollY;
/**
@@ -1619,28 +1619,28 @@
* left edge of this view and the left edge of its content.
* {@hide}
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "padding")
protected int mPaddingLeft;
/**
* The right padding in pixels, that is the distance in pixels between the
* right edge of this view and the right edge of its content.
* {@hide}
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "padding")
protected int mPaddingRight;
/**
* The top padding in pixels, that is the distance in pixels between the
* top edge of this view and the top edge of its content.
* {@hide}
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "padding")
protected int mPaddingTop;
/**
* The bottom padding in pixels, that is the distance in pixels between the
* bottom edge of this view and the bottom edge of its content.
* {@hide}
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "padding")
protected int mPaddingBottom;
/**
@@ -1651,13 +1651,13 @@
/**
* Cache the paddingRight set by the user to append to the scrollbar's size.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "padding")
int mUserPaddingRight;
/**
* Cache the paddingBottom set by the user to append to the scrollbar's size.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "padding")
int mUserPaddingBottom;
/**
@@ -1764,14 +1764,14 @@
* The minimum height of the view. We'll try our best to have the height
* of this view to at least this amount.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "measurement")
private int mMinHeight;
/**
* The minimum width of the view. We'll try our best to have the width
* of this view to at least this amount.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "measurement")
private int mMinWidth;
/**
@@ -2602,7 +2602,7 @@
*
* @return True if this view has or contains focus, false otherwise.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "focus")
public boolean hasFocus() {
return (mPrivateFlags & FOCUSED) != 0;
}
@@ -2780,7 +2780,7 @@
*
* @return True if this view has focus, false otherwise.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "focus")
public boolean isFocused() {
return (mPrivateFlags & FOCUSED) != 0;
}
@@ -3191,7 +3191,7 @@
*
* @return true if this view has nothing to draw, false otherwise
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "drawing")
public boolean willNotDraw() {
return (mViewFlags & DRAW_MASK) == WILL_NOT_DRAW;
}
@@ -3214,7 +3214,7 @@
*
* @return true if this view does not cache its drawing, false otherwise
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "drawing")
public boolean willNotCacheDrawing() {
return (mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING;
}
@@ -3357,7 +3357,7 @@
* @return True if this view can take focus, or false otherwise.
* @attr ref android.R.styleable#View_focusable
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "focus")
public final boolean isFocusable() {
return FOCUSABLE == (mViewFlags & FOCUSABLE_MASK);
}
@@ -4666,7 +4666,7 @@
*
* @return The width of your view, in pixels.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
public final int getWidth() {
return mRight - mLeft;
}
@@ -4676,7 +4676,7 @@
*
* @return The height of your view, in pixels.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
public final int getHeight() {
return mBottom - mTop;
}
@@ -5162,7 +5162,7 @@
*
* @return True if this View is guaranteed to be fully opaque, false otherwise.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "drawing")
public boolean isOpaque() {
return (mPrivateFlags & OPAQUE_MASK) == OPAQUE_MASK;
}
@@ -6247,7 +6247,7 @@
* @see #setDrawingCacheEnabled(boolean)
* @see #getDrawingCache()
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "drawing")
public boolean isDrawingCacheEnabled() {
return (mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED;
}
@@ -8116,7 +8116,7 @@
* @return the offset of the baseline within the widget's bounds or -1
* if baseline alignment is not supported
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
public int getBaseline() {
return -1;
}
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 09939a6..2ca08ea 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -255,6 +255,14 @@
* @see #deepExport()
*/
String prefix() default "";
+
+ /**
+ * Specifies the category the property falls into, such as measurement,
+ * layout, drawing, etc.
+ *
+ * @return the category as String
+ */
+ String category() default "";
}
/**
@@ -1368,9 +1376,12 @@
// TODO: This should happen on the UI thread
Object methodValue = method.invoke(view, (Object[]) null);
final Class<?> returnType = method.getReturnType();
+ final ExportedProperty property = sAnnotations.get(method);
+ String categoryPrefix =
+ property.category().length() != 0 ? property.category() + ":" : "";
if (returnType == int.class) {
- final ExportedProperty property = sAnnotations.get(method);
+
if (property.resolveId() && context != null) {
final int id = (Integer) methodValue;
methodValue = resolveId(context, id);
@@ -1378,7 +1389,8 @@
final FlagToString[] flagsMapping = property.flagMapping();
if (flagsMapping.length > 0) {
final int intValue = (Integer) methodValue;
- final String valuePrefix = prefix + method.getName() + '_';
+ final String valuePrefix =
+ categoryPrefix + prefix + method.getName() + '_';
exportUnrolledFlags(out, flagsMapping, intValue, valuePrefix);
}
@@ -1402,21 +1414,22 @@
}
}
} else if (returnType == int[].class) {
- final ExportedProperty property = sAnnotations.get(method);
final int[] array = (int[]) methodValue;
- final String valuePrefix = prefix + method.getName() + '_';
+ final String valuePrefix = categoryPrefix + prefix + method.getName() + '_';
final String suffix = "()";
exportUnrolledArray(context, out, property, array, valuePrefix, suffix);
+
+ // Probably want to return here, same as for fields.
+ return;
} else if (!returnType.isPrimitive()) {
- final ExportedProperty property = sAnnotations.get(method);
if (property.deepExport()) {
dumpViewProperties(context, methodValue, out, prefix + property.prefix());
continue;
}
}
- writeEntry(out, prefix, method.getName(), "()", methodValue);
+ writeEntry(out, categoryPrefix + prefix, method.getName(), "()", methodValue);
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
@@ -1436,9 +1449,12 @@
try {
Object fieldValue = null;
final Class<?> type = field.getType();
+ final ExportedProperty property = sAnnotations.get(field);
+ String categoryPrefix =
+ property.category().length() != 0 ? property.category() + ":" : "";
if (type == int.class) {
- final ExportedProperty property = sAnnotations.get(field);
+
if (property.resolveId() && context != null) {
final int id = field.getInt(view);
fieldValue = resolveId(context, id);
@@ -1446,7 +1462,8 @@
final FlagToString[] flagsMapping = property.flagMapping();
if (flagsMapping.length > 0) {
final int intValue = field.getInt(view);
- final String valuePrefix = prefix + field.getName() + '_';
+ final String valuePrefix =
+ categoryPrefix + prefix + field.getName() + '_';
exportUnrolledFlags(out, flagsMapping, intValue, valuePrefix);
}
@@ -1468,9 +1485,8 @@
}
}
} else if (type == int[].class) {
- final ExportedProperty property = sAnnotations.get(field);
final int[] array = (int[]) field.get(view);
- final String valuePrefix = prefix + field.getName() + '_';
+ final String valuePrefix = categoryPrefix + prefix + field.getName() + '_';
final String suffix = "";
exportUnrolledArray(context, out, property, array, valuePrefix, suffix);
@@ -1478,10 +1494,9 @@
// We exit here!
return;
} else if (!type.isPrimitive()) {
- final ExportedProperty property = sAnnotations.get(field);
if (property.deepExport()) {
- dumpViewProperties(context, field.get(view), out,
- prefix + property.prefix());
+ dumpViewProperties(context, field.get(view), out, prefix
+ + property.prefix());
continue;
}
}
@@ -1490,7 +1505,7 @@
fieldValue = field.get(view);
}
- writeEntry(out, prefix, field.getName(), "", fieldValue);
+ writeEntry(out, categoryPrefix + prefix, field.getName(), "", fieldValue);
} catch (IllegalAccessException e) {
}
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index e7b6c50..7159929 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -363,7 +363,7 @@
* @return one of {@link #FOCUS_BEFORE_DESCENDANTS}, {@link #FOCUS_AFTER_DESCENDANTS},
* {@link #FOCUS_BLOCK_DESCENDANTS}.
*/
- @ViewDebug.ExportedProperty(mapping = {
+ @ViewDebug.ExportedProperty(category = "focus", mapping = {
@ViewDebug.IntToString(from = FOCUS_BEFORE_DESCENDANTS, to = "FOCUS_BEFORE_DESCENDANTS"),
@ViewDebug.IntToString(from = FOCUS_AFTER_DESCENDANTS, to = "FOCUS_AFTER_DESCENDANTS"),
@ViewDebug.IntToString(from = FOCUS_BLOCK_DESCENDANTS, to = "FOCUS_BLOCK_DESCENDANTS")
@@ -2764,7 +2764,7 @@
* @see #setChildrenDrawnWithCacheEnabled(boolean)
* @see View#setDrawingCacheEnabled(boolean)
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "drawing")
public boolean isAlwaysDrawnWithCacheEnabled() {
return (mGroupFlags & FLAG_ALWAYS_DRAWN_WITH_CACHE) == FLAG_ALWAYS_DRAWN_WITH_CACHE;
}
@@ -2799,7 +2799,7 @@
* @see #setAlwaysDrawnWithCacheEnabled(boolean)
* @see #setChildrenDrawnWithCacheEnabled(boolean)
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "drawing")
protected boolean isChildrenDrawnWithCacheEnabled() {
return (mGroupFlags & FLAG_CHILDREN_DRAWN_WITH_CACHE) == FLAG_CHILDREN_DRAWN_WITH_CACHE;
}
@@ -2831,7 +2831,7 @@
* @see #setChildrenDrawingOrderEnabled(boolean)
* @see #getChildDrawingOrder(int, int)
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "drawing")
protected boolean isChildrenDrawingOrderEnabled() {
return (mGroupFlags & FLAG_USE_CHILD_DRAWING_ORDER) == FLAG_USE_CHILD_DRAWING_ORDER;
}
@@ -2868,7 +2868,7 @@
* {@link #PERSISTENT_ANIMATION_CACHE}, {@link #PERSISTENT_SCROLLING_CACHE}
* and {@link #PERSISTENT_ALL_CACHES}
*/
- @ViewDebug.ExportedProperty(mapping = {
+ @ViewDebug.ExportedProperty(category = "drawing", mapping = {
@ViewDebug.IntToString(from = PERSISTENT_NO_CACHE, to = "NONE"),
@ViewDebug.IntToString(from = PERSISTENT_ALL_CACHES, to = "ANIMATION"),
@ViewDebug.IntToString(from = PERSISTENT_SCROLLING_CACHE, to = "SCROLLING"),
@@ -3501,7 +3501,7 @@
* constants FILL_PARENT (replaced by MATCH_PARENT ,
* in API Level 8) or WRAP_CONTENT. or an exact size.
*/
- @ViewDebug.ExportedProperty(mapping = {
+ @ViewDebug.ExportedProperty(category = "layout", mapping = {
@ViewDebug.IntToString(from = MATCH_PARENT, to = "MATCH_PARENT"),
@ViewDebug.IntToString(from = WRAP_CONTENT, to = "WRAP_CONTENT")
})
@@ -3512,7 +3512,7 @@
* constants FILL_PARENT (replaced by MATCH_PARENT ,
* in API Level 8) or WRAP_CONTENT. or an exact size.
*/
- @ViewDebug.ExportedProperty(mapping = {
+ @ViewDebug.ExportedProperty(category = "layout", mapping = {
@ViewDebug.IntToString(from = MATCH_PARENT, to = "MATCH_PARENT"),
@ViewDebug.IntToString(from = WRAP_CONTENT, to = "WRAP_CONTENT")
})
@@ -3637,25 +3637,25 @@
/**
* The left margin in pixels of the child.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
public int leftMargin;
/**
* The top margin in pixels of the child.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
public int topMargin;
/**
* The right margin in pixels of the child.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
public int rightMargin;
/**
* The bottom margin in pixels of the child.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
public int bottomMargin;
/**
diff --git a/core/java/android/webkit/WebViewDatabase.java b/core/java/android/webkit/WebViewDatabase.java
index b18419d..7acd9ba 100644
--- a/core/java/android/webkit/WebViewDatabase.java
+++ b/core/java/android/webkit/WebViewDatabase.java
@@ -727,6 +727,9 @@
}
long getCacheTotalSize() {
+ if (mCacheDatabase == null) {
+ return 0;
+ }
long size = 0;
Cursor cursor = null;
final String query = "SELECT SUM(contentlength) as sum FROM cache";
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 6cfeb68..c970ae6 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -3830,7 +3830,7 @@
* View type for this view, as returned by
* {@link android.widget.Adapter#getItemViewType(int) }
*/
- @ViewDebug.ExportedProperty(mapping = {
+ @ViewDebug.ExportedProperty(category = "list", mapping = {
@ViewDebug.IntToString(from = ITEM_VIEW_TYPE_IGNORE, to = "ITEM_VIEW_TYPE_IGNORE"),
@ViewDebug.IntToString(from = ITEM_VIEW_TYPE_HEADER_OR_FOOTER, to = "ITEM_VIEW_TYPE_HEADER_OR_FOOTER")
})
@@ -3842,7 +3842,7 @@
* been added to the list view and whether they should be treated as
* recycled views or not.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "list")
boolean recycledHeaderFooter;
/**
@@ -3853,7 +3853,7 @@
* view to be attached to the window rather than just attached to the
* parent.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "list")
boolean forceAdd;
public LayoutParams(Context c, AttributeSet attrs) {
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index fe6d91a..10a8729 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -56,7 +56,7 @@
/**
* The position of the first child displayed
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "scrolling")
int mFirstPosition = 0;
/**
@@ -141,7 +141,7 @@
* The position within the adapter's data set of the item to select
* during the next layout.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "list")
int mNextSelectedPosition = INVALID_POSITION;
/**
@@ -152,7 +152,7 @@
/**
* The position within the adapter's data set of the currently selected item.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "list")
int mSelectedPosition = INVALID_POSITION;
/**
@@ -168,7 +168,7 @@
/**
* The number of items in the current adapter.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "list")
int mItemCount;
/**
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index e27bb4fe..e445180 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -46,27 +46,32 @@
*/
@RemoteView
public class FrameLayout extends ViewGroup {
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "measurement")
boolean mMeasureAllChildren = false;
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "drawing")
private Drawable mForeground;
- @ViewDebug.ExportedProperty
+
+ @ViewDebug.ExportedProperty(category = "padding")
private int mForegroundPaddingLeft = 0;
- @ViewDebug.ExportedProperty
+
+ @ViewDebug.ExportedProperty(category = "padding")
private int mForegroundPaddingTop = 0;
- @ViewDebug.ExportedProperty
+
+ @ViewDebug.ExportedProperty(category = "padding")
private int mForegroundPaddingRight = 0;
- @ViewDebug.ExportedProperty
+
+ @ViewDebug.ExportedProperty(category = "padding")
private int mForegroundPaddingBottom = 0;
private final Rect mSelfBounds = new Rect();
private final Rect mOverlayBounds = new Rect();
- @ViewDebug.ExportedProperty
+
+ @ViewDebug.ExportedProperty(category = "drawing")
private int mForegroundGravity = Gravity.FILL;
/** {@hide} */
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "drawing")
protected boolean mForegroundInPadding = true;
boolean mForegroundBoundsChanged = false;
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index bd07e1f..0525891 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -50,7 +50,7 @@
* Whether the children of this layout are baseline aligned. Only applicable
* if {@link #mOrientation} is horizontal.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
private boolean mBaselineAligned = true;
/**
@@ -60,7 +60,7 @@
* Note: this is orthogonal to {@link #mBaselineAligned}, which is concerned
* with whether the children of this layout are baseline aligned.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
private int mBaselineAlignedChildIndex = -1;
/**
@@ -68,12 +68,13 @@
* We'll calculate the baseline of this layout as we measure vertically; for
* horizontal linear layouts, the offset of 0 is appropriate.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "measurement")
private int mBaselineChildTop = 0;
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "measurement")
private int mOrientation;
- @ViewDebug.ExportedProperty(mapping = {
+
+ @ViewDebug.ExportedProperty(category = "measurement", mapping = {
@ViewDebug.IntToString(from = -1, to = "NONE"),
@ViewDebug.IntToString(from = Gravity.NO_GRAVITY, to = "NONE"),
@ViewDebug.IntToString(from = Gravity.TOP, to = "TOP"),
@@ -88,13 +89,14 @@
@ViewDebug.IntToString(from = Gravity.FILL, to = "FILL")
})
private int mGravity = Gravity.LEFT | Gravity.TOP;
- @ViewDebug.ExportedProperty
+
+ @ViewDebug.ExportedProperty(category = "measurement")
private int mTotalLength;
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
private float mWeightSum;
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
private boolean mUseLargestChild;
private int[] mMaxAscent;
@@ -1364,7 +1366,7 @@
* 0 if the view should not be stretched. Otherwise the extra pixels
* will be pro-rated among all views whose weight is greater than 0.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
public float weight;
/**
@@ -1372,7 +1374,7 @@
*
* @see android.view.Gravity
*/
- @ViewDebug.ExportedProperty(mapping = {
+ @ViewDebug.ExportedProperty(category = "layout", mapping = {
@ViewDebug.IntToString(from = -1, to = "NONE"),
@ViewDebug.IntToString(from = Gravity.NO_GRAVITY, to = "NONE"),
@ViewDebug.IntToString(from = Gravity.TOP, to = "TOP"),
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 892c44a..ec6dbb7 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1140,7 +1140,7 @@
* UNSPECIFIED/AT_MOST modes, false otherwise.
* @hide
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "list")
protected boolean recycleOnMeasure() {
return true;
}
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 8e9eb05..c0a546d 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -336,7 +336,7 @@
*
* @return true if the progress bar is in indeterminate mode
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "progress")
public synchronized boolean isIndeterminate() {
return mIndeterminate;
}
@@ -609,7 +609,7 @@
* @see #setMax(int)
* @see #getMax()
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "progress")
public synchronized int getProgress() {
return mIndeterminate ? 0 : mProgress;
}
@@ -626,7 +626,7 @@
* @see #setMax(int)
* @see #getMax()
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "progress")
public synchronized int getSecondaryProgress() {
return mIndeterminate ? 0 : mSecondaryProgress;
}
@@ -640,7 +640,7 @@
* @see #getProgress()
* @see #getSecondaryProgress()
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "progress")
public synchronized int getMax() {
return mMax;
}
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 1aa1df3..64cda49 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -1011,7 +1011,7 @@
* @attr ref android.R.styleable#RelativeLayout_Layout_layout_centerVertical
*/
public static class LayoutParams extends ViewGroup.MarginLayoutParams {
- @ViewDebug.ExportedProperty(resolveId = true, indexMapping = {
+ @ViewDebug.ExportedProperty(category = "layout", resolveId = true, indexMapping = {
@ViewDebug.IntToString(from = ABOVE, to = "above"),
@ViewDebug.IntToString(from = ALIGN_BASELINE, to = "alignBaseline"),
@ViewDebug.IntToString(from = ALIGN_BOTTOM, to = "alignBottom"),
@@ -1040,7 +1040,7 @@
* When true, uses the parent as the anchor if the anchor doesn't exist or if
* the anchor's visibility is GONE.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
public boolean alignWithParent;
public LayoutParams(Context c, AttributeSet attrs) {
diff --git a/core/java/android/widget/TableRow.java b/core/java/android/widget/TableRow.java
index 48d12df..b612004 100644
--- a/core/java/android/widget/TableRow.java
+++ b/core/java/android/widget/TableRow.java
@@ -387,13 +387,13 @@
/**
* <p>The column index of the cell represented by the widget.</p>
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
public int column;
/**
* <p>The number of columns the widgets spans over.</p>
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "layout")
public int span;
private static final int LOCATION = 0;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 950012c..27e0e94 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -5733,7 +5733,7 @@
/**
* Convenience for {@link Selection#getSelectionStart}.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "text")
public int getSelectionStart() {
return Selection.getSelectionStart(getText());
}
@@ -5741,7 +5741,7 @@
/**
* Convenience for {@link Selection#getSelectionEnd}.
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "text")
public int getSelectionEnd() {
return Selection.getSelectionEnd(getText());
}
@@ -7295,7 +7295,7 @@
return false;
}
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(category = "text")
private CharSequence mText;
private CharSequence mTransformed;
private BufferType mBufferType = BufferType.NORMAL;
diff --git a/core/java/com/android/internal/app/IMediaContainerService.aidl b/core/java/com/android/internal/app/IMediaContainerService.aidl
index 89649a9..5d1f632 100755
--- a/core/java/com/android/internal/app/IMediaContainerService.aidl
+++ b/core/java/com/android/internal/app/IMediaContainerService.aidl
@@ -19,6 +19,7 @@
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.content.pm.PackageInfoLite;
+import android.content.res.ObbInfo;
interface IMediaContainerService {
String copyResourceToContainer(in Uri packageURI,
@@ -28,4 +29,5 @@
in ParcelFileDescriptor outStream);
PackageInfoLite getMinimalPackageInfo(in Uri fileUri, int flags);
boolean checkFreeStorage(boolean external, in Uri fileUri);
+ ObbInfo getObbInfo(String filename);
}
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 @@
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_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 @@
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..0932473a 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -600,7 +600,7 @@
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 @@
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 @@
}
}
-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 @@
}
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 @@
}
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
diff --git a/include/android_runtime/android_content_res_Configuration.h b/include/android_runtime/android_content_res_Configuration.h
new file mode 100644
index 0000000..2f5a982
--- /dev/null
+++ b/include/android_runtime/android_content_res_Configuration.h
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#ifndef _ANDROID_CONTENT_RES_CONFIGURATION_H
+#define _ANDROID_CONTENT_RES_CONFIGURATION_H
+
+#include <utils/ResourceTypes.h>
+#include <android/configuration.h>
+
+#include "jni.h"
+
+struct AConfiguration : android::ResTable_config {
+};
+
+namespace android {
+
+extern void android_Configuration_getFromJava(
+ JNIEnv* env, jobject clazz, struct AConfiguration* out);
+
+} // namespace android
+
+
+#endif // _ANDROID_CONTENT_RES_CONFIGURATION_H
diff --git a/include/utils/AssetManager.h b/include/utils/AssetManager.h
index 97694ff..9e2bf37 100644
--- a/include/utils/AssetManager.h
+++ b/include/utils/AssetManager.h
@@ -129,6 +129,8 @@
*/
void setConfiguration(const ResTable_config& config, const char* locale = NULL);
+ void getConfiguration(ResTable_config* outConfig) const;
+
typedef Asset::AccessMode AccessMode; // typing shortcut
/*
diff --git a/include/utils/ObbFile.h b/include/utils/ObbFile.h
index 075927c..d2ca82e 100644
--- a/include/utils/ObbFile.h
+++ b/include/utils/ObbFile.h
@@ -35,6 +35,8 @@
bool readFrom(int fd);
bool writeTo(const char* filename);
bool writeTo(int fd);
+ bool removeFrom(const char* filename);
+ bool removeFrom(int fd);
const char* getFileName() const {
return mFileName;
@@ -78,6 +80,8 @@
size_t mFileSize;
+ size_t mFooterStart;
+
unsigned char* mReadBuf;
bool parseObbFile(int fd);
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index c7d9ff1..da86da4 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -31,6 +31,8 @@
#include <stdint.h>
#include <sys/types.h>
+#include <android/configuration.h>
+
namespace android {
/** ********************************************************************
@@ -822,25 +824,25 @@
};
enum {
- ORIENTATION_ANY = 0x0000,
- ORIENTATION_PORT = 0x0001,
- ORIENTATION_LAND = 0x0002,
- ORIENTATION_SQUARE = 0x0003,
+ ORIENTATION_ANY = ACONFIGURATION_ORIENTATION_ANY,
+ ORIENTATION_PORT = ACONFIGURATION_ORIENTATION_PORT,
+ ORIENTATION_LAND = ACONFIGURATION_ORIENTATION_LAND,
+ ORIENTATION_SQUARE = ACONFIGURATION_ORIENTATION_SQUARE,
};
enum {
- TOUCHSCREEN_ANY = 0x0000,
- TOUCHSCREEN_NOTOUCH = 0x0001,
- TOUCHSCREEN_STYLUS = 0x0002,
- TOUCHSCREEN_FINGER = 0x0003,
+ TOUCHSCREEN_ANY = ACONFIGURATION_TOUCHSCREEN_ANY,
+ TOUCHSCREEN_NOTOUCH = ACONFIGURATION_TOUCHSCREEN_NOTOUCH,
+ TOUCHSCREEN_STYLUS = ACONFIGURATION_TOUCHSCREEN_STYLUS,
+ TOUCHSCREEN_FINGER = ACONFIGURATION_TOUCHSCREEN_FINGER,
};
enum {
- DENSITY_DEFAULT = 0,
- DENSITY_LOW = 120,
- DENSITY_MEDIUM = 160,
- DENSITY_HIGH = 240,
- DENSITY_NONE = 0xffff
+ DENSITY_DEFAULT = ACONFIGURATION_DENSITY_DEFAULT,
+ DENSITY_LOW = ACONFIGURATION_DENSITY_LOW,
+ DENSITY_MEDIUM = ACONFIGURATION_DENSITY_MEDIUM,
+ DENSITY_HIGH = ACONFIGURATION_DENSITY_HIGH,
+ DENSITY_NONE = ACONFIGURATION_DENSITY_NONE
};
union {
@@ -853,33 +855,34 @@
};
enum {
- KEYBOARD_ANY = 0x0000,
- KEYBOARD_NOKEYS = 0x0001,
- KEYBOARD_QWERTY = 0x0002,
- KEYBOARD_12KEY = 0x0003,
+ KEYBOARD_ANY = ACONFIGURATION_KEYBOARD_ANY,
+ KEYBOARD_NOKEYS = ACONFIGURATION_KEYBOARD_NOKEYS,
+ KEYBOARD_QWERTY = ACONFIGURATION_KEYBOARD_QWERTY,
+ KEYBOARD_12KEY = ACONFIGURATION_KEYBOARD_12KEY,
};
enum {
- NAVIGATION_ANY = 0x0000,
- NAVIGATION_NONAV = 0x0001,
- NAVIGATION_DPAD = 0x0002,
- NAVIGATION_TRACKBALL = 0x0003,
- NAVIGATION_WHEEL = 0x0004,
+ NAVIGATION_ANY = ACONFIGURATION_NAVIGATION_ANY,
+ NAVIGATION_NONAV = ACONFIGURATION_NAVIGATION_NONAV,
+ NAVIGATION_DPAD = ACONFIGURATION_NAVIGATION_DPAD,
+ NAVIGATION_TRACKBALL = ACONFIGURATION_NAVIGATION_TRACKBALL,
+ NAVIGATION_WHEEL = ACONFIGURATION_NAVIGATION_WHEEL,
};
enum {
MASK_KEYSHIDDEN = 0x0003,
- KEYSHIDDEN_ANY = 0x0000,
- KEYSHIDDEN_NO = 0x0001,
- KEYSHIDDEN_YES = 0x0002,
- KEYSHIDDEN_SOFT = 0x0003,
+ KEYSHIDDEN_ANY = ACONFIGURATION_KEYSHIDDEN_ANY,
+ KEYSHIDDEN_NO = ACONFIGURATION_KEYSHIDDEN_NO,
+ KEYSHIDDEN_YES = ACONFIGURATION_KEYSHIDDEN_YES,
+ KEYSHIDDEN_SOFT = ACONFIGURATION_KEYSHIDDEN_SOFT,
};
enum {
MASK_NAVHIDDEN = 0x000c,
- NAVHIDDEN_ANY = 0x0000,
- NAVHIDDEN_NO = 0x0004,
- NAVHIDDEN_YES = 0x0008,
+ SHIFT_NAVHIDDEN = 2,
+ NAVHIDDEN_ANY = ACONFIGURATION_NAVHIDDEN_ANY << SHIFT_NAVHIDDEN,
+ NAVHIDDEN_NO = ACONFIGURATION_NAVHIDDEN_NO << SHIFT_NAVHIDDEN,
+ NAVHIDDEN_YES = ACONFIGURATION_NAVHIDDEN_YES << SHIFT_NAVHIDDEN,
};
union {
@@ -929,32 +932,34 @@
enum {
// screenLayout bits for screen size class.
MASK_SCREENSIZE = 0x0f,
- SCREENSIZE_ANY = 0x00,
- SCREENSIZE_SMALL = 0x01,
- SCREENSIZE_NORMAL = 0x02,
- SCREENSIZE_LARGE = 0x03,
- SCREENSIZE_XLARGE = 0x04,
+ SCREENSIZE_ANY = ACONFIGURATION_SCREENSIZE_ANY,
+ SCREENSIZE_SMALL = ACONFIGURATION_SCREENSIZE_SMALL,
+ SCREENSIZE_NORMAL = ACONFIGURATION_SCREENSIZE_NORMAL,
+ SCREENSIZE_LARGE = ACONFIGURATION_SCREENSIZE_LARGE,
+ SCREENSIZE_XLARGE = ACONFIGURATION_SCREENSIZE_XLARGE,
// screenLayout bits for wide/long screen variation.
MASK_SCREENLONG = 0x30,
- SCREENLONG_ANY = 0x00,
- SCREENLONG_NO = 0x10,
- SCREENLONG_YES = 0x20,
+ SHIFT_SCREENLONG = 4,
+ SCREENLONG_ANY = ACONFIGURATION_SCREENLONG_ANY << SHIFT_SCREENLONG,
+ SCREENLONG_NO = ACONFIGURATION_SCREENLONG_NO << SHIFT_SCREENLONG,
+ SCREENLONG_YES = ACONFIGURATION_SCREENLONG_YES << SHIFT_SCREENLONG,
};
enum {
// uiMode bits for the mode type.
MASK_UI_MODE_TYPE = 0x0f,
- UI_MODE_TYPE_ANY = 0x00,
- UI_MODE_TYPE_NORMAL = 0x01,
- UI_MODE_TYPE_DESK = 0x02,
- UI_MODE_TYPE_CAR = 0x03,
+ UI_MODE_TYPE_ANY = ACONFIGURATION_UI_MODE_TYPE_ANY,
+ UI_MODE_TYPE_NORMAL = ACONFIGURATION_UI_MODE_TYPE_NORMAL,
+ UI_MODE_TYPE_DESK = ACONFIGURATION_UI_MODE_TYPE_DESK,
+ UI_MODE_TYPE_CAR = ACONFIGURATION_UI_MODE_TYPE_CAR,
// uiMode bits for the night switch.
MASK_UI_MODE_NIGHT = 0x30,
- UI_MODE_NIGHT_ANY = 0x00,
- UI_MODE_NIGHT_NO = 0x10,
- UI_MODE_NIGHT_YES = 0x20,
+ SHIFT_UI_MODE_NIGHT = 4,
+ UI_MODE_NIGHT_ANY = ACONFIGURATION_UI_MODE_NIGHT_ANY << SHIFT_UI_MODE_NIGHT,
+ UI_MODE_NIGHT_NO = ACONFIGURATION_UI_MODE_NIGHT_NO << SHIFT_UI_MODE_NIGHT,
+ UI_MODE_NIGHT_YES = ACONFIGURATION_UI_MODE_NIGHT_YES << SHIFT_UI_MODE_NIGHT,
};
union {
@@ -1023,19 +1028,19 @@
// match the corresponding ones in android.content.pm.ActivityInfo and
// attrs_manifest.xml.
enum {
- CONFIG_MCC = 0x0001,
- CONFIG_MNC = 0x0002,
- CONFIG_LOCALE = 0x0004,
- CONFIG_TOUCHSCREEN = 0x0008,
- CONFIG_KEYBOARD = 0x0010,
- CONFIG_KEYBOARD_HIDDEN = 0x0020,
- CONFIG_NAVIGATION = 0x0040,
- CONFIG_ORIENTATION = 0x0080,
- CONFIG_DENSITY = 0x0100,
- CONFIG_SCREEN_SIZE = 0x0200,
- CONFIG_VERSION = 0x0400,
- CONFIG_SCREEN_LAYOUT = 0x0800,
- CONFIG_UI_MODE = 0x1000
+ CONFIG_MCC = ACONFIGURATION_MCC,
+ CONFIG_MNC = ACONFIGURATION_MCC,
+ CONFIG_LOCALE = ACONFIGURATION_LOCALE,
+ CONFIG_TOUCHSCREEN = ACONFIGURATION_TOUCHSCREEN,
+ CONFIG_KEYBOARD = ACONFIGURATION_KEYBOARD,
+ CONFIG_KEYBOARD_HIDDEN = ACONFIGURATION_KEYBOARD_HIDDEN,
+ CONFIG_NAVIGATION = ACONFIGURATION_NAVIGATION,
+ CONFIG_ORIENTATION = ACONFIGURATION_ORIENTATION,
+ CONFIG_DENSITY = ACONFIGURATION_DENSITY,
+ CONFIG_SCREEN_SIZE = ACONFIGURATION_SCREEN_SIZE,
+ CONFIG_VERSION = ACONFIGURATION_VERSION,
+ CONFIG_SCREEN_LAYOUT = ACONFIGURATION_SCREEN_LAYOUT,
+ CONFIG_UI_MODE = ACONFIGURATION_UI_MODE
};
// Compare two configuration, returning CONFIG_* flags set for each value
diff --git a/libs/utils/AssetManager.cpp b/libs/utils/AssetManager.cpp
index 60a0d82..e09e755 100644
--- a/libs/utils/AssetManager.cpp
+++ b/libs/utils/AssetManager.cpp
@@ -232,6 +232,12 @@
}
}
+void AssetManager::getConfiguration(ResTable_config* outConfig) const
+{
+ AutoMutex _l(mLock);
+ *outConfig = *mConfig;
+}
+
/*
* Open an asset.
*
diff --git a/libs/utils/ObbFile.cpp b/libs/utils/ObbFile.cpp
index fe49300..adedf0c 100644
--- a/libs/utils/ObbFile.cpp
+++ b/libs/utils/ObbFile.cpp
@@ -156,9 +156,9 @@
return false;
}
- if (footerSize < kFooterMinSize) {
- LOGW("claimed footer size is too small (%08zx; minimum size is 0x%x)\n",
- footerSize, kFooterMinSize);
+ if (footerSize < (kFooterMinSize - kFooterTagSize)) {
+ LOGW("claimed footer size is too small (0x%zx; minimum size is 0x%x)\n",
+ footerSize, kFooterMinSize - kFooterTagSize);
return false;
}
}
@@ -169,6 +169,8 @@
return false;
}
+ mFooterStart = fileOffset;
+
char* scanBuf = (char*)malloc(footerSize);
if (scanBuf == NULL) {
LOGW("couldn't allocate scanBuf: %s\n", strerror(errno));
@@ -293,4 +295,38 @@
return true;
}
+bool ObbFile::removeFrom(const char* filename)
+{
+ int fd;
+ bool success = false;
+
+ fd = ::open(filename, O_RDWR);
+ if (fd < 0) {
+ goto out;
+ }
+ success = removeFrom(fd);
+ close(fd);
+
+out:
+ if (!success) {
+ LOGW("failed to remove signature from %s: %s\n", filename, strerror(errno));
+ }
+ return success;
+}
+
+bool ObbFile::removeFrom(int fd)
+{
+ if (fd < 0) {
+ return false;
+ }
+
+ if (!readFrom(fd)) {
+ return false;
+ }
+
+ ftruncate(fd, mFooterStart);
+
+ return true;
+}
+
}
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 9c48daf..3e31d61 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -244,6 +244,7 @@
void CameraSource::signalBufferReturned(MediaBuffer *buffer) {
LOGV("signalBufferReturned: %p", buffer->data());
+ Mutex::Autolock autoLock(mLock);
for (List<sp<IMemory> >::iterator it = mFramesBeingEncoded.begin();
it != mFramesBeingEncoded.end(); ++it) {
if ((*it)->pointer() == buffer->data()) {
@@ -312,6 +313,7 @@
(*buffer)->setObserver(this);
(*buffer)->add_ref();
(*buffer)->meta_data()->setInt64(kKeyTime, frameTime);
+
return OK;
}
}
diff --git a/media/tests/MediaFrameworkTest/AndroidManifest.xml b/media/tests/MediaFrameworkTest/AndroidManifest.xml
index 246f9fc..f70a145 100644
--- a/media/tests/MediaFrameworkTest/AndroidManifest.xml
+++ b/media/tests/MediaFrameworkTest/AndroidManifest.xml
@@ -51,4 +51,9 @@
android:label="MediaRecorder stress tests InstrumentationRunner">
</instrumentation>
+ <instrumentation android:name=".MediaFrameworkPowerTestRunner"
+ android:targetPackage="com.android.mediaframeworktest"
+ android:label="Media Power tests InstrumentationRunner">
+ </instrumentation>
+
</manifest>
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPowerTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPowerTestRunner.java
new file mode 100755
index 0000000..34db4db
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPowerTestRunner.java
@@ -0,0 +1,50 @@
+/*
+ * 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.mediaframeworktest;
+
+import com.android.mediaframeworktest.power.MediaPlayerPowerTest;
+
+import junit.framework.TestSuite;
+
+import android.test.InstrumentationTestRunner;
+import android.test.InstrumentationTestSuite;
+
+
+/**
+ * Instrumentation Test Runner for all MediaPlayer tests.
+ *
+ * Running all tests:
+ *
+ * adb shell am instrument \
+ * -w com.android.mediaframeworktest/.MediaFrameworkPowerTestRunner
+ */
+
+public class MediaFrameworkPowerTestRunner extends InstrumentationTestRunner {
+
+ @Override
+ public TestSuite getAllTests() {
+ TestSuite suite = new InstrumentationTestSuite(this);
+ suite.addTestSuite(MediaPlayerPowerTest.class);
+ return suite;
+ }
+
+ @Override
+ public ClassLoader getLoader() {
+ return MediaFrameworkPowerTestRunner.class.getClassLoader();
+ }
+}
+
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/power/MediaPlayerPowerTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/power/MediaPlayerPowerTest.java
new file mode 100644
index 0000000..9e91740
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/power/MediaPlayerPowerTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.mediaframeworktest.power;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import com.android.mediaframeworktest.MediaNames;
+import android.media.MediaPlayer;
+import android.os.Environment;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import java.io.File;
+
+/**
+ * Junit / Instrumentation test case for the power measurment the media player
+ */
+public class MediaPlayerPowerTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
+ private String TAG = "MediaPlayerPowerTest";
+ private String MP3_POWERTEST =
+ Environment.getExternalStorageDirectory().toString() + "/power_sample_mp3.mp3";
+ private String MP3_STREAM = "http://75.17.48.204:10088/power_media/power_sample_mp3.mp3";
+ private String OGG_STREAM = "http://75.17.48.204:10088/power_media/power_sample_ogg.mp3";
+ private String AAC_STREAM = "http://75.17.48.204:10088/power_media/power_sample_aac.mp3";
+
+ public MediaPlayerPowerTest() {
+ super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+ }
+
+ protected void setUp() throws Exception {
+ getActivity();
+ super.setUp();
+
+ }
+
+ public void audioPlayback(String filePath) {
+ try {
+ MediaPlayer mp = new MediaPlayer();
+ mp.setDataSource(filePath);
+ mp.prepare();
+ mp.start();
+ Thread.sleep(200000);
+ mp.stop();
+ mp.release();
+ } catch (Exception e) {
+ Log.v(TAG, e.toString());
+ assertTrue("MP3 Playback", false);
+ }
+ }
+
+ // A very simple test case which start the audio player.
+ // Power measurment will be done in other application.
+ public void testPowerLocalMP3Playback() throws Exception {
+ audioPlayback(MP3_POWERTEST);
+ }
+
+ public void testPowerStreamMP3Playback() throws Exception {
+ audioPlayback(MP3_STREAM);
+ }
+
+ public void testPowerStreamOGGPlayback() throws Exception {
+ audioPlayback(OGG_STREAM);
+ }
+
+ public void testPowerStreamAACPlayback() throws Exception {
+ audioPlayback(AAC_STREAM);
+ }
+}
diff --git a/native/android/Android.mk b/native/android/Android.mk
index 950a1e9..bd2b27a 100644
--- a/native/android/Android.mk
+++ b/native/android/Android.mk
@@ -7,6 +7,7 @@
#
LOCAL_SRC_FILES:= \
asset_manager.cpp \
+ configuration.cpp \
input.cpp \
looper.cpp \
native_activity.cpp \
diff --git a/native/android/asset_manager.cpp b/native/android/asset_manager.cpp
index 36c381e..3f7c1b6 100644
--- a/native/android/asset_manager.cpp
+++ b/native/android/asset_manager.cpp
@@ -17,7 +17,7 @@
#define LOG_TAG "NAsset"
#include <utils/Log.h>
-#include <android/asset_manager.h>
+#include <android/asset_manager_jni.h>
#include <utils/AssetManager.h>
#include <utils/AssetDir.h>
#include <utils/Asset.h>
diff --git a/native/android/configuration.cpp b/native/android/configuration.cpp
new file mode 100644
index 0000000..d76164f
--- /dev/null
+++ b/native/android/configuration.cpp
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "Configuration"
+#include <utils/Log.h>
+
+#include <utils/AssetManager.h>
+
+#include <android_runtime/android_content_res_Configuration.h>
+
+using namespace android;
+
+AConfiguration* AConfiguration_new() {
+ AConfiguration* config = new AConfiguration;
+ memset(config, 0, sizeof(AConfiguration));
+ return config;
+}
+
+void AConfiguration_delete(AConfiguration* config) {
+ delete config;
+}
+
+void AConfiguration_fromAssetManager(AConfiguration* out, AAssetManager* am) {
+ ((AssetManager*)am)->getConfiguration(out);
+}
+
+void AConfiguration_copy(AConfiguration* dest, AConfiguration* src) {
+ *dest = *src;
+}
+
+int32_t AConfiguration_getMcc(AConfiguration* config) {
+ return config->mcc;
+}
+
+int32_t AConfiguration_getMnc(AConfiguration* config) {
+ return config->mnc;
+}
+
+void AConfiguration_getLanguage(AConfiguration* config, char* outLanguage) {
+ outLanguage[0] = config->language[0];
+ outLanguage[1] = config->language[1];
+}
+
+void AConfiguration_getCountry(AConfiguration* config, char* outCountry) {
+ outCountry[0] = config->country[0];
+ outCountry[1] = config->country[1];
+}
+
+int32_t AConfiguration_getOrientation(AConfiguration* config) {
+ return config->orientation;
+}
+
+int32_t AConfiguration_getTouchscreen(AConfiguration* config) {
+ return config->touchscreen;
+}
+
+int32_t AConfiguration_getDensity(AConfiguration* config) {
+ return config->density;
+}
+
+int32_t AConfiguration_getKeyboard(AConfiguration* config) {
+ return config->keyboard;
+}
+
+int32_t AConfiguration_getNavigation(AConfiguration* config) {
+ return config->navigation;
+}
+
+int32_t AConfiguration_getKeysHidden(AConfiguration* config) {
+ return config->inputFlags&ResTable_config::MASK_KEYSHIDDEN;
+}
+
+int32_t AConfiguration_getNavHidden(AConfiguration* config) {
+ return (config->inputFlags&ResTable_config::MASK_NAVHIDDEN)
+ >> ResTable_config::SHIFT_NAVHIDDEN;
+}
+
+int32_t AConfiguration_getSdkVersion(AConfiguration* config) {
+ return config->sdkVersion;
+}
+
+int32_t AConfiguration_getScreenSize(AConfiguration* config) {
+ return config->screenLayout&ResTable_config::MASK_SCREENSIZE;
+}
+
+int32_t AConfiguration_getScreenLong(AConfiguration* config) {
+ return (config->screenLayout&ResTable_config::MASK_SCREENLONG)
+ >> ResTable_config::SHIFT_SCREENLONG;
+}
+
+int32_t AConfiguration_getUiModeType(AConfiguration* config) {
+ return config->uiMode&ResTable_config::MASK_UI_MODE_TYPE;
+}
+
+int32_t AConfiguration_getUiModeNight(AConfiguration* config) {
+ return (config->uiMode&ResTable_config::MASK_UI_MODE_NIGHT)
+ >> ResTable_config::SHIFT_UI_MODE_NIGHT;
+
+}
+
+// ----------------------------------------------------------------------
+
+void AConfiguration_setMcc(AConfiguration* config, int32_t mcc) {
+ config->mcc = mcc;
+}
+
+void AConfiguration_setMnc(AConfiguration* config, int32_t mnc) {
+ config->mnc = mnc;
+}
+
+void AConfiguration_setLanguage(AConfiguration* config, const char* language) {
+ config->language[0] = language[0];
+ config->language[1] = language[1];
+}
+
+void AConfiguration_setCountry(AConfiguration* config, const char* country) {
+ config->country[0] = country[0];
+ config->country[1] = country[1];
+}
+
+void AConfiguration_setOrientation(AConfiguration* config, int32_t orientation) {
+ config->orientation = orientation;
+}
+
+void AConfiguration_setTouchscreen(AConfiguration* config, int32_t touchscreen) {
+ config->touchscreen = touchscreen;
+}
+
+void AConfiguration_setDensity(AConfiguration* config, int32_t density) {
+ config->density = density;
+}
+
+void AConfiguration_setKeyboard(AConfiguration* config, int32_t keyboard) {
+ config->keyboard = keyboard;
+}
+
+void AConfiguration_setNavigation(AConfiguration* config, int32_t navigation) {
+ config->navigation = navigation;
+}
+
+void AConfiguration_setKeysHidden(AConfiguration* config, int32_t keysHidden) {
+ config->inputFlags = (config->inputFlags&~ResTable_config::MASK_KEYSHIDDEN)
+ | (keysHidden&ResTable_config::MASK_KEYSHIDDEN);
+}
+
+void AConfiguration_setNavHidden(AConfiguration* config, int32_t navHidden) {
+ config->inputFlags = (config->inputFlags&~ResTable_config::MASK_NAVHIDDEN)
+ | ((navHidden<<ResTable_config::SHIFT_NAVHIDDEN)&ResTable_config::MASK_NAVHIDDEN);
+}
+
+void AConfiguration_setSdkVersion(AConfiguration* config, int32_t sdkVersion) {
+ config->sdkVersion = sdkVersion;
+}
+
+void AConfiguration_setScreenSize(AConfiguration* config, int32_t screenSize) {
+ config->screenLayout = (config->screenLayout&~ResTable_config::MASK_SCREENSIZE)
+ | (screenSize&ResTable_config::MASK_SCREENSIZE);
+}
+
+void AConfiguration_setScreenLong(AConfiguration* config, int32_t screenLong) {
+ config->screenLayout = (config->screenLayout&~ResTable_config::MASK_SCREENLONG)
+ | ((screenLong<<ResTable_config::SHIFT_SCREENLONG)&ResTable_config::MASK_SCREENLONG);
+}
+
+void AConfiguration_setUiModeType(AConfiguration* config, int32_t uiModeType) {
+ config->uiMode = (config->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
+ | (uiModeType&ResTable_config::MASK_UI_MODE_TYPE);
+}
+
+void AConfiguration_setUiModeNight(AConfiguration* config, int32_t uiModeNight) {
+ config->uiMode = (config->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
+ | ((uiModeNight<<ResTable_config::SHIFT_UI_MODE_NIGHT)&ResTable_config::MASK_UI_MODE_NIGHT);
+
+}
+
+// ----------------------------------------------------------------------
+
+int32_t AConfiguration_diff(AConfiguration* config1, AConfiguration* config2) {
+ return (config1->diff(*config2));
+}
+
+int32_t AConfiguration_match(AConfiguration* base, AConfiguration* requested) {
+ return base->match(*requested);
+}
+
+int32_t AConfiguration_isBetterThan(AConfiguration* base, AConfiguration* test,
+ AConfiguration* requested) {
+ return base->isBetterThan(*test, requested);
+}
diff --git a/native/copy-to-ndk.sh b/native/copy-to-ndk.sh
new file mode 100644
index 0000000..4f5a16a
--- /dev/null
+++ b/native/copy-to-ndk.sh
@@ -0,0 +1,55 @@
+# Take care of copying current header files over to the correct
+# location in the NDK.
+
+copyndkheaders() {
+ local CURR_PLATFORM=android-9
+ local ALL_PLATFORMS="$CURR_PLATFORM android-8 android-5 android-4 android-3"
+
+ local SRC_HEADERS=$ANDROID_BUILD_TOP/frameworks/base/native/include/android
+ local NDK_PLATFORMS=$ANDROID_BUILD_TOP/development/ndk/platforms
+ local DST_HEADERS=$NDK_PLATFORMS/$CURR_PLATFORM
+
+ local SRC_LIB_ANDROID=$ANDROID_PRODUCT_OUT/system/lib/libandroid.so
+ local DST_LIB_ANDROID=$NDK_PLATFORMS/$CURR_PLATFORM/arch-arm/usr/lib/libandroid.so
+
+ local didsomething=""
+
+ #echo "SRC_HEADERS: $SRC_HEADERS"
+
+ for i in $(cd $SRC_HEADERS; ls *.h); do
+ local src=$SRC_HEADERS/$i
+ local changed=""
+ for j in $ALL_PLATFORMS; do
+ local dst=$NDK_PLATFORMS/$j/arch-arm/usr/include/android/$i
+ if [ "$changed" == "" -a -e $dst ]; then
+ #echo "Exists: $dst"
+ if diff $src $dst >/dev/null; then
+ echo "$i: has not changed from $j" >/dev/null
+ changed="false"
+ else
+ changed="true"
+ echo "$i: has changed from $j" >/dev/null
+ fi
+ fi
+ done
+ if [ "$changed" == "true" -o "$changed" == "" ]; then
+ echo "Updating: $i"
+ cp $src $NDK_PLATFORMS/$CURR_PLATFORM/arch-arm/usr/include/android/$i
+ didsomething="true"
+ fi
+ done
+
+ if diff $SRC_LIB_ANDROID $DST_LIB_ANDROID >/dev/null; then
+ echo "libandroid.so: has not changed" >/dev/null
+ else
+ echo "Updating: $DST_LIB_ANDROID"
+ cp $SRC_LIB_ANDROID $DST_LIB_ANDROID
+ didsomething="true"
+ fi
+ if [ "$didsomething" != "" ]; then
+ echo "Headers changed... rebuilding platforms."
+ sh $ANDROID_BUILD_TOP/ndk/build/tools/build-platforms.sh
+ fi
+}
+
+copyndkheaders
diff --git a/native/include/android/asset_manager.h b/native/include/android/asset_manager.h
index 89989f8..4fa0ef3 100644
--- a/native/include/android/asset_manager.h
+++ b/native/include/android/asset_manager.h
@@ -18,8 +18,6 @@
#ifndef ANDROID_ASSET_MANAGER_H
#define ANDROID_ASSET_MANAGER_H
-#include <jni.h>
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -43,14 +41,6 @@
/**
- * Given a Dalvik AssetManager object, obtain the corresponding native AAssetManager
- * object. Note that the caller is responsible for obtaining and holding a VM reference
- * to the jobject to prevent its being garbage collected while the native object is
- * in use.
- */
-AAssetManager* AAssetManager_fromJava(JNIEnv* env, jobject assetManager);
-
-/**
* Open the named directory within the asset hierarchy. The directory can then
* be inspected with the AAssetDir functions. To open the top-level directory,
* pass in "" as the dirName.
diff --git a/native/include/android/asset_manager_jni.h b/native/include/android/asset_manager_jni.h
new file mode 100644
index 0000000..aec2d3c
--- /dev/null
+++ b/native/include/android/asset_manager_jni.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+
+#ifndef ANDROID_ASSET_MANAGER_JNI_H
+#define ANDROID_ASSET_MANAGER_JNI_H
+
+#include <android/asset_manager.h>
+#include <jni.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Given a Dalvik AssetManager object, obtain the corresponding native AAssetManager
+ * object. Note that the caller is responsible for obtaining and holding a VM reference
+ * to the jobject to prevent its being garbage collected while the native object is
+ * in use.
+ */
+AAssetManager* AAssetManager_fromJava(JNIEnv* env, jobject assetManager);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // ANDROID_ASSET_MANAGER_JNI_H
diff --git a/native/include/android/configuration.h b/native/include/android/configuration.h
new file mode 100644
index 0000000..79b9b1e
--- /dev/null
+++ b/native/include/android/configuration.h
@@ -0,0 +1,319 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_CONFIGURATION_H
+#define ANDROID_CONFIGURATION_H
+
+#include <android/asset_manager.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct AConfiguration;
+typedef struct AConfiguration AConfiguration;
+
+enum {
+ ACONFIGURATION_ORIENTATION_ANY = 0x0000,
+ ACONFIGURATION_ORIENTATION_PORT = 0x0001,
+ ACONFIGURATION_ORIENTATION_LAND = 0x0002,
+ ACONFIGURATION_ORIENTATION_SQUARE = 0x0003,
+
+ ACONFIGURATION_TOUCHSCREEN_ANY = 0x0000,
+ ACONFIGURATION_TOUCHSCREEN_NOTOUCH = 0x0001,
+ ACONFIGURATION_TOUCHSCREEN_STYLUS = 0x0002,
+ ACONFIGURATION_TOUCHSCREEN_FINGER = 0x0003,
+
+ ACONFIGURATION_DENSITY_DEFAULT = 0,
+ ACONFIGURATION_DENSITY_LOW = 120,
+ ACONFIGURATION_DENSITY_MEDIUM = 160,
+ ACONFIGURATION_DENSITY_HIGH = 240,
+ ACONFIGURATION_DENSITY_NONE = 0xffff,
+
+ ACONFIGURATION_KEYBOARD_ANY = 0x0000,
+ ACONFIGURATION_KEYBOARD_NOKEYS = 0x0001,
+ ACONFIGURATION_KEYBOARD_QWERTY = 0x0002,
+ ACONFIGURATION_KEYBOARD_12KEY = 0x0003,
+
+ ACONFIGURATION_NAVIGATION_ANY = 0x0000,
+ ACONFIGURATION_NAVIGATION_NONAV = 0x0001,
+ ACONFIGURATION_NAVIGATION_DPAD = 0x0002,
+ ACONFIGURATION_NAVIGATION_TRACKBALL = 0x0003,
+ ACONFIGURATION_NAVIGATION_WHEEL = 0x0004,
+
+ ACONFIGURATION_KEYSHIDDEN_ANY = 0x0000,
+ ACONFIGURATION_KEYSHIDDEN_NO = 0x0001,
+ ACONFIGURATION_KEYSHIDDEN_YES = 0x0002,
+ ACONFIGURATION_KEYSHIDDEN_SOFT = 0x0003,
+
+ ACONFIGURATION_NAVHIDDEN_ANY = 0x0000,
+ ACONFIGURATION_NAVHIDDEN_NO = 0x0001,
+ ACONFIGURATION_NAVHIDDEN_YES = 0x0002,
+
+ ACONFIGURATION_SCREENSIZE_ANY = 0x00,
+ ACONFIGURATION_SCREENSIZE_SMALL = 0x01,
+ ACONFIGURATION_SCREENSIZE_NORMAL = 0x02,
+ ACONFIGURATION_SCREENSIZE_LARGE = 0x03,
+ ACONFIGURATION_SCREENSIZE_XLARGE = 0x04,
+
+ ACONFIGURATION_SCREENLONG_ANY = 0x00,
+ ACONFIGURATION_SCREENLONG_NO = 0x1,
+ ACONFIGURATION_SCREENLONG_YES = 0x2,
+
+ ACONFIGURATION_UI_MODE_TYPE_ANY = 0x00,
+ ACONFIGURATION_UI_MODE_TYPE_NORMAL = 0x01,
+ ACONFIGURATION_UI_MODE_TYPE_DESK = 0x02,
+ ACONFIGURATION_UI_MODE_TYPE_CAR = 0x03,
+
+ ACONFIGURATION_UI_MODE_NIGHT_ANY = 0x00,
+ ACONFIGURATION_UI_MODE_NIGHT_NO = 0x10,
+ ACONFIGURATION_UI_MODE_NIGHT_YES = 0x20,
+
+ ACONFIGURATION_MCC = 0x0001,
+ ACONFIGURATION_MNC = 0x0002,
+ ACONFIGURATION_LOCALE = 0x0004,
+ ACONFIGURATION_TOUCHSCREEN = 0x0008,
+ ACONFIGURATION_KEYBOARD = 0x0010,
+ ACONFIGURATION_KEYBOARD_HIDDEN = 0x0020,
+ ACONFIGURATION_NAVIGATION = 0x0040,
+ ACONFIGURATION_ORIENTATION = 0x0080,
+ ACONFIGURATION_DENSITY = 0x0100,
+ ACONFIGURATION_SCREEN_SIZE = 0x0200,
+ ACONFIGURATION_VERSION = 0x0400,
+ ACONFIGURATION_SCREEN_LAYOUT = 0x0800,
+ ACONFIGURATION_UI_MODE = 0x1000,
+};
+
+/**
+ * Create a new AConfiguration, initialized with no values set.
+ */
+AConfiguration* AConfiguration_new();
+
+/**
+ * Free an AConfiguration that was previously created with
+ * AConfiguration_new().
+ */
+void AConfiguration_delete(AConfiguration* config);
+
+/**
+ * Create and return a new AConfiguration based on the current configuration in
+ * use in the given AssetManager.
+ */
+void AConfiguration_fromAssetManager(AConfiguration* out, AAssetManager* am);
+
+/**
+ * Copy the contents of 'src' to 'dest'.
+ */
+void AConfiguration_copy(AConfiguration* dest, AConfiguration* src);
+
+/**
+ * Return the current MCC set in the configuration. 0 if not set.
+ */
+int32_t AConfiguration_getMcc(AConfiguration* config);
+
+/**
+ * Set the current MCC in the configuration. 0 to clear.
+ */
+void AConfiguration_setMcc(AConfiguration* config, int32_t mcc);
+
+/**
+ * Return the current MNC set in the configuration. 0 if not set.
+ */
+int32_t AConfiguration_getMnc(AConfiguration* config);
+
+/**
+ * Set the current MNC in the configuration. 0 to clear.
+ */
+void AConfiguration_setMnc(AConfiguration* config, int32_t mnc);
+
+/**
+ * Return the current language code set in the configuration. The output will
+ * be filled with an array of two characters. They are not 0-terminated. If
+ * a language is not set, they will be 0.
+ */
+void AConfiguration_getLanguage(AConfiguration* config, char* outLanguage);
+
+/**
+ * Set the current language code in the configuration, from the first two
+ * characters in the string.
+ */
+void AConfiguration_setLanguage(AConfiguration* config, const char* language);
+
+/**
+ * Return the current country code set in the configuration. The output will
+ * be filled with an array of two characters. They are not 0-terminated. If
+ * a country is not set, they will be 0.
+ */
+void AConfiguration_getCountry(AConfiguration* config, char* outCountry);
+
+/**
+ * Set the current country code in the configuration, from the first two
+ * characters in the string.
+ */
+void AConfiguration_setCountry(AConfiguration* config, const char* country);
+
+/**
+ * Return the current ACONFIGURATION_ORIENTATION_* set in the configuration.
+ */
+int32_t AConfiguration_getOrientation(AConfiguration* config);
+
+/**
+ * Set the current orientation in the configuration.
+ */
+void AConfiguration_setOrientation(AConfiguration* config, int32_t orientation);
+
+/**
+ * Return the current ACONFIGURATION_TOUCHSCREEN_* set in the configuration.
+ */
+int32_t AConfiguration_getTouchscreen(AConfiguration* config);
+
+/**
+ * Set the current touchscreen in the configuration.
+ */
+void AConfiguration_setTouchscreen(AConfiguration* config, int32_t touchscreen);
+
+/**
+ * Return the current ACONFIGURATION_DENSITY_* set in the configuration.
+ */
+int32_t AConfiguration_getDensity(AConfiguration* config);
+
+/**
+ * Set the current density in the configuration.
+ */
+void AConfiguration_setDensity(AConfiguration* config, int32_t density);
+
+/**
+ * Return the current ACONFIGURATION_KEYBOARD_* set in the configuration.
+ */
+int32_t AConfiguration_getKeyboard(AConfiguration* config);
+
+/**
+ * Set the current keyboard in the configuration.
+ */
+void AConfiguration_setKeyboard(AConfiguration* config, int32_t keyboard);
+
+/**
+ * Return the current ACONFIGURATION_NAVIGATION_* set in the configuration.
+ */
+int32_t AConfiguration_getNavigation(AConfiguration* config);
+
+/**
+ * Set the current navigation in the configuration.
+ */
+void AConfiguration_setNavigation(AConfiguration* config, int32_t navigation);
+
+/**
+ * Return the current ACONFIGURATION_KEYSHIDDEN_* set in the configuration.
+ */
+int32_t AConfiguration_getKeysHidden(AConfiguration* config);
+
+/**
+ * Set the current keys hidden in the configuration.
+ */
+void AConfiguration_setKeysHidden(AConfiguration* config, int32_t keysHidden);
+
+/**
+ * Return the current ACONFIGURATION_NAVHIDDEN_* set in the configuration.
+ */
+int32_t AConfiguration_getNavHidden(AConfiguration* config);
+
+/**
+ * Set the current nav hidden in the configuration.
+ */
+void AConfiguration_setNavHidden(AConfiguration* config, int32_t navHidden);
+
+/**
+ * Return the current SDK (API) version set in the configuration.
+ */
+int32_t AConfiguration_getSdkVersion(AConfiguration* config);
+
+/**
+ * Set the current SDK version in the configuration.
+ */
+void AConfiguration_setSdkVersion(AConfiguration* config, int32_t sdkVersion);
+
+/**
+ * Return the current ACONFIGURATION_SCREENSIZE_* set in the configuration.
+ */
+int32_t AConfiguration_getScreenSize(AConfiguration* config);
+
+/**
+ * Set the current screen size in the configuration.
+ */
+void AConfiguration_setScreenSize(AConfiguration* config, int32_t screenSize);
+
+/**
+ * Return the current ACONFIGURATION_SCREENLONG_* set in the configuration.
+ */
+int32_t AConfiguration_getScreenLong(AConfiguration* config);
+
+/**
+ * Set the current screen long in the configuration.
+ */
+void AConfiguration_setScreenLong(AConfiguration* config, int32_t screenLong);
+
+/**
+ * Return the current ACONFIGURATION_UI_MODE_TYPE_* set in the configuration.
+ */
+int32_t AConfiguration_getUiModeType(AConfiguration* config);
+
+/**
+ * Set the current UI mode type in the configuration.
+ */
+void AConfiguration_setUiModeType(AConfiguration* config, int32_t uiModeType);
+
+/**
+ * Return the current ACONFIGURATION_UI_MODE_NIGHT_* set in the configuration.
+ */
+int32_t AConfiguration_getUiModeNight(AConfiguration* config);
+
+/**
+ * Set the current UI mode night in the configuration.
+ */
+void AConfiguration_setUiModeNight(AConfiguration* config, int32_t uiModeNight);
+
+/**
+ * Perform a diff between two configurations. Returns a bit mask of
+ * ACONFIGURATION_* constants, each bit set meaning that configuration element
+ * is different between them.
+ */
+int32_t AConfiguration_diff(AConfiguration* config1, AConfiguration* config2);
+
+/**
+ * Determine whether 'base' is a valid configuration for use within the
+ * environment 'requested'. Returns 0 if there are any values in 'base'
+ * that conflict with 'requested'. Returns 1 if it does not conflict.
+ */
+int32_t AConfiguration_match(AConfiguration* base, AConfiguration* requested);
+
+/**
+ * Determine whether the configuration in 'test' is better than the existing
+ * configuration in 'base'. If 'requested' is non-NULL, this decision is based
+ * on the overall configuration given there. If it is NULL, this decision is
+ * simply based on which configuration is more specific. Returns non-0 if
+ * 'test' is better than 'base'.
+ *
+ * This assumes you have already filtered the configurations with
+ * AConfiguration_match().
+ */
+int32_t AConfiguration_isBetterThan(AConfiguration* base, AConfiguration* test,
+ AConfiguration* requested);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // ANDROID_CONFIGURATION_H
diff --git a/native/include/android/native_activity.h b/native/include/android/native_activity.h
index ee4204d..d74e1ce 100644
--- a/native/include/android/native_activity.h
+++ b/native/include/android/native_activity.h
@@ -197,6 +197,12 @@
void (*onContentRectChanged)(ANativeActivity* activity, const ARect* rect);
/**
+ * The current device AConfiguration has changed. The new configuration can
+ * be retrieved from assetManager.
+ */
+ void (*onConfigurationChanged)(ANativeActivity* activity);
+
+ /**
* 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.
@@ -208,7 +214,9 @@
* 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.
+ * the savedState will be non-NULL and point to the saved data. You must make
+ * any copy of this data you need -- it will be released after you return from
+ * this function.
*/
typedef void ANativeActivity_createFunc(ANativeActivity* activity,
void* savedState, size_t savedStateSize);
diff --git a/native/include/android/native_window.h b/native/include/android/native_window.h
index 7599d7e..ad03d0e 100644
--- a/native/include/android/native_window.h
+++ b/native/include/android/native_window.h
@@ -36,12 +36,23 @@
typedef struct ANativeWindow ANativeWindow;
typedef struct ANativeWindow_Buffer {
+ // The number of pixels that are show horizontally.
int32_t width;
+
+ // The number of pixels that are shown vertically.
int32_t height;
+
+ // The number of *pixels* that a line in the buffer takes in
+ // memory. This may be >= width.
int32_t stride;
+
+ // The format of the buffer. One of WINDOW_FORMAT_*
int32_t format;
+
+ // The actual bits.
void* bits;
+ // Do not touch.
uint32_t reserved[6];
} ANativeWindow_Buffer;
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index f1c6532..c6e0a24 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -24,6 +24,8 @@
import android.content.pm.PackageInfoLite;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
+import android.content.res.ObbInfo;
+import android.content.res.ObbScanner;
import android.net.Uri;
import android.os.Environment;
import android.os.IBinder;
@@ -142,6 +144,10 @@
public boolean checkFreeStorage(boolean external, Uri fileUri) {
return checkFreeStorageInner(external, fileUri);
}
+
+ public ObbInfo getObbInfo(String filename) {
+ return ObbScanner.getObbInfo(filename);
+ }
};
public DefaultContainerService() {
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index d7b92ec..344bfc1 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -16,34 +16,42 @@
package com.android.server;
+import com.android.internal.app.IMediaContainerService;
import com.android.server.am.ActivityManagerService;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.res.ObbInfo;
-import android.content.res.ObbScanner;
import android.net.Uri;
-import android.os.storage.IMountService;
-import android.os.storage.IMountServiceListener;
-import android.os.storage.IMountShutdownObserver;
-import android.os.storage.StorageResultCode;
import android.os.Binder;
+import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
+import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
-import android.os.IBinder;
-import android.os.Environment;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.os.storage.IMountService;
+import android.os.storage.IMountServiceListener;
+import android.os.storage.IMountShutdownObserver;
+import android.os.storage.IObbActionListener;
+import android.os.storage.StorageResultCode;
import android.util.Slog;
+
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
/**
* MountService implements back-end services for platform storage
@@ -135,9 +143,77 @@
final private HashSet<String> mAsecMountSet = new HashSet<String>();
/**
- * Private hash of currently mounted filesystem images.
+ * Mounted OBB tracking information. Used to track the current state of all
+ * OBBs.
*/
- final private HashSet<String> mObbMountSet = new HashSet<String>();
+ final private Map<IObbActionListener, ObbState> mObbMounts = new HashMap<IObbActionListener, ObbState>();
+ final private Map<String, ObbState> mObbPathToStateMap = new HashMap<String, ObbState>();
+
+ class ObbState implements IBinder.DeathRecipient {
+ public ObbState(String filename, IObbActionListener token, int callerUid) {
+ this.filename = filename;
+ this.token = token;
+ this.callerUid = callerUid;
+ mounted = false;
+ }
+
+ // OBB source filename
+ String filename;
+
+ // Token of remote Binder caller
+ IObbActionListener token;
+
+ // Binder.callingUid()
+ public int callerUid;
+
+ // Whether this is mounted currently.
+ boolean mounted;
+
+ @Override
+ public void binderDied() {
+ ObbAction action = new UnmountObbAction(this, true);
+ mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_RUN_ACTION, action));
+
+ removeObbState(this);
+
+ token.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+
+ // OBB Action Handler
+ final private ObbActionHandler mObbActionHandler;
+
+ // OBB action handler messages
+ private static final int OBB_RUN_ACTION = 1;
+ private static final int OBB_MCS_BOUND = 2;
+ private static final int OBB_MCS_UNBIND = 3;
+ private static final int OBB_MCS_RECONNECT = 4;
+ private static final int OBB_MCS_GIVE_UP = 5;
+
+ /*
+ * Default Container Service information
+ */
+ static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
+ "com.android.defcontainer", "com.android.defcontainer.DefaultContainerService");
+
+ final private DefaultContainerConnection mDefContainerConn = new DefaultContainerConnection();
+
+ class DefaultContainerConnection implements ServiceConnection {
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ if (DEBUG_OBB)
+ Slog.i(TAG, "onServiceConnected");
+ IMediaContainerService imcs = IMediaContainerService.Stub.asInterface(service);
+ mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_MCS_BOUND, imcs));
+ }
+
+ public void onServiceDisconnected(ComponentName name) {
+ if (DEBUG_OBB)
+ Slog.i(TAG, "onServiceDisconnected");
+ }
+ };
+
+ // Used in the ObbActionHandler
+ private IMediaContainerService mContainerService = null;
// Handler messages
private static final int H_UNMOUNT_PM_UPDATE = 1;
@@ -359,7 +435,7 @@
public void binderDied() {
if (LOCAL_LOGD) Slog.d(TAG, "An IMountServiceListener has died!");
- synchronized(mListeners) {
+ synchronized (mListeners) {
mListeners.remove(this);
mListener.asBinder().unlinkToDeath(this, 0);
}
@@ -904,6 +980,9 @@
mHandlerThread.start();
mHandler = new MountServiceHandler(mHandlerThread.getLooper());
+ // Add OBB Action Handler to MountService thread.
+ mObbActionHandler = new ObbActionHandler(mHandlerThread.getLooper());
+
/*
* Vold does not run in the simulator, so pretend the connector thread
* ran and did its thing.
@@ -1338,12 +1417,16 @@
mHandler.sendEmptyMessage(H_UNMOUNT_PM_DONE);
}
- private boolean isCallerOwnerOfPackage(String packageName) {
+ private boolean isCallerOwnerOfPackageOrSystem(String packageName) {
final int callerUid = Binder.getCallingUid();
- return isUidOwnerOfPackage(packageName, callerUid);
+ return isUidOwnerOfPackageOrSystem(packageName, callerUid);
}
- private boolean isUidOwnerOfPackage(String packageName, int callerUid) {
+ private boolean isUidOwnerOfPackageOrSystem(String packageName, int callerUid) {
+ if (callerUid == android.os.Process.SYSTEM_UID) {
+ return true;
+ }
+
if (packageName == null) {
return false;
}
@@ -1362,12 +1445,6 @@
waitForReady();
warnOnNotMounted();
- // XXX replace with call to IMediaContainerService
- ObbInfo obbInfo = ObbScanner.getObbInfo(filename);
- if (!isCallerOwnerOfPackage(obbInfo.packageName)) {
- throw new IllegalArgumentException("Caller package does not match OBB file");
- }
-
try {
ArrayList<String> rsp = mConnector.doCommand(String.format("obb path %s", filename));
String []tok = rsp.get(0).split(" ");
@@ -1379,7 +1456,7 @@
} catch (NativeDaemonConnectorException e) {
int code = e.getCode();
if (code == VoldResponseCode.OpFailedStorageNotFound) {
- throw new IllegalArgumentException(String.format("OBB '%s' not found", filename));
+ return null;
} else {
throw new IllegalStateException(String.format("Unexpected response code %d", code));
}
@@ -1387,95 +1464,390 @@
}
public boolean isObbMounted(String filename) {
- waitForReady();
- warnOnNotMounted();
-
- // XXX replace with call to IMediaContainerService
- ObbInfo obbInfo = ObbScanner.getObbInfo(filename);
- if (!isCallerOwnerOfPackage(obbInfo.packageName)) {
- throw new IllegalArgumentException("Caller package does not match OBB file");
- }
-
- synchronized (mObbMountSet) {
- return mObbMountSet.contains(filename);
+ synchronized (mObbMounts) {
+ return mObbPathToStateMap.containsKey(filename);
}
}
- public int mountObb(String filename, String key) {
+ public void mountObb(String filename, String key, IObbActionListener token) {
waitForReady();
warnOnNotMounted();
- synchronized (mObbMountSet) {
- if (mObbMountSet.contains(filename)) {
- return StorageResultCode.OperationFailedStorageMounted;
+ final ObbState obbState;
+
+ synchronized (mObbMounts) {
+ if (isObbMounted(filename)) {
+ throw new IllegalArgumentException("OBB file is already mounted");
}
+
+ if (mObbMounts.containsKey(token)) {
+ throw new IllegalArgumentException("You may only have one OBB mounted at a time");
+ }
+
+ final int callerUid = Binder.getCallingUid();
+ obbState = new ObbState(filename, token, callerUid);
+ addObbState(obbState);
}
- final int callerUid = Binder.getCallingUid();
-
- // XXX replace with call to IMediaContainerService
- ObbInfo obbInfo = ObbScanner.getObbInfo(filename);
- if (!isUidOwnerOfPackage(obbInfo.packageName, callerUid)) {
- throw new IllegalArgumentException("Caller package does not match OBB file");
- }
-
- if (key == null) {
- key = "none";
- }
-
- int rc = StorageResultCode.OperationSucceeded;
- String cmd = String.format("obb mount %s %s %d", filename, key, callerUid);
try {
- mConnector.doCommand(cmd);
- } catch (NativeDaemonConnectorException e) {
- int code = e.getCode();
- if (code != VoldResponseCode.OpFailedStorageBusy) {
- rc = StorageResultCode.OperationFailedInternalError;
- }
+ token.asBinder().linkToDeath(obbState, 0);
+ } catch (RemoteException rex) {
+ Slog.e(TAG, "Failed to link to listener death");
}
- if (rc == StorageResultCode.OperationSucceeded) {
- synchronized (mObbMountSet) {
- mObbMountSet.add(filename);
- }
- }
- return rc;
+ MountObbAction action = new MountObbAction(obbState, key);
+ mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_RUN_ACTION, action));
+
+ if (DEBUG_OBB)
+ Slog.i(TAG, "Send to OBB handler: " + action.toString());
}
- public int unmountObb(String filename, boolean force) {
- waitForReady();
- warnOnNotMounted();
+ public void unmountObb(String filename, boolean force, IObbActionListener token) {
+ final ObbState obbState;
- ObbInfo obbInfo = ObbScanner.getObbInfo(filename);
- if (!isCallerOwnerOfPackage(obbInfo.packageName)) {
- throw new IllegalArgumentException("Caller package does not match OBB file");
+ synchronized (mObbMounts) {
+ if (!isObbMounted(filename)) {
+ throw new IllegalArgumentException("OBB is not mounted");
+ }
+ obbState = mObbPathToStateMap.get(filename);
}
- synchronized (mObbMountSet) {
- if (!mObbMountSet.contains(filename)) {
- return StorageResultCode.OperationFailedStorageNotMounted;
- }
- }
+ UnmountObbAction action = new UnmountObbAction(obbState, force);
+ mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_RUN_ACTION, action));
- int rc = StorageResultCode.OperationSucceeded;
- String cmd = String.format("obb unmount %s%s", filename, (force ? " force" : ""));
- try {
- mConnector.doCommand(cmd);
- } catch (NativeDaemonConnectorException e) {
- int code = e.getCode();
- if (code == VoldResponseCode.OpFailedStorageBusy) {
- rc = StorageResultCode.OperationFailedStorageBusy;
+ if (DEBUG_OBB)
+ Slog.i(TAG, "Send to OBB handler: " + action.toString());
+ }
+
+ private void addObbState(ObbState obbState) {
+ synchronized (mObbMounts) {
+ mObbMounts.put(obbState.token, obbState);
+ mObbPathToStateMap.put(obbState.filename, obbState);
+ }
+ }
+
+ private void removeObbState(ObbState obbState) {
+ synchronized (mObbMounts) {
+ mObbMounts.remove(obbState.token);
+ mObbPathToStateMap.remove(obbState.filename);
+ }
+ }
+
+ private class ObbActionHandler extends Handler {
+ private boolean mBound = false;
+ private List<ObbAction> mActions = new LinkedList<ObbAction>();
+
+ ObbActionHandler(Looper l) {
+ super(l);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case OBB_RUN_ACTION: {
+ ObbAction action = (ObbAction) msg.obj;
+
+ if (DEBUG_OBB)
+ Slog.i(TAG, "OBB_RUN_ACTION: " + action.toString());
+
+ // If a bind was already initiated we don't really
+ // need to do anything. The pending install
+ // will be processed later on.
+ if (!mBound) {
+ // If this is the only one pending we might
+ // have to bind to the service again.
+ if (!connectToService()) {
+ Slog.e(TAG, "Failed to bind to media container service");
+ action.handleError();
+ return;
+ } else {
+ // Once we bind to the service, the first
+ // pending request will be processed.
+ mActions.add(action);
+ }
+ } else {
+ // Already bound to the service. Just make
+ // sure we trigger off processing the first request.
+ if (mActions.size() == 0) {
+ mObbActionHandler.sendEmptyMessage(OBB_MCS_BOUND);
+ }
+
+ mActions.add(action);
+ }
+ break;
+ }
+ case OBB_MCS_BOUND: {
+ if (DEBUG_OBB)
+ Slog.i(TAG, "OBB_MCS_BOUND");
+ if (msg.obj != null) {
+ mContainerService = (IMediaContainerService) msg.obj;
+ }
+ if (mContainerService == null) {
+ // Something seriously wrong. Bail out
+ Slog.e(TAG, "Cannot bind to media container service");
+ for (ObbAction action : mActions) {
+ // Indicate service bind error
+ action.handleError();
+ }
+ mActions.clear();
+ } else if (mActions.size() > 0) {
+ ObbAction action = mActions.get(0);
+ if (action != null) {
+ action.execute(this);
+ }
+ } else {
+ // Should never happen ideally.
+ Slog.w(TAG, "Empty queue");
+ }
+ break;
+ }
+ case OBB_MCS_RECONNECT: {
+ if (DEBUG_OBB)
+ Slog.i(TAG, "OBB_MCS_RECONNECT");
+ if (mActions.size() > 0) {
+ if (mBound) {
+ disconnectService();
+ }
+ if (!connectToService()) {
+ Slog.e(TAG, "Failed to bind to media container service");
+ for (ObbAction action : mActions) {
+ // Indicate service bind error
+ action.handleError();
+ }
+ mActions.clear();
+ }
+ }
+ break;
+ }
+ case OBB_MCS_UNBIND: {
+ if (DEBUG_OBB)
+ Slog.i(TAG, "OBB_MCS_UNBIND");
+
+ // Delete pending install
+ if (mActions.size() > 0) {
+ mActions.remove(0);
+ }
+ if (mActions.size() == 0) {
+ if (mBound) {
+ disconnectService();
+ }
+ } else {
+ // There are more pending requests in queue.
+ // Just post MCS_BOUND message to trigger processing
+ // of next pending install.
+ mObbActionHandler.sendEmptyMessage(OBB_MCS_BOUND);
+ }
+ break;
+ }
+ case OBB_MCS_GIVE_UP: {
+ if (DEBUG_OBB)
+ Slog.i(TAG, "OBB_MCS_GIVE_UP");
+ mActions.remove(0);
+ break;
+ }
+ }
+ }
+
+ private boolean connectToService() {
+ if (DEBUG_OBB)
+ Slog.i(TAG, "Trying to bind to DefaultContainerService");
+
+ Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
+ if (mContext.bindService(service, mDefContainerConn, Context.BIND_AUTO_CREATE)) {
+ mBound = true;
+ return true;
+ }
+ return false;
+ }
+
+ private void disconnectService() {
+ mContainerService = null;
+ mBound = false;
+ mContext.unbindService(mDefContainerConn);
+ }
+ }
+
+ abstract class ObbAction {
+ private static final int MAX_RETRIES = 3;
+ private int mRetries;
+
+ ObbState mObbState;
+
+ ObbAction(ObbState obbState) {
+ mObbState = obbState;
+ }
+
+ public void execute(ObbActionHandler handler) {
+ try {
+ if (DEBUG_OBB)
+ Slog.i(TAG, "Starting to execute action: " + this.toString());
+ mRetries++;
+ if (mRetries > MAX_RETRIES) {
+ Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
+ mObbActionHandler.sendEmptyMessage(OBB_MCS_GIVE_UP);
+ handleError();
+ return;
+ } else {
+ handleExecute();
+ if (DEBUG_OBB)
+ Slog.i(TAG, "Posting install MCS_UNBIND");
+ mObbActionHandler.sendEmptyMessage(OBB_MCS_UNBIND);
+ }
+ } catch (RemoteException e) {
+ if (DEBUG_OBB)
+ Slog.i(TAG, "Posting install MCS_RECONNECT");
+ mObbActionHandler.sendEmptyMessage(OBB_MCS_RECONNECT);
+ } catch (Exception e) {
+ if (DEBUG_OBB)
+ Slog.d(TAG, "Error handling OBB action", e);
+ handleError();
+ }
+ }
+
+ abstract void handleExecute() throws RemoteException;
+ abstract void handleError();
+ }
+
+ class MountObbAction extends ObbAction {
+ private String mKey;
+
+ MountObbAction(ObbState obbState, String key) {
+ super(obbState);
+ mKey = key;
+ }
+
+ public void handleExecute() throws RemoteException {
+ ObbInfo obbInfo = mContainerService.getObbInfo(mObbState.filename);
+ if (!isUidOwnerOfPackageOrSystem(obbInfo.packageName, mObbState.callerUid)) {
+ throw new IllegalArgumentException("Caller package does not match OBB file");
+ }
+
+ if (mKey == null) {
+ mKey = "none";
+ }
+
+ int rc = StorageResultCode.OperationSucceeded;
+ String cmd = String.format("obb mount %s %s %d", mObbState.filename, mKey,
+ mObbState.callerUid);
+ try {
+ mConnector.doCommand(cmd);
+ } catch (NativeDaemonConnectorException e) {
+ int code = e.getCode();
+ if (code != VoldResponseCode.OpFailedStorageBusy) {
+ rc = StorageResultCode.OperationFailedInternalError;
+ }
+ }
+
+ if (rc == StorageResultCode.OperationSucceeded) {
+ try {
+ mObbState.token.onObbResult(mObbState.filename, "mounted");
+ } catch (RemoteException e) {
+ Slog.w(TAG, "MountServiceListener went away while calling onObbStateChanged");
+ }
} else {
- rc = StorageResultCode.OperationFailedInternalError;
+ Slog.e(TAG, "Couldn't mount OBB file");
+
+ // We didn't succeed, so remove this from the mount-set.
+ removeObbState(mObbState);
}
}
- if (rc == StorageResultCode.OperationSucceeded) {
- synchronized (mObbMountSet) {
- mObbMountSet.remove(filename);
+ public void handleError() {
+ removeObbState(mObbState);
+
+ try {
+ mObbState.token.onObbResult(mObbState.filename, "error");
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Couldn't send back OBB mount error for " + mObbState.filename);
}
}
- return rc;
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("MountObbAction{");
+ sb.append("filename=");
+ sb.append(mObbState.filename);
+ sb.append(",callerUid=");
+ sb.append(mObbState.callerUid);
+ sb.append(",token=");
+ sb.append(mObbState.token != null ? mObbState.token.toString() : "NULL");
+ sb.append('}');
+ return sb.toString();
+ }
+ }
+
+ class UnmountObbAction extends ObbAction {
+ private boolean mForceUnmount;
+
+ UnmountObbAction(ObbState obbState, boolean force) {
+ super(obbState);
+ mForceUnmount = force;
+ }
+
+ public void handleExecute() throws RemoteException {
+ ObbInfo obbInfo = mContainerService.getObbInfo(mObbState.filename);
+
+ if (!isCallerOwnerOfPackageOrSystem(obbInfo.packageName)) {
+ throw new IllegalArgumentException("Caller package does not match OBB file");
+ }
+
+ int rc = StorageResultCode.OperationSucceeded;
+ String cmd = String.format("obb unmount %s%s", mObbState.filename,
+ (mForceUnmount ? " force" : ""));
+ try {
+ mConnector.doCommand(cmd);
+ } catch (NativeDaemonConnectorException e) {
+ int code = e.getCode();
+ if (code == VoldResponseCode.OpFailedStorageBusy) {
+ rc = StorageResultCode.OperationFailedStorageBusy;
+ } else {
+ rc = StorageResultCode.OperationFailedInternalError;
+ }
+ }
+
+ if (rc == StorageResultCode.OperationSucceeded) {
+ removeObbState(mObbState);
+
+ try {
+ mObbState.token.onObbResult(mObbState.filename, "unmounted");
+ } catch (RemoteException e) {
+ Slog.w(TAG, "MountServiceListener went away while calling onObbStateChanged");
+ }
+ } else {
+ try {
+ mObbState.token.onObbResult(mObbState.filename, "error");
+ } catch (RemoteException e) {
+ Slog.w(TAG, "MountServiceListener went away while calling onObbStateChanged");
+ }
+ }
+ }
+
+ public void handleError() {
+ removeObbState(mObbState);
+
+ try {
+ mObbState.token.onObbResult(mObbState.filename, "error");
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Couldn't send back OBB unmount error for " + mObbState.filename);
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("UnmountObbAction{");
+ sb.append("filename=");
+ sb.append(mObbState.filename != null ? mObbState.filename : "null");
+ sb.append(",force=");
+ sb.append(mForceUnmount);
+ sb.append(",callerUid=");
+ sb.append(mObbState.callerUid);
+ sb.append(",token=");
+ sb.append(mObbState.token != null ? mObbState.token.toString() : "null");
+ sb.append('}');
+ return sb.toString();
+ }
}
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 162fffe..dff6a8a 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3571,6 +3571,7 @@
if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
// Tell anyone interested that we are done booting!
+ SystemProperties.set("sys.boot_completed", "1");
broadcastIntentLocked(null, null,
new Intent(Intent.ACTION_BOOT_COMPLETED, null),
null, null, 0, null, null,
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
index b57f358..4dc1991 100644
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ b/telephony/java/com/android/internal/telephony/CallManager.java
@@ -215,7 +215,7 @@
* @param phone
*/
public void unregisterPhone(Phone phone) {
- if (phone != null && !mPhones.contains(phone)) {
+ if (phone != null && mPhones.contains(phone)) {
mPhones.remove(phone);
mRingingCalls.remove(phone.getRingingCall());
mBackgroundCalls.remove(phone.getBackgroundCall());
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index edc1f8a..a94518f 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -102,6 +102,10 @@
return mProfile.getProfileName();
}
+ public String getSipUri() {
+ return mProfile.getUriString();
+ }
+
public boolean canTake(Object incomingCall) {
synchronized (SipPhone.class) {
if (!(incomingCall instanceof SipAudioCall)) return false;
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhoneFactory.java b/telephony/java/com/android/internal/telephony/sip/SipPhoneFactory.java
index a1bdd2f..611e3ea 100644
--- a/telephony/java/com/android/internal/telephony/sip/SipPhoneFactory.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhoneFactory.java
@@ -42,7 +42,7 @@
SipProfile profile = new SipProfile.Builder(sipUri).build();
return new SipPhone(context, phoneNotifier, profile);
} catch (ParseException e) {
- Log.w("SipPhoneProxy", "setPhone", e);
+ Log.w("SipPhoneFactory", "makePhone", e);
return null;
}
}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhoneProxy.java b/telephony/java/com/android/internal/telephony/sip/SipPhoneProxy.java
deleted file mode 100644
index 7cc1a9b..0000000
--- a/telephony/java/com/android/internal/telephony/sip/SipPhoneProxy.java
+++ /dev/null
@@ -1,749 +0,0 @@
-/*
- * 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.telephony.sip;
-
-import com.android.internal.telephony.*;
-import com.android.internal.telephony.gsm.NetworkInfo;
-import com.android.internal.telephony.test.SimulatedRadioControl;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Message;
-import android.telephony.CellLocation;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.util.Log;
-
-import java.util.List;
-
-/**
- * Temporary. Will be removed after integrating with CallManager.
- * (TODO)
- * @hide
- */
-public class SipPhoneProxy implements Phone {
- private static final String LOG_TAG = "PHONE";
-
- private static SipPhoneProxy sPhoneProxy = new SipPhoneProxy();
-
- public static SipPhoneProxy getInstance() {
- return sPhoneProxy;
- }
-
- private SipPhone mActivePhone;
- private CallProxy mRingingCall = new CallProxy();
- private CallProxy mForegroundCall = new CallProxy();
- private CallProxy mBackgroundCall = new CallProxy();
-
- private SipPhoneProxy() {
- }
-
- public void onNewCall(Object call) {
- if (mActivePhone.canTake(call)) {
- Log.v("SipPhoneProxy", "onNewCall(): call taken: " + call);
- } else {
- Log.v("SipPhoneProxy", "onNewCall(): call dropped: " + call);
- }
- }
-
- public synchronized void setPhone(SipPhone phone) {
- if (phone == null) return;
- if (mActivePhone != null) phone.migrateFrom(mActivePhone);
- mActivePhone = phone;
- mForegroundCall.setTarget(phone.getForegroundCall());
- mBackgroundCall.setTarget(phone.getBackgroundCall());
- mRingingCall.setTarget(phone.getRingingCall());
- }
-
- public synchronized Call getForegroundCall() {
- return mForegroundCall;
- }
-
- public synchronized Call getBackgroundCall() {
- return mBackgroundCall;
- }
-
- public synchronized Call getRingingCall() {
- return mRingingCall;
- }
-
-
- public ServiceState getServiceState() {
- return mActivePhone.getServiceState();
- }
-
- public CellLocation getCellLocation() {
- return mActivePhone.getCellLocation();
- }
-
- public DataState getDataConnectionState() {
- return mActivePhone.getDataConnectionState();
- }
-
- public DataActivityState getDataActivityState() {
- return mActivePhone.getDataActivityState();
- }
-
- public Context getContext() {
- return mActivePhone.getContext();
- }
-
- public void disableDnsCheck(boolean b) {
- mActivePhone.disableDnsCheck(b);
- }
-
- public boolean isDnsCheckDisabled() {
- return mActivePhone.isDnsCheckDisabled();
- }
-
- public State getState() {
- return mActivePhone.getState();
- }
-
- public String getPhoneName() {
- return mActivePhone.getPhoneName();
- }
-
- public int getPhoneType() {
- return mActivePhone.getPhoneType();
- }
-
- public String[] getActiveApnTypes() {
- return mActivePhone.getActiveApnTypes();
- }
-
- public String getActiveApn() {
- return mActivePhone.getActiveApn();
- }
-
- public SignalStrength getSignalStrength() {
- return mActivePhone.getSignalStrength();
- }
-
- public void registerForUnknownConnection(Handler h, int what, Object obj) {
- mActivePhone.registerForUnknownConnection(h, what, obj);
- }
-
- public void unregisterForUnknownConnection(Handler h) {
- mActivePhone.unregisterForUnknownConnection(h);
- }
-
- public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) {
- mActivePhone.registerForPreciseCallStateChanged(h, what, obj);
- }
-
- public void unregisterForPreciseCallStateChanged(Handler h) {
- mActivePhone.unregisterForPreciseCallStateChanged(h);
- }
-
- public void registerForNewRingingConnection(Handler h, int what, Object obj) {
- mActivePhone.registerForNewRingingConnection(h, what, obj);
- }
-
- public void unregisterForNewRingingConnection(Handler h) {
- mActivePhone.unregisterForNewRingingConnection(h);
- }
-
- public void registerForIncomingRing(Handler h, int what, Object obj) {
- mActivePhone.registerForIncomingRing(h, what, obj);
- }
-
- public void unregisterForIncomingRing(Handler h) {
- mActivePhone.unregisterForIncomingRing(h);
- }
-
- public void registerForDisconnect(Handler h, int what, Object obj) {
- mActivePhone.registerForDisconnect(h, what, obj);
- }
-
- public void unregisterForDisconnect(Handler h) {
- mActivePhone.unregisterForDisconnect(h);
- }
-
- public void registerForMmiInitiate(Handler h, int what, Object obj) {
- mActivePhone.registerForMmiInitiate(h, what, obj);
- }
-
- public void unregisterForMmiInitiate(Handler h) {
- mActivePhone.unregisterForMmiInitiate(h);
- }
-
- public void registerForMmiComplete(Handler h, int what, Object obj) {
- mActivePhone.registerForMmiComplete(h, what, obj);
- }
-
- public void unregisterForMmiComplete(Handler h) {
- mActivePhone.unregisterForMmiComplete(h);
- }
-
- public List<? extends MmiCode> getPendingMmiCodes() {
- return mActivePhone.getPendingMmiCodes();
- }
-
- public void sendUssdResponse(String ussdMessge) {
- mActivePhone.sendUssdResponse(ussdMessge);
- }
-
- public void registerForServiceStateChanged(Handler h, int what, Object obj) {
- mActivePhone.registerForServiceStateChanged(h, what, obj);
- }
-
- public void unregisterForServiceStateChanged(Handler h) {
- mActivePhone.unregisterForServiceStateChanged(h);
- }
-
- public void registerForSuppServiceNotification(Handler h, int what, Object obj) {
- mActivePhone.registerForSuppServiceNotification(h, what, obj);
- }
-
- public void unregisterForSuppServiceNotification(Handler h) {
- mActivePhone.unregisterForSuppServiceNotification(h);
- }
-
- public void registerForSuppServiceFailed(Handler h, int what, Object obj) {
- mActivePhone.registerForSuppServiceFailed(h, what, obj);
- }
-
- public void unregisterForSuppServiceFailed(Handler h) {
- mActivePhone.unregisterForSuppServiceFailed(h);
- }
-
- public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
- mActivePhone.registerForInCallVoicePrivacyOn(h,what,obj);
- }
-
- public void unregisterForInCallVoicePrivacyOn(Handler h){
- mActivePhone.unregisterForInCallVoicePrivacyOn(h);
- }
-
- public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
- mActivePhone.registerForInCallVoicePrivacyOff(h,what,obj);
- }
-
- public void unregisterForInCallVoicePrivacyOff(Handler h){
- mActivePhone.unregisterForInCallVoicePrivacyOff(h);
- }
-
- public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
- mActivePhone.registerForCdmaOtaStatusChange(h,what,obj);
- }
-
- public void unregisterForCdmaOtaStatusChange(Handler h) {
- mActivePhone.unregisterForCdmaOtaStatusChange(h);
- }
-
- public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
- mActivePhone.registerForSubscriptionInfoReady(h, what, obj);
- }
-
- public void unregisterForSubscriptionInfoReady(Handler h) {
- mActivePhone.unregisterForSubscriptionInfoReady(h);
- }
-
- public void registerForEcmTimerReset(Handler h, int what, Object obj) {
- mActivePhone.registerForEcmTimerReset(h,what,obj);
- }
-
- public void unregisterForEcmTimerReset(Handler h) {
- mActivePhone.unregisterForEcmTimerReset(h);
- }
-
- public void registerForRingbackTone(Handler h, int what, Object obj) {
- mActivePhone.registerForRingbackTone(h,what,obj);
- }
-
- public void unregisterForRingbackTone(Handler h) {
- mActivePhone.unregisterForRingbackTone(h);
- }
-
- public void registerForResendIncallMute(Handler h, int what, Object obj) {
- mActivePhone.registerForResendIncallMute(h,what,obj);
- }
-
- public void unregisterForResendIncallMute(Handler h) {
- mActivePhone.unregisterForResendIncallMute(h);
- }
-
- public boolean getIccRecordsLoaded() {
- return mActivePhone.getIccRecordsLoaded();
- }
-
- public IccCard getIccCard() {
- return mActivePhone.getIccCard();
- }
-
- public void acceptCall() throws CallStateException {
- mActivePhone.acceptCall();
- }
-
- public void rejectCall() throws CallStateException {
- mActivePhone.rejectCall();
- }
-
- public void switchHoldingAndActive() throws CallStateException {
- mActivePhone.switchHoldingAndActive();
- }
-
- public boolean canConference() {
- return mActivePhone.canConference();
- }
-
- public void conference() throws CallStateException {
- mActivePhone.conference();
- }
-
- public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
- mActivePhone.enableEnhancedVoicePrivacy(enable, onComplete);
- }
-
- public void getEnhancedVoicePrivacy(Message onComplete) {
- mActivePhone.getEnhancedVoicePrivacy(onComplete);
- }
-
- public boolean canTransfer() {
- return mActivePhone.canTransfer();
- }
-
- public void explicitCallTransfer() throws CallStateException {
- mActivePhone.explicitCallTransfer();
- }
-
- public void clearDisconnected() {
- mActivePhone.clearDisconnected();
- }
-
- public Connection dial(String dialString) throws CallStateException {
- return mActivePhone.dial(dialString);
- }
-
- public Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException {
- return mActivePhone.dial(dialString);
- }
-
- public boolean handlePinMmi(String dialString) {
- return mActivePhone.handlePinMmi(dialString);
- }
-
- public boolean handleInCallMmiCommands(String command) throws CallStateException {
- return mActivePhone.handleInCallMmiCommands(command);
- }
-
- public void sendDtmf(char c) {
- mActivePhone.sendDtmf(c);
- }
-
- public void startDtmf(char c) {
- mActivePhone.startDtmf(c);
- }
-
- public void stopDtmf() {
- mActivePhone.stopDtmf();
- }
-
- public void setRadioPower(boolean power) {
- mActivePhone.setRadioPower(power);
- }
-
- public boolean getMessageWaitingIndicator() {
- return mActivePhone.getMessageWaitingIndicator();
- }
-
- public boolean getCallForwardingIndicator() {
- return mActivePhone.getCallForwardingIndicator();
- }
-
- public String getLine1Number() {
- return mActivePhone.getLine1Number();
- }
-
- public String getCdmaMin() {
- return mActivePhone.getCdmaMin();
- }
-
- public boolean isMinInfoReady() {
- return mActivePhone.isMinInfoReady();
- }
-
- public String getCdmaPrlVersion() {
- return mActivePhone.getCdmaPrlVersion();
- }
-
- public String getLine1AlphaTag() {
- return mActivePhone.getLine1AlphaTag();
- }
-
- public void setLine1Number(String alphaTag, String number, Message onComplete) {
- mActivePhone.setLine1Number(alphaTag, number, onComplete);
- }
-
- public String getVoiceMailNumber() {
- return mActivePhone.getVoiceMailNumber();
- }
-
- /** @hide */
- public int getVoiceMessageCount(){
- return mActivePhone.getVoiceMessageCount();
- }
-
- public String getVoiceMailAlphaTag() {
- return mActivePhone.getVoiceMailAlphaTag();
- }
-
- public void setVoiceMailNumber(String alphaTag,String voiceMailNumber,
- Message onComplete) {
- mActivePhone.setVoiceMailNumber(alphaTag, voiceMailNumber, onComplete);
- }
-
- public void getCallForwardingOption(int commandInterfaceCFReason,
- Message onComplete) {
- mActivePhone.getCallForwardingOption(commandInterfaceCFReason,
- onComplete);
- }
-
- public void setCallForwardingOption(int commandInterfaceCFReason,
- int commandInterfaceCFAction, String dialingNumber,
- int timerSeconds, Message onComplete) {
- mActivePhone.setCallForwardingOption(commandInterfaceCFReason,
- commandInterfaceCFAction, dialingNumber, timerSeconds, onComplete);
- }
-
- public void getOutgoingCallerIdDisplay(Message onComplete) {
- mActivePhone.getOutgoingCallerIdDisplay(onComplete);
- }
-
- public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
- Message onComplete) {
- mActivePhone.setOutgoingCallerIdDisplay(commandInterfaceCLIRMode,
- onComplete);
- }
-
- public void getCallWaiting(Message onComplete) {
- mActivePhone.getCallWaiting(onComplete);
- }
-
- public void setCallWaiting(boolean enable, Message onComplete) {
- mActivePhone.setCallWaiting(enable, onComplete);
- }
-
- public void getAvailableNetworks(Message response) {
- mActivePhone.getAvailableNetworks(response);
- }
-
- public void setNetworkSelectionModeAutomatic(Message response) {
- mActivePhone.setNetworkSelectionModeAutomatic(response);
- }
-
- public void selectNetworkManually(NetworkInfo network, Message response) {
- mActivePhone.selectNetworkManually(network, response);
- }
-
- public void setPreferredNetworkType(int networkType, Message response) {
- mActivePhone.setPreferredNetworkType(networkType, response);
- }
-
- public void getPreferredNetworkType(Message response) {
- mActivePhone.getPreferredNetworkType(response);
- }
-
- public void getNeighboringCids(Message response) {
- mActivePhone.getNeighboringCids(response);
- }
-
- public void setOnPostDialCharacter(Handler h, int what, Object obj) {
- mActivePhone.setOnPostDialCharacter(h, what, obj);
- }
-
- public void setMute(boolean muted) {
- mActivePhone.setMute(muted);
- }
-
- public boolean getMute() {
- return mActivePhone.getMute();
- }
-
- public void invokeOemRilRequestRaw(byte[] data, Message response) {
- mActivePhone.invokeOemRilRequestRaw(data, response);
- }
-
- public void invokeOemRilRequestStrings(String[] strings, Message response) {
- mActivePhone.invokeOemRilRequestStrings(strings, response);
- }
-
- public void getDataCallList(Message response) {
- mActivePhone.getDataCallList(response);
- }
-
- public List<DataConnection> getCurrentDataConnectionList() {
- return mActivePhone.getCurrentDataConnectionList();
- }
-
- public void updateServiceLocation() {
- mActivePhone.updateServiceLocation();
- }
-
- public void enableLocationUpdates() {
- mActivePhone.enableLocationUpdates();
- }
-
- public void disableLocationUpdates() {
- mActivePhone.disableLocationUpdates();
- }
-
- public void setUnitTestMode(boolean f) {
- mActivePhone.setUnitTestMode(f);
- }
-
- public boolean getUnitTestMode() {
- return mActivePhone.getUnitTestMode();
- }
-
- public void setBandMode(int bandMode, Message response) {
- mActivePhone.setBandMode(bandMode, response);
- }
-
- public void queryAvailableBandMode(Message response) {
- mActivePhone.queryAvailableBandMode(response);
- }
-
- public boolean getDataRoamingEnabled() {
- return mActivePhone.getDataRoamingEnabled();
- }
-
- public void setDataRoamingEnabled(boolean enable) {
- mActivePhone.setDataRoamingEnabled(enable);
- }
-
- public void queryCdmaRoamingPreference(Message response) {
- mActivePhone.queryCdmaRoamingPreference(response);
- }
-
- public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
- mActivePhone.setCdmaRoamingPreference(cdmaRoamingType, response);
- }
-
- public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
- mActivePhone.setCdmaSubscription(cdmaSubscriptionType, response);
- }
-
- public SimulatedRadioControl getSimulatedRadioControl() {
- return mActivePhone.getSimulatedRadioControl();
- }
-
- public boolean enableDataConnectivity() {
- return mActivePhone.enableDataConnectivity();
- }
-
- public boolean disableDataConnectivity() {
- return mActivePhone.disableDataConnectivity();
- }
-
- public int enableApnType(String type) {
- return mActivePhone.enableApnType(type);
- }
-
- public int disableApnType(String type) {
- return mActivePhone.disableApnType(type);
- }
-
- public boolean isDataConnectivityEnabled() {
- return mActivePhone.isDataConnectivityEnabled();
- }
-
- public boolean isDataConnectivityPossible() {
- return mActivePhone.isDataConnectivityPossible();
- }
-
- public String getInterfaceName(String apnType) {
- return mActivePhone.getInterfaceName(apnType);
- }
-
- public String getIpAddress(String apnType) {
- return mActivePhone.getIpAddress(apnType);
- }
-
- public String getGateway(String apnType) {
- return mActivePhone.getGateway(apnType);
- }
-
- public String[] getDnsServers(String apnType) {
- return mActivePhone.getDnsServers(apnType);
- }
-
- public String getDeviceId() {
- return mActivePhone.getDeviceId();
- }
-
- public String getDeviceSvn() {
- return mActivePhone.getDeviceSvn();
- }
-
- public String getSubscriberId() {
- return mActivePhone.getSubscriberId();
- }
-
- public String getIccSerialNumber() {
- return mActivePhone.getIccSerialNumber();
- }
-
- public String getEsn() {
- return mActivePhone.getEsn();
- }
-
- public String getMeid() {
- return mActivePhone.getMeid();
- }
-
- public PhoneSubInfo getPhoneSubInfo(){
- return mActivePhone.getPhoneSubInfo();
- }
-
- public IccSmsInterfaceManager getIccSmsInterfaceManager(){
- return mActivePhone.getIccSmsInterfaceManager();
- }
-
- public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){
- return mActivePhone.getIccPhoneBookInterfaceManager();
- }
-
- public void setTTYMode(int ttyMode, Message onComplete) {
- mActivePhone.setTTYMode(ttyMode, onComplete);
- }
-
- public void queryTTYMode(Message onComplete) {
- mActivePhone.queryTTYMode(onComplete);
- }
-
- public void activateCellBroadcastSms(int activate, Message response) {
- mActivePhone.activateCellBroadcastSms(activate, response);
- }
-
- public void getCellBroadcastSmsConfig(Message response) {
- mActivePhone.getCellBroadcastSmsConfig(response);
- }
-
- public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response) {
- mActivePhone.setCellBroadcastSmsConfig(configValuesArray, response);
- }
-
- public void notifyDataActivity() {
- mActivePhone.notifyDataActivity();
- }
-
- public void getSmscAddress(Message result) {
- mActivePhone.getSmscAddress(result);
- }
-
- public void setSmscAddress(String address, Message result) {
- mActivePhone.setSmscAddress(address, result);
- }
-
- public int getCdmaEriIconIndex() {
- return mActivePhone.getCdmaEriIconIndex();
- }
-
- public String getCdmaEriText() {
- return mActivePhone.getCdmaEriText();
- }
-
- public int getCdmaEriIconMode() {
- return mActivePhone.getCdmaEriIconMode();
- }
-
- public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete){
- mActivePhone.sendBurstDtmf(dtmfString, on, off, onComplete);
- }
-
- public void exitEmergencyCallbackMode(){
- mActivePhone.exitEmergencyCallbackMode();
- }
-
- public boolean isOtaSpNumber(String dialStr){
- return mActivePhone.isOtaSpNumber(dialStr);
- }
-
- public void registerForCallWaiting(Handler h, int what, Object obj){
- mActivePhone.registerForCallWaiting(h,what,obj);
- }
-
- public void unregisterForCallWaiting(Handler h){
- mActivePhone.unregisterForCallWaiting(h);
- }
-
- public void registerForSignalInfo(Handler h, int what, Object obj) {
- mActivePhone.registerForSignalInfo(h,what,obj);
- }
-
- public void unregisterForSignalInfo(Handler h) {
- mActivePhone.unregisterForSignalInfo(h);
- }
-
- public void registerForDisplayInfo(Handler h, int what, Object obj) {
- mActivePhone.registerForDisplayInfo(h,what,obj);
- }
-
- public void unregisterForDisplayInfo(Handler h) {
- mActivePhone.unregisterForDisplayInfo(h);
- }
-
- public void registerForNumberInfo(Handler h, int what, Object obj) {
- mActivePhone.registerForNumberInfo(h, what, obj);
- }
-
- public void unregisterForNumberInfo(Handler h) {
- mActivePhone.unregisterForNumberInfo(h);
- }
-
- public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
- mActivePhone.registerForRedirectedNumberInfo(h, what, obj);
- }
-
- public void unregisterForRedirectedNumberInfo(Handler h) {
- mActivePhone.unregisterForRedirectedNumberInfo(h);
- }
-
- public void registerForLineControlInfo(Handler h, int what, Object obj) {
- mActivePhone.registerForLineControlInfo( h, what, obj);
- }
-
- public void unregisterForLineControlInfo(Handler h) {
- mActivePhone.unregisterForLineControlInfo(h);
- }
-
- public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
- mActivePhone.registerFoT53ClirlInfo(h, what, obj);
- }
-
- public void unregisterForT53ClirInfo(Handler h) {
- mActivePhone.unregisterForT53ClirInfo(h);
- }
-
- public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
- mActivePhone.registerForT53AudioControlInfo( h, what, obj);
- }
-
- public void unregisterForT53AudioControlInfo(Handler h) {
- mActivePhone.unregisterForT53AudioControlInfo(h);
- }
-
- public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
- mActivePhone.setOnEcbModeExitResponse(h,what,obj);
- }
-
- public void unsetOnEcbModeExitResponse(Handler h){
- mActivePhone.unsetOnEcbModeExitResponse(h);
- }
-}
diff --git a/tools/obbtool/Android.mk b/tools/obbtool/Android.mk
new file mode 100644
index 0000000..b02c1cb
--- /dev/null
+++ b/tools/obbtool/Android.mk
@@ -0,0 +1,30 @@
+#
+# Copyright 2010 The Android Open Source Project
+#
+# Opaque Binary Blob (OBB) Tool
+#
+
+# This tool is prebuilt if we're doing an app-only build.
+ifeq ($(TARGET_BUILD_APPS),)
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ Main.cpp
+
+#LOCAL_C_INCLUDES +=
+
+LOCAL_STATIC_LIBRARIES := \
+ libutils \
+ libcutils
+
+ifeq ($(HOST_OS),linux)
+LOCAL_LDLIBS += -lpthread
+endif
+
+LOCAL_MODULE := obbtool
+
+include $(BUILD_HOST_EXECUTABLE)
+
+endif # TARGET_BUILD_APPS
diff --git a/tools/obbtool/Main.cpp b/tools/obbtool/Main.cpp
new file mode 100644
index 0000000..2a9bf04
--- /dev/null
+++ b/tools/obbtool/Main.cpp
@@ -0,0 +1,225 @@
+/*
+ * 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.
+ */
+
+#include <utils/ObbFile.h>
+#include <utils/String8.h>
+
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+using namespace android;
+
+static const char* gProgName = "obbtool";
+static const char* gProgVersion = "1.0";
+
+static int wantUsage = 0;
+static int wantVersion = 0;
+
+#define ADD_OPTS "n:v:f:c:"
+static const struct option longopts[] = {
+ {"help", no_argument, &wantUsage, 1},
+ {"version", no_argument, &wantVersion, 1},
+
+ /* Args for "add" */
+ {"name", required_argument, NULL, 'n'},
+ {"version", required_argument, NULL, 'v'},
+ {"filesystem", required_argument, NULL, 'f'},
+ {"crypto", required_argument, NULL, 'c'},
+
+ {NULL, 0, NULL, '\0'}
+};
+
+struct package_info_t {
+ char* packageName;
+ int packageVersion;
+ char* filesystem;
+ char* crypto;
+};
+
+/*
+ * Print usage info.
+ */
+void usage(void)
+{
+ fprintf(stderr, "Opaque Binary Blob (OBB) Tool\n\n");
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr,
+ " %s a[dd] [ OPTIONS ] FILENAME\n"
+ " Adds an OBB signature to the file.\n\n", gProgName);
+ fprintf(stderr,
+ " %s r[emove] FILENAME\n"
+ " Removes the OBB signature from the file.\n\n", gProgName);
+ fprintf(stderr,
+ " %s i[nfo] FILENAME\n"
+ " Prints the OBB signature information of a file.\n\n", gProgName);
+}
+
+void doAdd(const char* filename, struct package_info_t* info) {
+ ObbFile *obb = new ObbFile();
+ if (obb->readFrom(filename)) {
+ fprintf(stderr, "ERROR: %s: OBB signature already present\n", filename);
+ return;
+ }
+
+ obb->setPackageName(String8(info->packageName));
+ obb->setVersion(info->packageVersion);
+
+ if (!obb->writeTo(filename)) {
+ fprintf(stderr, "ERROR: %s: couldn't write OBB signature: %s\n",
+ filename, strerror(errno));
+ return;
+ }
+
+ fprintf(stderr, "OBB signature successfully written\n");
+}
+
+void doRemove(const char* filename) {
+ ObbFile *obb = new ObbFile();
+ if (!obb->readFrom(filename)) {
+ fprintf(stderr, "ERROR: %s: no OBB signature present\n", filename);
+ return;
+ }
+
+ if (!obb->removeFrom(filename)) {
+ fprintf(stderr, "ERROR: %s: couldn't remove OBB signature\n", filename);
+ return;
+ }
+
+ fprintf(stderr, "OBB signature successfully removed\n");
+}
+
+void doInfo(const char* filename) {
+ ObbFile *obb = new ObbFile();
+ if (!obb->readFrom(filename)) {
+ fprintf(stderr, "ERROR: %s: couldn't read OBB signature\n", filename);
+ return;
+ }
+
+ printf("OBB info for '%s':\n", filename);
+ printf("Package name: %s\n", obb->getPackageName().string());
+ printf(" Version: %d\n", obb->getVersion());
+}
+
+/*
+ * Parse args.
+ */
+int main(int argc, char* const argv[])
+{
+ const char *prog = argv[0];
+ struct options *options;
+ int opt;
+ int option_index = 0;
+ struct package_info_t package_info;
+
+ int result = 1; // pessimistically assume an error.
+
+ if (argc < 2) {
+ wantUsage = 1;
+ goto bail;
+ }
+
+ while ((opt = getopt_long(argc, argv, ADD_OPTS, longopts, &option_index)) != -1) {
+ switch (opt) {
+ case 0:
+ if (longopts[option_index].flag)
+ break;
+ fprintf(stderr, "'%s' requires an argument\n", longopts[option_index].name);
+ wantUsage = 1;
+ goto bail;
+ case 'n':
+ package_info.packageName = optarg;
+ break;
+ case 'v':
+ char *end;
+ package_info.packageVersion = strtol(optarg, &end, 10);
+ if (*optarg == '\0' || *end != '\0') {
+ fprintf(stderr, "ERROR: invalid version; should be integer!\n\n");
+ wantUsage = 1;
+ goto bail;
+ }
+ break;
+ case 'f':
+ package_info.filesystem = optarg;
+ break;
+ case 'c':
+ package_info.crypto = optarg;
+ break;
+ case '?':
+ wantUsage = 1;
+ goto bail;
+ }
+ }
+
+ if (wantVersion) {
+ fprintf(stderr, "%s %s\n", gProgName, gProgVersion);
+ }
+
+ if (wantUsage) {
+ goto bail;
+ }
+
+#define CHECK_OP(name) \
+ if (strncmp(op, name, opsize)) { \
+ fprintf(stderr, "ERROR: unknown function '%s'!\n\n", op); \
+ wantUsage = 1; \
+ goto bail; \
+ }
+
+ if (optind < argc) {
+ const char* op = argv[optind++];
+ const int opsize = strlen(op);
+
+ if (optind >= argc) {
+ fprintf(stderr, "ERROR: filename required!\n\n");
+ wantUsage = 1;
+ goto bail;
+ }
+
+ const char* filename = argv[optind++];
+
+ switch (op[0]) {
+ case 'a':
+ CHECK_OP("add");
+ if (package_info.packageName == NULL) {
+ fprintf(stderr, "ERROR: arguments required 'packageName' and 'version'\n");
+ goto bail;
+ }
+ doAdd(filename, &package_info);
+ break;
+ case 'r':
+ CHECK_OP("remove");
+ doRemove(filename);
+ break;
+ case 'i':
+ CHECK_OP("info");
+ doInfo(filename);
+ break;
+ default:
+ fprintf(stderr, "ERROR: unknown command '%s'!\n\n", op);
+ wantUsage = 1;
+ goto bail;
+ }
+ }
+
+bail:
+ if (wantUsage) {
+ usage();
+ result = 2;
+ }
+
+ return result;
+}
diff --git a/voip/java/android/net/sip/SipAudioCallImpl.java b/voip/java/android/net/sip/SipAudioCallImpl.java
index 57e0bd2..474bc4b 100644
--- a/voip/java/android/net/sip/SipAudioCallImpl.java
+++ b/voip/java/android/net/sip/SipAudioCallImpl.java
@@ -343,8 +343,11 @@
public synchronized void endCall() throws SipException {
try {
stopRinging();
- if (mSipSession != null) mSipSession.endCall();
stopCall(true);
+ mInCall = false;
+
+ // perform the above local ops first and then network op
+ if (mSipSession != null) mSipSession.endCall();
} catch (Throwable e) {
throwSipException(e);
}