Merge "Unhide social stream APIs for Contacts." into ics-mr1
diff --git a/api/current.txt b/api/current.txt
index e60712c..5c830d4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3235,6 +3235,7 @@
method public final android.app.Fragment getTargetFragment();
method public final int getTargetRequestCode();
method public final java.lang.CharSequence getText(int);
+ method public boolean getUserVisibleHint();
method public android.view.View getView();
method public final int hashCode();
method public static android.app.Fragment instantiate(android.content.Context, java.lang.String);
@@ -3245,7 +3246,6 @@
method public final boolean isInLayout();
method public final boolean isRemoving();
method public final boolean isResumed();
- method public boolean isStartDeferred();
method public final boolean isVisible();
method public void onActivityCreated(android.os.Bundle);
method public void onActivityResult(int, int, android.content.Intent);
@@ -3281,8 +3281,8 @@
method public void setInitialSavedState(android.app.Fragment.SavedState);
method public void setMenuVisibility(boolean);
method public void setRetainInstance(boolean);
- method public void setStartDeferred(boolean);
method public void setTargetFragment(android.app.Fragment, int);
+ method public void setUserVisibleHint(boolean);
method public void startActivity(android.content.Intent);
method public void startActivityForResult(android.content.Intent, int);
method public void unregisterForContextMenu(android.view.View);
@@ -4145,6 +4145,7 @@
ctor public AppWidgetHostView(android.content.Context, int, int);
method public int getAppWidgetId();
method public android.appwidget.AppWidgetProviderInfo getAppWidgetInfo();
+ method public static android.graphics.Rect getDefaultPaddingForWidget(android.content.Context, android.content.ComponentName, android.graphics.Rect);
method protected android.view.View getDefaultView();
method protected android.view.View getErrorView();
method protected void prepareView(android.view.View);
@@ -4474,10 +4475,12 @@
method public android.bluetooth.BluetoothSocket createInsecureRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
method public android.bluetooth.BluetoothSocket createRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
method public int describeContents();
+ method public boolean fetchUuidsWithSdp();
method public java.lang.String getAddress();
method public android.bluetooth.BluetoothClass getBluetoothClass();
method public int getBondState();
method public java.lang.String getName();
+ method public android.os.ParcelUuid[] getUuids();
method public void writeToParcel(android.os.Parcel, int);
field public static final java.lang.String ACTION_ACL_CONNECTED = "android.bluetooth.device.action.ACL_CONNECTED";
field public static final java.lang.String ACTION_ACL_DISCONNECTED = "android.bluetooth.device.action.ACL_DISCONNECTED";
@@ -4486,6 +4489,7 @@
field public static final java.lang.String ACTION_CLASS_CHANGED = "android.bluetooth.device.action.CLASS_CHANGED";
field public static final java.lang.String ACTION_FOUND = "android.bluetooth.device.action.FOUND";
field public static final java.lang.String ACTION_NAME_CHANGED = "android.bluetooth.device.action.NAME_CHANGED";
+ field public static final java.lang.String ACTION_UUID = "android.bluetooth.device.action.UUID";
field public static final int BOND_BONDED = 12; // 0xc
field public static final int BOND_BONDING = 11; // 0xb
field public static final int BOND_NONE = 10; // 0xa
@@ -4497,6 +4501,7 @@
field public static final java.lang.String EXTRA_NAME = "android.bluetooth.device.extra.NAME";
field public static final java.lang.String EXTRA_PREVIOUS_BOND_STATE = "android.bluetooth.device.extra.PREVIOUS_BOND_STATE";
field public static final java.lang.String EXTRA_RSSI = "android.bluetooth.device.extra.RSSI";
+ field public static final java.lang.String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
}
public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile {
@@ -17421,6 +17426,7 @@
field public static final java.lang.String LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED = "lock_pattern_tactile_feedback_enabled";
field public static final java.lang.String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern";
field public static final deprecated java.lang.String LOGGING_ID = "logging_id";
+ field public static final java.lang.String MESSAGING_APP_NOTIFICATIONS = "messaging_app_notifications";
field public static final java.lang.String NETWORK_PREFERENCE = "network_preference";
field public static final java.lang.String PARENTAL_CONTROL_ENABLED = "parental_control_enabled";
field public static final java.lang.String PARENTAL_CONTROL_LAST_UPDATE = "parental_control_last_update";
diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp
index 2378345..bd430d1 100644
--- a/cmds/stagefright/stream.cpp
+++ b/cmds/stagefright/stream.cpp
@@ -360,7 +360,7 @@
service->create(getpid(), client, 0);
if (player != NULL && player->setDataSource(source) == NO_ERROR) {
- player->setVideoSurface(surface);
+ player->setVideoSurfaceTexture(surface->getSurfaceTexture());
player->start();
client->waitForEOS();
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 9b01b7f..473a2d1 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -458,6 +458,9 @@
// have been started and their loaders are finished.
boolean mDeferStart;
+ // Hint provided by the app that this fragment is currently visible to the user.
+ boolean mUserVisibleHint = true;
+
LoaderManagerImpl mLoaderManager;
boolean mLoadersStarted;
boolean mCheckedForLoaderManager;
@@ -915,31 +918,32 @@
}
/**
- * Set whether this fragment should enter the started state as normal or if
- * start should be deferred until a system-determined convenient time, such
- * as after any loaders have completed their work.
+ * Set a hint to the system about whether this fragment's UI is currently visible
+ * to the user. This hint defaults to true and is persistent across fragment instance
+ * state save and restore.
*
- * <p>This option is not sticky across fragment starts; after a deferred start
- * completes this option will be set to false.</p>
+ * <p>An app may set this to false to indicate that the fragment's UI is
+ * scrolled out of visibility or is otherwise not directly visible to the user.
+ * This may be used by the system to prioritize operations such as fragment lifecycle updates
+ * or loader ordering behavior.</p>
*
- * @param deferResume true if this fragment can defer its resume until after others
+ * @param isVisibleToUser true if this fragment's UI is currently visible to the user (default),
+ * false if it is not.
*/
- public void setStartDeferred(boolean deferResume) {
- if (mDeferStart && !deferResume) {
+ public void setUserVisibleHint(boolean isVisibleToUser) {
+ if (!mUserVisibleHint && isVisibleToUser && mState < STARTED) {
mFragmentManager.performPendingDeferredStart(this);
}
- mDeferStart = deferResume;
+ mUserVisibleHint = isVisibleToUser;
+ mDeferStart = !isVisibleToUser;
}
/**
- * Returns true if this fragment's move to the started state has been deferred.
- * If this returns true it will be started once other fragments' loaders
- * have finished running.
- *
- * @return true if this fragment's start has been deferred.
+ * @return The current value of the user-visible hint on this fragment.
+ * @see #setUserVisibleHint(boolean)
*/
- public boolean isStartDeferred() {
- return mDeferStart;
+ public boolean getUserVisibleHint() {
+ return mUserVisibleHint;
}
/**
@@ -1477,7 +1481,8 @@
writer.print(" mMenuVisible="); writer.print(mMenuVisible);
writer.print(" mHasMenu="); writer.println(mHasMenu);
writer.print(prefix); writer.print("mRetainInstance="); writer.print(mRetainInstance);
- writer.print(" mRetaining="); writer.println(mRetaining);
+ writer.print(" mRetaining="); writer.print(mRetaining);
+ writer.print(" mUserVisibleHint="); writer.println(mUserVisibleHint);
if (mFragmentManager != null) {
writer.print(prefix); writer.print("mFragmentManager=");
writer.println(mFragmentManager);
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index c4ba778..a8c9cba 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -382,6 +382,7 @@
static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state";
static final String TARGET_STATE_TAG = "android:target_state";
static final String VIEW_STATE_TAG = "android:view_state";
+ static final String USER_VISIBLE_HINT_TAG = "android:user_visible_hint";
ArrayList<Runnable> mPendingActions;
Runnable[] mTmpActions;
@@ -406,6 +407,7 @@
boolean mStateSaved;
boolean mDestroyed;
String mNoTransactionsBecause;
+ boolean mHavePendingDeferredStart;
// Temporary vars for state save and restore.
Bundle mStateBundle = null;
@@ -711,6 +713,11 @@
public void performPendingDeferredStart(Fragment f) {
if (f.mDeferStart) {
+ if (mExecutingActions) {
+ // Wait until we're done executing our pending transactions
+ mHavePendingDeferredStart = true;
+ return;
+ }
f.mDeferStart = false;
moveToState(f, mCurState, 0, 0);
}
@@ -757,6 +764,14 @@
f.mTargetRequestCode = f.mSavedFragmentState.getInt(
FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
}
+ f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
+ FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
+ if (!f.mUserVisibleHint) {
+ f.mDeferStart = true;
+ if (newState > Fragment.STOPPED) {
+ newState = Fragment.STOPPED;
+ }
+ }
}
f.mActivity = mActivity;
f.mFragmentManager = mActivity.mFragments;
@@ -1343,7 +1358,7 @@
synchronized (this) {
if (mPendingActions == null || mPendingActions.size() == 0) {
- return didSomething;
+ break;
}
numActions = mPendingActions.size();
@@ -1363,8 +1378,23 @@
mExecutingActions = false;
didSomething = true;
}
+
+ if (mHavePendingDeferredStart) {
+ boolean loadersRunning = false;
+ for (int i=0; i<mActive.size(); i++) {
+ Fragment f = mActive.get(i);
+ if (f != null && f.mLoaderManager != null) {
+ loadersRunning |= f.mLoaderManager.hasRunningLoaders();
+ }
+ }
+ if (!loadersRunning) {
+ mHavePendingDeferredStart = false;
+ startPendingDeferredFragments();
+ }
+ }
+ return didSomething;
}
-
+
void reportBackStackChanged() {
if (mBackStackChangeListeners != null) {
for (int i=0; i<mBackStackChangeListeners.size(); i++) {
@@ -1500,6 +1530,10 @@
result.putSparseParcelableArray(
FragmentManagerImpl.VIEW_STATE_TAG, f.mSavedViewState);
}
+ if (!f.mUserVisibleHint) {
+ // Only add this if it's not the default value
+ result.putBoolean(FragmentManagerImpl.USER_VISIBLE_HINT_TAG, f.mUserVisibleHint);
+ }
return result;
}
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index 761c7eb..61a9dce 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -26,6 +26,7 @@
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
+import android.graphics.Rect;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
@@ -41,8 +42,8 @@
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.RemoteViews;
-import android.widget.TextView;
import android.widget.RemoteViewsAdapter.RemoteAdapterConnectionCallback;
+import android.widget.TextView;
/**
* Provides the glue to show AppWidget views. This class offers automatic animation
@@ -106,7 +107,9 @@
}
/**
- * Set the AppWidget that will be displayed by this view.
+ * Set the AppWidget that will be displayed by this view. This method also adds default padding
+ * to widgets, as described in {@link #getDefaultPaddingForWidget(Context, ComponentName, Rect)}
+ * and can be overridden in order to add custom padding.
*/
public void setAppWidget(int appWidgetId, AppWidgetProviderInfo info) {
mAppWidgetId = appWidgetId;
@@ -116,49 +119,57 @@
// a widget, eg. for some widgets in safe mode.
if (info != null) {
// We add padding to the AppWidgetHostView if necessary
- Padding padding = getPaddingForWidget(info.provider);
+ Rect padding = getDefaultPaddingForWidget(mContext, info.provider, null);
setPadding(padding.left, padding.top, padding.right, padding.bottom);
}
}
- private static class Padding {
- int left = 0;
- int right = 0;
- int top = 0;
- int bottom = 0;
- }
-
/**
* As of ICE_CREAM_SANDWICH we are automatically adding padding to widgets targeting
* ICE_CREAM_SANDWICH and higher. The new widget design guidelines strongly recommend
* that widget developers do not add extra padding to their widgets. This will help
* achieve consistency among widgets.
+ *
+ * Note: this method is only needed by developers of AppWidgetHosts. The method is provided in
+ * order for the AppWidgetHost to account for the automatic padding when computing the number
+ * of cells to allocate to a particular widget.
+ *
+ * @param context the current context
+ * @param component the component name of the widget
+ * @param padding Rect in which to place the output, if null, a new Rect will be allocated and
+ * returned
+ * @return default padding for this widget
*/
- private Padding getPaddingForWidget(ComponentName component) {
- PackageManager packageManager = mContext.getPackageManager();
- Padding p = new Padding();
+ public static Rect getDefaultPaddingForWidget(Context context, ComponentName component,
+ Rect padding) {
+ PackageManager packageManager = context.getPackageManager();
ApplicationInfo appInfo;
+ if (padding == null) {
+ padding = new Rect(0, 0, 0, 0);
+ } else {
+ padding.set(0, 0, 0, 0);
+ }
+
try {
appInfo = packageManager.getApplicationInfo(component.getPackageName(), 0);
- } catch (Exception e) {
+ } catch (NameNotFoundException e) {
// if we can't find the package, return 0 padding
- return p;
+ return padding;
}
if (appInfo.targetSdkVersion >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
- Resources r = getResources();
- p.left = r.getDimensionPixelSize(com.android.internal.
+ Resources r = context.getResources();
+ padding.left = r.getDimensionPixelSize(com.android.internal.
R.dimen.default_app_widget_padding_left);
- p.right = r.getDimensionPixelSize(com.android.internal.
+ padding.right = r.getDimensionPixelSize(com.android.internal.
R.dimen.default_app_widget_padding_right);
- p.top = r.getDimensionPixelSize(com.android.internal.
+ padding.top = r.getDimensionPixelSize(com.android.internal.
R.dimen.default_app_widget_padding_top);
- p.bottom = r.getDimensionPixelSize(com.android.internal.
+ padding.bottom = r.getDimensionPixelSize(com.android.internal.
R.dimen.default_app_widget_padding_bottom);
}
-
- return p;
+ return padding;
}
public int getAppWidgetId() {
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 4cb8220..0306521 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -247,13 +247,12 @@
* has been fetched. This intent is sent only when the UUIDs of the remote
* device are requested to be fetched using Service Discovery Protocol
* <p> Always contains the extra field {@link #EXTRA_DEVICE}
- * <p> Always contains the extra filed {@link #EXTRA_UUID}
+ * <p> Always contains the extra field {@link #EXTRA_UUID}
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
- * @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_UUID =
- "android.bleutooth.device.action.UUID";
+ "android.bluetooth.device.action.UUID";
/**
* Broadcast Action: Indicates a failure to retrieve the name of a remote
@@ -451,7 +450,6 @@
* Used as an extra field in {@link #ACTION_UUID} intents,
* Contains the {@link android.os.ParcelUuid}s of the remote device which
* is a parcelable version of {@link UUID}.
- * @hide
*/
public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
@@ -770,7 +768,18 @@
return false;
}
- /** @hide */
+ /**
+ * Returns the supported features (UUIDs) of the remote device.
+ *
+ * <p>This method does not start a service discovery procedure to retrieve the UUIDs
+ * from the remote device. Instead, the local cached copy of the service
+ * UUIDs are returned.
+ * <p>Use {@link #fetchUuidsWithSdp} if fresh UUIDs are desired.
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
+ *
+ * @return the supported features (UUIDs) of the remote device,
+ * or null on error
+ */
public ParcelUuid[] getUuids() {
try {
return sService.getRemoteUuids(mAddress);
@@ -779,18 +788,19 @@
}
/**
- * Perform a SDP query on the remote device to get the UUIDs
- * supported. This API is asynchronous and an Intent is sent,
- * with the UUIDs supported by the remote end. If there is an error
- * in getting the SDP records or if the process takes a long time,
- * an Intent is sent with the UUIDs that is currently present in the
- * cache. Clients should use the {@link #getUuids} to get UUIDs
- * is SDP is not to be performed.
+ * Perform a service discovery on the remote device to get the UUIDs supported.
*
- * @return False if the sanity check fails, True if the process
+ * <p>This API is asynchronous and {@link #ACTION_UUID} intent is sent,
+ * with the UUIDs supported by the remote end. If there is an error
+ * in getting the SDP records or if the process takes a long time,
+ * {@link #ACTION_UUID} intent is sent with the UUIDs that is currently
+ * present in the cache. Clients should use the {@link #getUuids} to get UUIDs
+ * if service discovery is not to be performed.
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
+ *
+ * @return False if the sanity check fails, True if the process
* of initiating an ACL connection to the remote device
* was started.
- * @hide
*/
public boolean fetchUuidsWithSdp() {
try {
diff --git a/core/java/android/net/wimax/WimaxManagerConstants.java b/core/java/android/net/wimax/WimaxManagerConstants.java
new file mode 100644
index 0000000..b4aaf5b
--- /dev/null
+++ b/core/java/android/net/wimax/WimaxManagerConstants.java
@@ -0,0 +1,104 @@
+package android.net.wimax;
+
+/**
+ * {@hide}
+ */
+public class WimaxManagerConstants
+{
+
+ /**
+ * Used by android.net.wimax.WimaxManager for handling management of
+ * Wimax access.
+ */
+ public static final String WIMAX_SERVICE = "WiMax";
+
+ /**
+ * Broadcast intent action indicating that Wimax has been enabled, disabled,
+ * enabling, disabling, or unknown. One extra provides this state as an int.
+ * Another extra provides the previous state, if available.
+ */
+ public static final String NET_4G_STATE_CHANGED_ACTION =
+ "android.net.fourG.NET_4G_STATE_CHANGED";
+
+ /**
+ * The lookup key for an int that indicates whether Wimax is enabled,
+ * disabled, enabling, disabling, or unknown.
+ */
+ public static final String EXTRA_WIMAX_STATUS = "wimax_status";
+
+ /**
+ * Broadcast intent action indicating that Wimax state has been changed
+ * state could be scanning, connecting, connected, disconnecting, disconnected
+ * initializing, initialized, unknown and ready. One extra provides this state as an int.
+ * Another extra provides the previous state, if available.
+ */
+ public static final String WIMAX_NETWORK_STATE_CHANGED_ACTION =
+ "android.net.fourG.wimax.WIMAX_NETWORK_STATE_CHANGED";
+
+ /**
+ * Broadcast intent action indicating that Wimax signal level has been changed.
+ * Level varies from 0 to 3.
+ */
+ public static final String SIGNAL_LEVEL_CHANGED_ACTION =
+ "android.net.wimax.SIGNAL_LEVEL_CHANGED";
+
+ /**
+ * The lookup key for an int that indicates whether Wimax state is
+ * scanning, connecting, connected, disconnecting, disconnected
+ * initializing, initialized, unknown and ready.
+ */
+ public static final String EXTRA_WIMAX_STATE = "WimaxState";
+ public static final String EXTRA_4G_STATE = "4g_state";
+ public static final String EXTRA_WIMAX_STATE_INT = "WimaxStateInt";
+ /**
+ * The lookup key for an int that indicates whether state of Wimax
+ * is idle.
+ */
+ public static final String EXTRA_WIMAX_STATE_DETAIL = "WimaxStateDetail";
+
+ /**
+ * The lookup key for an int that indicates Wimax signal level.
+ */
+ public static final String EXTRA_NEW_SIGNAL_LEVEL = "newSignalLevel";
+
+ /**
+ * Indicatates Wimax is disabled.
+ */
+ public static final int NET_4G_STATE_DISABLED = 1;
+
+ /**
+ * Indicatates Wimax is enabled.
+ */
+ public static final int NET_4G_STATE_ENABLED = 3;
+
+ /**
+ * Indicatates Wimax status is known.
+ */
+ public static final int NET_4G_STATE_UNKNOWN = 4;
+
+ /**
+ * Indicatates Wimax is in idle state.
+ */
+ public static final int WIMAX_IDLE = 6;
+
+ /**
+ * Indicatates Wimax is being deregistered.
+ */
+ public static final int WIMAX_DEREGISTRATION = 8;
+
+ /**
+ * Indicatates wimax state is unknown.
+ */
+ public static final int WIMAX_STATE_UNKNOWN = 0;
+
+ /**
+ * Indicatates wimax state is connected.
+ */
+ public static final int WIMAX_STATE_CONNECTED = 7;
+
+ /**
+ * Indicatates wimax state is disconnected.
+ */
+ public static final int WIMAX_STATE_DISCONNECTED = 9;
+
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a0652f7..769776e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1183,6 +1183,10 @@
public static final String RADIO_WIFI = "wifi";
/**
+ * {@hide}
+ */
+ public static final String RADIO_WIMAX = "wimax";
+ /**
* Constant for use in AIRPLANE_MODE_RADIOS to specify Cellular radio.
*/
public static final String RADIO_CELL = "cell";
@@ -2899,6 +2903,11 @@
*/
public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON =
"wifi_networks_available_notification_on";
+ /**
+ * {@hide}
+ */
+ public static final String WIMAX_NETWORKS_AVAILABLE_NOTIFICATION_ON =
+ "wimax_networks_available_notification_on";
/**
* Delay (in seconds) before repeating the Wi-Fi networks available notification.
@@ -4068,6 +4077,13 @@
"contacts_preauth_uri_expiration";
/**
+ * Whether the Messaging app posts notifications.
+ * 0=disabled. 1=enabled.
+ */
+ public static final String MESSAGING_APP_NOTIFICATIONS = "messaging_app_notifications";
+
+
+ /**
* This are the settings to be backed up.
*
* NOTE: Settings are backed up and restored in the order they appear
@@ -4104,7 +4120,8 @@
MOUNT_UMS_NOTIFY_ENABLED,
UI_NIGHT_MODE,
LOCK_SCREEN_OWNER_INFO,
- LOCK_SCREEN_OWNER_INFO_ENABLED
+ LOCK_SCREEN_OWNER_INFO_ENABLED,
+ MESSAGING_APP_NOTIFICATIONS
};
/**
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 0e6d07d..8eb9da1 100755
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -1838,5 +1838,15 @@
public static final String EXTRA_PLMN = "plmn";
public static final String EXTRA_SHOW_SPN = "showSpn";
public static final String EXTRA_SPN = "spn";
+
+ /**
+ * Activity Action: Shows a dialog to turn off Messaging app notification.
+ * <p>Input: Nothing.
+ * <p>Output: Nothing.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_MESSAGING_APP_NOTIFICATIONS =
+ "android.provider.Telephony.MESSAGING_APP_NOTIFICATIONS";
+
}
}
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 954a6fe..fdc2570 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -1089,6 +1089,7 @@
// Copy feature strings defined by the framework.
copyStringParam(bundle, params, Engine.KEY_FEATURE_NETWORK_SYNTHESIS);
+ copyStringParam(bundle, params, Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS);
// Copy over all parameters that start with the name of the
// engine that we are currently connected to. The engine is
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index 245271d..83b6d4c 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -792,8 +792,13 @@
public String[] getFeaturesForLanguage(String lang, String country, String variant) {
Set<String> features = onGetFeaturesForLanguage(lang, country, variant);
- String[] featuresArray = new String[features.size()];
- features.toArray(featuresArray);
+ String[] featuresArray = null;
+ if (features != null) {
+ featuresArray = new String[features.size()];
+ features.toArray(featuresArray);
+ } else {
+ featuresArray = new String[0];
+ }
return featuresArray;
}
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 2cc928f..388920c 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -813,8 +813,6 @@
boolean synchronous,
String username,
String password) {
- PerfChecker checker = new PerfChecker();
-
if (mSettings.getCacheMode() != WebSettings.LOAD_DEFAULT) {
cacheMode = mSettings.getCacheMode();
}
@@ -872,11 +870,6 @@
|| headers.containsKey("If-None-Match") ?
WebSettings.LOAD_NO_CACHE : cacheMode);
// Set referrer to current URL?
- if (!loader.executeLoad()) {
- checker.responseAlert("startLoadingResource fail");
- }
- checker.responseAlert("startLoadingResource succeed");
-
return !synchronous ? loadListener : null;
}
diff --git a/core/java/android/webkit/JWebCoreJavaBridge.java b/core/java/android/webkit/JWebCoreJavaBridge.java
index 5b78586..b498435 100644
--- a/core/java/android/webkit/JWebCoreJavaBridge.java
+++ b/core/java/android/webkit/JWebCoreJavaBridge.java
@@ -87,11 +87,9 @@
* Call native timer callbacks.
*/
private void fireSharedTimer() {
- PerfChecker checker = new PerfChecker();
// clear the flag so that sharedTimerFired() can set a new timer
mHasInstantTimer = false;
sharedTimerFired();
- checker.responseAlert("sharedTimer");
}
/**
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index 04af738..37e8bc0 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -1136,7 +1136,6 @@
// Give the data to WebKit now. We don't have to synchronize on
// mDataBuilder here because pulling each chunk removes it from the
// internal list so it cannot be modified.
- PerfChecker checker = new PerfChecker();
ByteArrayBuilder.Chunk c;
while (true) {
c = mDataBuilder.getFirstChunk();
@@ -1152,7 +1151,6 @@
} else {
c.release();
}
- checker.responseAlert("res nativeAddData");
}
}
@@ -1173,13 +1171,11 @@
WebViewWorker.MSG_REMOVE_CACHE, this).sendToTarget();
}
if (mNativeLoader != 0) {
- PerfChecker checker = new PerfChecker();
if (!mSetNativeResponse) {
setNativeResponse();
}
nativeFinished();
- checker.responseAlert("res nativeFinished");
clearNativeLoader();
}
}
diff --git a/core/java/android/webkit/PerfChecker.java b/core/java/android/webkit/PerfChecker.java
deleted file mode 100644
index 8c5f86e..0000000
--- a/core/java/android/webkit/PerfChecker.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2007 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.webkit;
-
-import android.os.SystemClock;
-import android.util.Log;
-
-class PerfChecker {
-
- private long mTime;
- private static final long mResponseThreshold = 2000; // 2s
-
- public PerfChecker() {
- if (false) {
- mTime = SystemClock.uptimeMillis();
- }
- }
-
- /**
- * @param what log string
- * Logs given string if mResponseThreshold time passed between either
- * instantiation or previous responseAlert call
- */
- public void responseAlert(String what) {
- if (false) {
- long upTime = SystemClock.uptimeMillis();
- long time = upTime - mTime;
- if (time > mResponseThreshold) {
- Log.w("webkit", what + " used " + time + " ms");
- }
- // Reset mTime, to permit reuse
- mTime = upTime;
- }
- }
-}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 58b63fe..55f345f 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -683,7 +683,6 @@
private static final int SWITCH_TO_LONGPRESS = 4;
private static final int RELEASE_SINGLE_TAP = 5;
private static final int REQUEST_FORM_DATA = 6;
- private static final int RESUME_WEBCORE_PRIORITY = 7;
private static final int DRAG_HELD_MOTIONLESS = 8;
private static final int AWAKEN_SCROLL_BARS = 9;
private static final int PREVENT_DEFAULT_TIMEOUT = 10;
@@ -2850,46 +2849,47 @@
// Used to avoid sending many visible rect messages.
private Rect mLastVisibleRectSent;
private Rect mLastGlobalRect;
+ private Rect mVisibleRect = new Rect();
+ private Rect mGlobalVisibleRect = new Rect();
+ private Point mScrollOffset = new Point();
Rect sendOurVisibleRect() {
if (mZoomManager.isPreventingWebkitUpdates()) return mLastVisibleRectSent;
- Rect rect = new Rect();
- calcOurContentVisibleRect(rect);
+ calcOurContentVisibleRect(mVisibleRect);
// Rect.equals() checks for null input.
- if (!rect.equals(mLastVisibleRectSent)) {
+ if (!mVisibleRect.equals(mLastVisibleRectSent)) {
if (!mBlockWebkitViewMessages) {
- Point pos = new Point(rect.left, rect.top);
+ mScrollOffset.set(mVisibleRect.left, mVisibleRect.top);
mWebViewCore.removeMessages(EventHub.SET_SCROLL_OFFSET);
mWebViewCore.sendMessage(EventHub.SET_SCROLL_OFFSET,
- nativeMoveGeneration(), mSendScrollEvent ? 1 : 0, pos);
+ nativeMoveGeneration(), mSendScrollEvent ? 1 : 0, mScrollOffset);
}
- mLastVisibleRectSent = rect;
+ mLastVisibleRectSent = mVisibleRect;
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
}
- Rect globalRect = new Rect();
- if (getGlobalVisibleRect(globalRect)
- && !globalRect.equals(mLastGlobalRect)) {
+ if (getGlobalVisibleRect(mGlobalVisibleRect)
+ && !mGlobalVisibleRect.equals(mLastGlobalRect)) {
if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "sendOurVisibleRect=(" + globalRect.left + ","
- + globalRect.top + ",r=" + globalRect.right + ",b="
- + globalRect.bottom);
+ Log.v(LOGTAG, "sendOurVisibleRect=(" + mGlobalVisibleRect.left + ","
+ + mGlobalVisibleRect.top + ",r=" + mGlobalVisibleRect.right + ",b="
+ + mGlobalVisibleRect.bottom);
}
// TODO: the global offset is only used by windowRect()
// in ChromeClientAndroid ; other clients such as touch
// and mouse events could return view + screen relative points.
if (!mBlockWebkitViewMessages) {
- mWebViewCore.sendMessage(EventHub.SET_GLOBAL_BOUNDS, globalRect);
+ mWebViewCore.sendMessage(EventHub.SET_GLOBAL_BOUNDS, mGlobalVisibleRect);
}
- mLastGlobalRect = globalRect;
+ mLastGlobalRect = mGlobalVisibleRect;
}
- return rect;
+ return mVisibleRect;
}
+ private Point mGlobalVisibleOffset = new Point();
// Sets r to be the visible rectangle of our webview in view coordinates
private void calcOurVisibleRect(Rect r) {
- Point p = new Point();
- getGlobalVisibleRect(r, p);
- r.offset(-p.x, -p.y);
+ getGlobalVisibleRect(r, mGlobalVisibleOffset);
+ r.offset(-mGlobalVisibleOffset.x, -mGlobalVisibleOffset.y);
}
// Sets r to be our visible rectangle in content coordinates
@@ -2905,21 +2905,21 @@
r.bottom = viewToContentY(r.bottom);
}
+ private Rect mContentVisibleRect = new Rect();
// Sets r to be our visible rectangle in content coordinates. We use this
// method on the native side to compute the position of the fixed layers.
// Uses floating coordinates (necessary to correctly place elements when
// the scale factor is not 1)
private void calcOurContentVisibleRectF(RectF r) {
- Rect ri = new Rect(0,0,0,0);
- calcOurVisibleRect(ri);
- r.left = viewToContentXf(ri.left);
+ calcOurVisibleRect(mContentVisibleRect);
+ r.left = viewToContentXf(mContentVisibleRect.left);
// viewToContentY will remove the total height of the title bar. Add
// the visible height back in to account for the fact that if the title
// bar is partially visible, the part of the visible rect which is
// displaying our content is displaced by that amount.
- r.top = viewToContentYf(ri.top + getVisibleTitleHeightImpl());
- r.right = viewToContentXf(ri.right);
- r.bottom = viewToContentYf(ri.bottom);
+ r.top = viewToContentYf(mContentVisibleRect.top + getVisibleTitleHeightImpl());
+ r.right = viewToContentXf(mContentVisibleRect.right);
+ r.bottom = viewToContentYf(mContentVisibleRect.bottom);
}
static class ViewSizeData {
@@ -3569,7 +3569,6 @@
mScrollingLayerRect.top = y;
}
abortAnimation();
- mPrivateHandler.removeMessages(RESUME_WEBCORE_PRIORITY);
nativeSetIsScrolling(false);
if (!mBlockWebkitViewMessages) {
WebViewCore.resumePriority();
@@ -4119,20 +4118,6 @@
}
private void drawContent(Canvas canvas, boolean drawRings) {
- // Update the buttons in the picture, so when we draw the picture
- // to the screen, they are in the correct state.
- // Tell the native side if user is a) touching the screen,
- // b) pressing the trackball down, or c) pressing the enter key
- // If the cursor is on a button, we need to draw it in the pressed
- // state.
- // If mNativeClass is 0, we should not reach here, so we do not
- // need to check it again.
- boolean pressed = (mTouchMode == TOUCH_SHORTPRESS_START_MODE
- || mTouchMode == TOUCH_INIT_MODE
- || mTouchMode == TOUCH_SHORTPRESS_MODE);
- recordButtons(canvas,
- hasFocus() && hasWindowFocus(), (pressed && !USE_WEBKIT_RINGS)
- || mTrackballDown || mGotCenterDown, false);
drawCoreAndCursorRing(canvas, mBackgroundColor,
mDrawCursorRing && drawRings);
}
@@ -5193,9 +5178,6 @@
mGotCenterDown = true;
mPrivateHandler.sendMessageDelayed(mPrivateHandler
.obtainMessage(LONG_PRESS_CENTER), LONG_PRESS_TIMEOUT);
- // Already checked mNativeClass, so we do not need to check it
- // again.
- recordButtons(null, hasFocus() && hasWindowFocus(), true, true);
if (!wantsKeyEvents) return true;
}
// Bubble up the key event as WebView doesn't handle it
@@ -5631,9 +5613,6 @@
// drawing the cursor ring
mDrawCursorRing = true;
setFocusControllerActive(true);
- if (mNativeClass != 0) {
- recordButtons(null, true, false, true);
- }
} else {
if (!inEditingMode()) {
// If our window gained focus, but we do not have it, do not
@@ -5659,9 +5638,6 @@
mKeysPressed.clear();
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
mTouchMode = TOUCH_DONE_MODE;
- if (mNativeClass != 0) {
- recordButtons(null, false, false, true);
- }
setFocusControllerActive(false);
}
invalidate();
@@ -5717,9 +5693,6 @@
// the cursor ring
if (hasWindowFocus()) {
mDrawCursorRing = true;
- if (mNativeClass != 0) {
- recordButtons(null, true, false, true);
- }
setFocusControllerActive(true);
//} else {
// The WebView has gained focus while we do not have
@@ -5731,9 +5704,6 @@
// true if we are in editing mode), stop drawing the cursor ring.
if (!inEditingMode()) {
mDrawCursorRing = false;
- if (mNativeClass != 0) {
- recordButtons(null, false, false, true);
- }
setFocusControllerActive(false);
}
mKeysPressed.clear();
@@ -6021,7 +5991,6 @@
mScroller.abortAnimation();
mTouchMode = TOUCH_DRAG_START_MODE;
mConfirmMove = true;
- mPrivateHandler.removeMessages(RESUME_WEBCORE_PRIORITY);
nativeSetIsScrolling(false);
} else if (mPrivateHandler.hasMessages(RELEASE_SINGLE_TAP)) {
mPrivateHandler.removeMessages(RELEASE_SINGLE_TAP);
@@ -6847,7 +6816,6 @@
if (mNativeClass == 0) {
return false;
}
- recordButtons(null, hasFocus() && hasWindowFocus(), true, true);
if (time - mLastCursorTime <= TRACKBALL_TIMEOUT
&& !mLastCursorBounds.equals(nativeGetCursorRingBounds())) {
nativeSelectBestAt(mLastCursorBounds);
@@ -7359,7 +7327,6 @@
mLastTouchTime = eventTime;
if (!mScroller.isFinished()) {
abortAnimation();
- mPrivateHandler.removeMessages(RESUME_WEBCORE_PRIORITY);
}
mSnapScrollMode = SNAP_NONE;
mVelocityTracker = VelocityTracker.obtain();
@@ -8491,10 +8458,6 @@
mWebTextView.setAdapterCustom(adapter);
}
break;
- case RESUME_WEBCORE_PRIORITY:
- WebViewCore.resumePriority();
- WebViewCore.resumeUpdatePicture(mWebViewCore);
- break;
case LONG_PRESS_CENTER:
// as this is shared by keydown and trackballdown, reset all
@@ -9442,24 +9405,6 @@
return nativeTileProfilingGetFloat(frame, tile, key);
}
- /**
- * Helper method to deal with differences between hardware and software rendering
- */
- private void recordButtons(Canvas canvas, boolean focus, boolean pressed,
- boolean inval) {
- boolean isHardwareAccel = canvas != null
- ? canvas.isHardwareAccelerated()
- : isHardwareAccelerated();
- if (isHardwareAccel) {
- // We never want to change button state if we are hardware accelerated,
- // but we DO want to invalidate as necessary so that the GL ring
- // can be drawn
- nativeRecordButtons(mNativeClass, false, false, inval);
- } else {
- nativeRecordButtons(mNativeClass, focus, pressed, inval);
- }
- }
-
private native int nativeCacheHitFramePointer();
private native boolean nativeCacheHitIsPlugin();
private native Rect nativeCacheHitNodeBounds();
@@ -9556,8 +9501,6 @@
private native boolean nativePointInNavCache(int x, int y, int slop);
// Like many other of our native methods, you must make sure that
// mNativeClass is not null before calling this method.
- private native void nativeRecordButtons(int nativeInstance,
- boolean focused, boolean pressed, boolean invalidate);
private native void nativeResetSelection();
private native Point nativeSelectableText();
private native void nativeSelectAll();
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index 27d44bf..ec3790e 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -68,6 +68,7 @@
int mDropDownWidth;
private int mGravity;
+ private boolean mDisableChildrenWhenDisabled;
private Rect mTempRect = new Rect();
@@ -186,6 +187,9 @@
mPopup.setPromptText(a.getString(com.android.internal.R.styleable.Spinner_prompt));
+ mDisableChildrenWhenDisabled = a.getBoolean(
+ com.android.internal.R.styleable.Spinner_disableChildrenWhenDisabled, false);
+
a.recycle();
// Base constructor can call setAdapter before we initialize mPopup.
@@ -196,6 +200,17 @@
}
}
+ @Override
+ public void setEnabled(boolean enabled) {
+ super.setEnabled(enabled);
+ if (mDisableChildrenWhenDisabled) {
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ getChildAt(i).setEnabled(enabled);
+ }
+ }
+ }
+
/**
* Describes how the selected item view is positioned. Currently only the horizontal component
* is used. The default is determined by the current theme.
@@ -398,6 +413,9 @@
addViewInLayout(child, 0, lp);
child.setSelected(hasFocus());
+ if (mDisableChildrenWhenDisabled) {
+ child.setEnabled(isEnabled());
+ }
// Get measure specs
int childHeightSpec = ViewGroup.getChildMeasureSpec(mHeightMeasureSpec,
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a8680d4..5833afd 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -9059,51 +9059,6 @@
sendAccessibilityEventUnchecked(event);
}
- @Override
- protected void onCreateContextMenu(ContextMenu menu) {
- super.onCreateContextMenu(menu);
- boolean added = false;
- mContextMenuTriggeredByKey = mDPadCenterIsDown || mEnterKeyIsDown;
- // Problem with context menu on long press: the menu appears while the key in down and when
- // the key is released, the view does not receive the key_up event.
- // We need two layers of flags: mDPadCenterIsDown and mEnterKeyIsDown are set in key down/up
- // events. We cannot simply clear these flags in onTextContextMenuItem since
- // it may not be called (if the user/ discards the context menu with the back key).
- // We clear these flags here and mContextMenuTriggeredByKey saves that state so that it is
- // available in onTextContextMenuItem.
- mDPadCenterIsDown = mEnterKeyIsDown = false;
-
- MenuHandler handler = new MenuHandler();
-
- if (mText instanceof Spanned && hasSelectionController()) {
- long lastTouchOffset = getLastTouchOffsets();
- final int selStart = extractRangeStartFromLong(lastTouchOffset);
- final int selEnd = extractRangeEndFromLong(lastTouchOffset);
-
- URLSpan[] urls = ((Spanned) mText).getSpans(selStart, selEnd, URLSpan.class);
- if (urls.length > 0) {
- menu.add(0, ID_COPY_URL, 0, com.android.internal.R.string.copyUrl).
- setOnMenuItemClickListener(handler);
-
- added = true;
- }
- }
-
- // The context menu is not empty, which will prevent the selection mode from starting.
- // Add a entry to start it in the context menu.
- // TODO Does not handle the case where a subclass does not call super.thisMethod or
- // populates the menu AFTER this call.
- if (menu.size() > 0) {
- menu.add(0, ID_SELECTION_MODE, 0, com.android.internal.R.string.selectTextMode).
- setOnMenuItemClickListener(handler);
- added = true;
- }
-
- if (added) {
- menu.setHeaderTitle(com.android.internal.R.string.editTextMenuTitle);
- }
- }
-
/**
* Returns whether this text view is a current input method target. The
* default implementation just checks with {@link InputMethodManager}.
@@ -9118,9 +9073,6 @@
private static final int ID_CUT = android.R.id.cut;
private static final int ID_COPY = android.R.id.copy;
private static final int ID_PASTE = android.R.id.paste;
- // Context menu entries
- private static final int ID_COPY_URL = android.R.id.copyUrl;
- private static final int ID_SELECTION_MODE = android.R.id.selectTextMode;
private class MenuHandler implements MenuItem.OnMenuItemClickListener {
public boolean onMenuItemClick(MenuItem item) {
@@ -9130,9 +9082,8 @@
/**
* Called when a context menu option for the text view is selected. Currently
- * this will be {@link android.R.id#copyUrl}, {@link android.R.id#selectTextMode},
- * {@link android.R.id#selectAll}, {@link android.R.id#paste}, {@link android.R.id#cut}
- * or {@link android.R.id#copy}.
+ * this will be one of {@link android.R.id#selectAll}, {@link android.R.id#cut},
+ * {@link android.R.id#copy} or {@link android.R.id#paste}.
*
* @return true if the context menu item action was performed.
*/
@@ -9149,34 +9100,6 @@
}
switch (id) {
- case ID_COPY_URL:
- URLSpan[] urls = ((Spanned) mText).getSpans(min, max, URLSpan.class);
- if (urls.length >= 1) {
- ClipData clip = null;
- for (int i=0; i<urls.length; i++) {
- Uri uri = Uri.parse(urls[0].getURL());
- if (clip == null) {
- clip = ClipData.newRawUri(null, uri);
- } else {
- clip.addItem(new ClipData.Item(uri));
- }
- }
- if (clip != null) {
- setPrimaryClip(clip);
- }
- }
- stopSelectionActionMode();
- return true;
-
- case ID_SELECTION_MODE:
- if (mSelectionActionMode != null) {
- // Selection mode is already started, simply change selected part.
- selectCurrentWord();
- } else {
- startSelectionActionMode();
- }
- return true;
-
case ID_SELECT_ALL:
// This does not enter text selection mode. Text is highlighted, so that it can be
// bulk edited, like selectAllOnFocus does. Returns true even if text is empty.
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index d5450e4..17b8acf 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -439,17 +439,6 @@
}
/**
- * Calls back SetupFaceLock to save the temporary gallery file if this is the backup lock.
- * This doesn't have to verify that biometric is enabled because it's only called in that case
- */
- void moveTempGallery() {
- Intent intent = new Intent().setClassName("com.android.facelock",
- "com.android.facelock.SetupFaceLock");
- intent.putExtra("moveTempGallery", true);
- mContext.startActivity(intent);
- }
-
- /**
* Calls back SetupFaceLock to delete the temporary gallery file
*/
public void deleteTempGallery() {
@@ -501,8 +490,7 @@
setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK);
setLong(PASSWORD_TYPE_ALTERNATE_KEY,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
- setBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY, true);
- moveTempGallery();
+ finishBiometricWeak();
}
dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, pattern
.size(), 0, 0, 0, 0, 0, 0);
@@ -619,8 +607,7 @@
} else {
setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK);
setLong(PASSWORD_TYPE_ALTERNATE_KEY, Math.max(quality, computedQuality));
- setBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY, true);
- moveTempGallery();
+ finishBiometricWeak();
}
if (computedQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
int letters = 0;
@@ -1087,4 +1074,16 @@
}
return false;
}
+
+ private void finishBiometricWeak() {
+ setBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY, true);
+
+ // Launch intent to show final screen, this also
+ // moves the temporary gallery to the actual gallery
+ Intent intent = new Intent();
+ intent.setClassName("com.android.facelock",
+ "com.android.facelock.SetupEndScreen");
+ mContext.startActivity(intent);
+ }
+
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 18194ee..0ed0523 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -423,6 +423,12 @@
android:description="@string/permdesc_accessWifiState"
android:label="@string/permlab_accessWifiState" />
+ <!-- @hide -->
+ <permission android:name="android.permission.ACCESS_WIMAX_STATE"
+ android:permissionGroup="android.permission-group.NETWORK"
+ android:protectionLevel="normal"
+ android:description="@string/permdesc_accessWimaxState"
+ android:label="@string/permlab_accessWimaxState" />
<!-- Allows applications to connect to paired bluetooth devices -->
<permission android:name="android.permission.BLUETOOTH"
android:permissionGroup="android.permission-group.NETWORK"
@@ -984,6 +990,12 @@
android:description="@string/permdesc_changeWifiState"
android:label="@string/permlab_changeWifiState" />
+ <!-- @hide -->
+ <permission android:name="android.permission.CHANGE_WIMAX_STATE"
+ android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+ android:protectionLevel="dangerous"
+ android:description="@string/permdesc_changeWimaxState"
+ android:label="@string/permlab_changeWimaxState" />
<!-- Allows applications to enter Wi-Fi Multicast mode -->
<permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_dark.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_dark.9.png
new file mode 100644
index 0000000..cbd8c5c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_light.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_light.9.png
new file mode 100644
index 0000000..f7f4ba3
--- /dev/null
+++ b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png b/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png
new file mode 100644
index 0000000..c2e4b78
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png b/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png
new file mode 100644
index 0000000..51b839f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_dark.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_dark.9.png
new file mode 100644
index 0000000..d12a196
--- /dev/null
+++ b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_light.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_light.9.png
new file mode 100644
index 0000000..27c7977
--- /dev/null
+++ b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_dark.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_dark.9.png
new file mode 100644
index 0000000..6927834
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_light.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_light.9.png
new file mode 100644
index 0000000..4bce527
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_light.9.png
Binary files differ
diff --git a/core/res/res/drawable/quickcontact_badge_overlay_dark.xml b/core/res/res/drawable/quickcontact_badge_overlay_dark.xml
index 972488d..6bd7403 100644
--- a/core/res/res/drawable/quickcontact_badge_overlay_dark.xml
+++ b/core/res/res/drawable/quickcontact_badge_overlay_dark.xml
@@ -16,13 +16,13 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
- android:state_focused="false"
- android:state_selected="false"
- android:state_pressed="false"
- android:drawable="@drawable/quickcontact_badge_overlay_normal_dark" />
-
- <item
android:state_pressed="true"
android:drawable="@drawable/quickcontact_badge_overlay_pressed_dark" />
+ <item
+ android:state_pressed="false"
+ android:state_focused="true"
+ android:drawable="@drawable/quickcontact_badge_overlay_focused_dark" />
+ <item
+ android:drawable="@drawable/quickcontact_badge_overlay_normal_dark" />
</selector>
diff --git a/core/res/res/drawable/quickcontact_badge_overlay_light.xml b/core/res/res/drawable/quickcontact_badge_overlay_light.xml
index bf95d52..cf7f916 100644
--- a/core/res/res/drawable/quickcontact_badge_overlay_light.xml
+++ b/core/res/res/drawable/quickcontact_badge_overlay_light.xml
@@ -16,13 +16,13 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
- android:state_focused="false"
- android:state_selected="false"
- android:state_pressed="false"
- android:drawable="@drawable/quickcontact_badge_overlay_normal_light" />
-
- <item
android:state_pressed="true"
android:drawable="@drawable/quickcontact_badge_overlay_pressed_light" />
+ <item
+ android:state_pressed="false"
+ android:state_focused="true"
+ android:drawable="@drawable/quickcontact_badge_overlay_focused_light" />
+ <item
+ android:drawable="@drawable/quickcontact_badge_overlay_normal_light" />
</selector>
diff --git a/core/res/res/drawable/tab_indicator_ab_holo.xml b/core/res/res/drawable/tab_indicator_ab_holo.xml
new file mode 100644
index 0000000..d8a5750
--- /dev/null
+++ b/core/res/res/drawable/tab_indicator_ab_holo.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Non focused states -->
+ <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@color/transparent" />
+ <item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_selected_holo" />
+
+ <!-- Focused states -->
+ <item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/list_focused_holo" />
+ <item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_selected_focused_holo" />
+
+ <!-- Pressed -->
+ <!-- Non focused states -->
+ <item android:state_focused="false" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/list_pressed_holo_dark" />
+ <item android:state_focused="false" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed_holo" />
+
+ <!-- Focused states -->
+ <item android:state_focused="true" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/tab_unselected_pressed_holo" />
+ <item android:state_focused="true" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed_holo" />
+</selector>
diff --git a/core/res/res/layout/action_menu_layout.xml b/core/res/res/layout/action_menu_layout.xml
index 5696d87..c401fec 100644
--- a/core/res/res/layout/action_menu_layout.xml
+++ b/core/res/res/layout/action_menu_layout.xml
@@ -18,6 +18,6 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:divider="?android:attr/dividerVertical"
+ android:divider="?android:attr/actionBarDivider"
android:dividerPadding="12dip"
android:gravity="center_vertical" />
diff --git a/core/res/res/values-sw600dp/dimens.xml b/core/res/res/values-sw600dp/dimens.xml
index 551c1d8..5b488c0 100644
--- a/core/res/res/values-sw600dp/dimens.xml
+++ b/core/res/res/values-sw600dp/dimens.xml
@@ -60,6 +60,12 @@
<!-- Compensate for double margin : preference_screen_side_margin + 4 (frame background shadow) = -preference_screen_side_margin_negative -->
<dimen name="preference_screen_side_margin_negative">-4dp</dimen>
+ <!-- Default padding to apply to AppWidgetHostViews containing widgets targeting API level 14 and up. -->
+ <dimen name="default_app_widget_padding_left">12dp</dimen>
+ <dimen name="default_app_widget_padding_top">12dp</dimen>
+ <dimen name="default_app_widget_padding_right">4dp</dimen>
+ <dimen name="default_app_widget_padding_bottom">20dp</dimen>
+
<!-- Minimum width for an action button in the menu area of an action bar -->
<dimen name="action_button_min_width">64dip</dimen>
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index a40e24c..d0ab8b1 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3331,6 +3331,9 @@
<attr name="popupPromptView" format="reference" />
<!-- Gravity setting for positioning the currently selected item. -->
<attr name="gravity" />
+ <!-- Whether this spinner should mark child views as enabled/disabled when
+ the spinner itself is enabled/disabled. -->
+ <attr name="disableChildrenWhenDisabled" format="boolean" />
</declare-styleable>
<declare-styleable name="DatePicker">
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
old mode 100755
new mode 100644
index 48e8f1e..8b07e34
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -166,6 +166,12 @@
</string-array>
<!-- List of regexpressions describing the interface (if any) that represent tetherable
+ WiMAX interfaces. If the device doesn't want to support tethering over Wifi this
+ should be empty. An example would be "softap.*" -->
+ <string-array translatable="false" name="config_tether_wimax_regexs">
+ </string-array>
+
+ <!-- List of regexpressions describing the interface (if any) that represent tetherable
bluetooth interfaces. If the device doesn't want to support tethering over bluetooth this
should be empty. -->
<string-array translatable="false" name="config_tether_bluetooth_regexs">
@@ -718,4 +724,16 @@
<!-- Default network policy warning threshold, in megabytes. -->
<integer name="config_networkPolicyDefaultWarning">2048</integer>
+ <!-- Set and Unsets WiMAX -->
+ <bool name="config_wimaxEnabled">false</bool>
+ <!-- Location of the wimax framwork jar location -->
+ <string name="config_wimaxServiceJarLocation"></string>
+ <!-- Location of the wimax native library locaiton -->
+ <string name="config_wimaxNativeLibLocation"></string>
+ <!-- Name of the wimax manager class -->
+ <string name="config_wimaxManagerClassname"></string>
+ <!-- Name of the wimax service class -->
+ <string name="config_wimaxServiceClassname"></string>
+ <!-- Name of the wimax state tracker clas -->
+ <string name="config_wimaxStateTrackerClassname"></string>
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 97d5afe..4d97ad2 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1974,5 +1974,4 @@
<public type="color" name="holo_orange_dark" id="0x01060019" />
<public type="color" name="holo_purple" id="0x0106001a" />
<public type="color" name="holo_blue_bright" id="0x0106001b" />
-
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
old mode 100755
new mode 100644
index a819173..2f40a5a
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1362,6 +1362,12 @@
than the non-multicast mode.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_accessWimaxState">view WiMAX state</string>
+ <string name="permdesc_accessWimaxState">Allows an application to view
+ the information about the state of WiMAX.</string>
+ <string name="permlab_changeWimaxState">change WiMAX state</string>
+ <string name="permdesc_changeWimaxState">Allows an application to connect
+ to and disconnect from WiMAX network.</string>
<string name="permlab_bluetoothAdmin">bluetooth administration</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_bluetoothAdmin" product="tablet">Allows an application to configure
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 8d95d86e5..73e1a7c 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1798,6 +1798,7 @@
<item name="android:dropDownWidth">wrap_content</item>
<item name="android:popupPromptView">@android:layout/simple_dropdown_hint</item>
<item name="android:gravity">left|center_vertical</item>
+ <item name="android:disableChildrenWhenDisabled">true</item>
</style>
<style name="Widget.Holo.Spinner.DropDown">
@@ -1823,6 +1824,7 @@
</style>
<style name="Widget.Holo.Tab" parent="Widget.Holo.ActionBar.TabView">
+ <item name="android:background">@android:drawable/tab_indicator_holo</item>
<item name="android:layout_width">0dip</item>
<item name="android:layout_weight">1</item>
<item name="android:minWidth">80dip</item>
@@ -1910,7 +1912,7 @@
</style>
<style name="Widget.Holo.ActionBar.TabView" parent="Widget.ActionBar.TabView">
- <item name="android:background">@drawable/tab_indicator_holo</item>
+ <item name="android:background">@drawable/tab_indicator_ab_holo</item>
<item name="android:paddingLeft">16dip</item>
<item name="android:paddingRight">16dip</item>
</style>
@@ -2277,6 +2279,10 @@
</style>
<style name="Widget.Holo.Light.Tab" parent="Widget.Holo.Light.ActionBar.TabView">
+ <item name="android:background">@android:drawable/tab_indicator_holo</item>
+ <item name="android:layout_width">0dip</item>
+ <item name="android:layout_weight">1</item>
+ <item name="android:minWidth">80dip</item>
</style>
<style name="Widget.Holo.Light.ActionBar.TabBar" parent="Widget.Holo.ActionBar.TabBar">
diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h
index 0e2cdf7..e905903 100644
--- a/include/media/IMediaPlayer.h
+++ b/include/media/IMediaPlayer.h
@@ -40,7 +40,6 @@
const KeyedVector<String8, String8>* headers) = 0;
virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0;
virtual status_t setDataSource(const sp<IStreamSource>& source) = 0;
- virtual status_t setVideoSurface(const sp<Surface>& surface) = 0;
virtual status_t setVideoSurfaceTexture(
const sp<ISurfaceTexture>& surfaceTexture) = 0;
virtual status_t prepareAsync() = 0;
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 4328d3c..80f43a3 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -117,9 +117,6 @@
return INVALID_OPERATION;
}
- // pass the buffered Surface to the media player service
- virtual status_t setVideoSurface(const sp<Surface>& surface) = 0;
-
// pass the buffered ISurfaceTexture to the media player service
virtual status_t setVideoSurfaceTexture(
const sp<ISurfaceTexture>& surfaceTexture) = 0;
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index 08835fb..e6a0cc5 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -170,7 +170,6 @@
status_t setDataSource(int fd, int64_t offset, int64_t length);
status_t setDataSource(const sp<IStreamSource> &source);
- status_t setVideoSurface(const sp<Surface>& surface);
status_t setVideoSurfaceTexture(
const sp<ISurfaceTexture>& surfaceTexture);
status_t setListener(const sp<MediaPlayerListener>& listener);
diff --git a/media/java/android/media/videoeditor/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java
index a862d00..590b4ae 100755
--- a/media/java/android/media/videoeditor/MediaImageItem.java
+++ b/media/java/android/media/videoeditor/MediaImageItem.java
@@ -154,7 +154,7 @@
final Bitmap imageBitmap;
- if (mHeight > maxResolution.second) {
+ if (mWidth > maxResolution.first || mHeight > maxResolution.second) {
/**
* We need to scale the image
*/
@@ -971,14 +971,13 @@
/**
* Create the bitmap from file
*/
- if (nativeWidth / bitmapWidth > 1) {
-
- final BitmapFactory.Options options = new BitmapFactory.Options();
- options.inSampleSize = nativeWidth / (int)bitmapWidth;
- srcBitmap = BitmapFactory.decodeFile(filename, options);
- } else {
- srcBitmap = BitmapFactory.decodeFile(filename);
- }
+ int sampleSize = (int) Math.ceil(Math.max(
+ (float) nativeWidth / bitmapWidth,
+ (float) nativeHeight / bitmapHeight));
+ sampleSize = nextPowerOf2(sampleSize);
+ final BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inSampleSize = sampleSize;
+ srcBitmap = BitmapFactory.decodeFile(filename, options);
} else {
bitmapWidth = width;
bitmapHeight = height;
@@ -1009,4 +1008,14 @@
srcBitmap.recycle();
return bitmap;
}
+
+ public static int nextPowerOf2(int n) {
+ n -= 1;
+ n |= n >>> 16;
+ n |= n >>> 8;
+ n |= n >>> 4;
+ n |= n >>> 2;
+ n |= n >>> 1;
+ return n + 1;
+ }
}
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index 50a41ca..9c1e6b7 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -35,7 +35,6 @@
SET_DATA_SOURCE_URL,
SET_DATA_SOURCE_FD,
SET_DATA_SOURCE_STREAM,
- SET_VIDEO_SURFACE,
PREPARE_ASYNC,
START,
STOP,
@@ -112,16 +111,6 @@
return reply.readInt32();
}
- // pass the buffered Surface to the media player service
- status_t setVideoSurface(const sp<Surface>& surface)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
- Surface::writeToParcel(surface, &data);
- remote()->transact(SET_VIDEO_SURFACE, data, &reply);
- return reply.readInt32();
- }
-
// pass the buffered ISurfaceTexture to the media player service
status_t setVideoSurfaceTexture(const sp<ISurfaceTexture>& surfaceTexture)
{
@@ -345,12 +334,6 @@
reply->writeInt32(setDataSource(source));
return NO_ERROR;
}
- case SET_VIDEO_SURFACE: {
- CHECK_INTERFACE(IMediaPlayer, data, reply);
- sp<Surface> surface = Surface::readFromParcel(data);
- reply->writeInt32(setVideoSurface(surface));
- return NO_ERROR;
- } break;
case SET_VIDEO_SURFACETEXTURE: {
CHECK_INTERFACE(IMediaPlayer, data, reply);
sp<ISurfaceTexture> surfaceTexture =
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index f72300b..c2e1ddf 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -219,14 +219,6 @@
return mPlayer->getMetadata(update_only, apply_filter, metadata);
}
-status_t MediaPlayer::setVideoSurface(const sp<Surface>& surface)
-{
- LOGV("setVideoSurface");
- Mutex::Autolock _l(mLock);
- if (mPlayer == 0) return NO_INIT;
- return mPlayer->setVideoSurface(surface);
-}
-
status_t MediaPlayer::setVideoSurfaceTexture(
const sp<ISurfaceTexture>& surfaceTexture)
{
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index b655358..e8d0f0c 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -788,14 +788,6 @@
return mStatus;
}
-status_t MediaPlayerService::Client::setVideoSurface(const sp<Surface>& surface)
-{
- LOGV("[%d] setVideoSurface(%p)", mConnId, surface.get());
- sp<MediaPlayerBase> p = getPlayer();
- if (p == 0) return UNKNOWN_ERROR;
- return p->setVideoSurface(surface);
-}
-
void MediaPlayerService::Client::disconnectNativeWindow() {
if (mConnectedWindow != NULL) {
status_t err = native_window_api_disconnect(mConnectedWindow.get(),
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 62214ba..04d9e28 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -248,7 +248,6 @@
// IMediaPlayer interface
virtual void disconnect();
- virtual status_t setVideoSurface(const sp<Surface>& surface);
virtual status_t setVideoSurfaceTexture(
const sp<ISurfaceTexture>& surfaceTexture);
virtual status_t prepareAsync();
diff --git a/media/libmediaplayerservice/MidiFile.h b/media/libmediaplayerservice/MidiFile.h
index b35696f1..3469389 100644
--- a/media/libmediaplayerservice/MidiFile.h
+++ b/media/libmediaplayerservice/MidiFile.h
@@ -35,7 +35,6 @@
const char* path, const KeyedVector<String8, String8> *headers);
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
- virtual status_t setVideoSurface(const sp<Surface>& surface) { return UNKNOWN_ERROR; }
virtual status_t setVideoSurfaceTexture(
const sp<ISurfaceTexture>& surfaceTexture)
{ return UNKNOWN_ERROR; }
diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp
index cd4b1ef..598d573 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.cpp
+++ b/media/libmediaplayerservice/StagefrightPlayer.cpp
@@ -69,12 +69,6 @@
return mPlayer->setDataSource(source);
}
-status_t StagefrightPlayer::setVideoSurface(const sp<Surface> &surface) {
- LOGV("setVideoSurface");
-
- return mPlayer->setSurface(surface);
-}
-
status_t StagefrightPlayer::setVideoSurfaceTexture(
const sp<ISurfaceTexture> &surfaceTexture) {
LOGV("setVideoSurfaceTexture");
diff --git a/media/libmediaplayerservice/StagefrightPlayer.h b/media/libmediaplayerservice/StagefrightPlayer.h
index cbc6d49..e89e18a 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.h
+++ b/media/libmediaplayerservice/StagefrightPlayer.h
@@ -40,7 +40,6 @@
virtual status_t setDataSource(const sp<IStreamSource> &source);
- virtual status_t setVideoSurface(const sp<Surface> &surface);
virtual status_t setVideoSurfaceTexture(
const sp<ISurfaceTexture> &surfaceTexture);
virtual status_t prepare();
diff --git a/media/libmediaplayerservice/TestPlayerStub.h b/media/libmediaplayerservice/TestPlayerStub.h
index 802a11b..91ffa7d 100644
--- a/media/libmediaplayerservice/TestPlayerStub.h
+++ b/media/libmediaplayerservice/TestPlayerStub.h
@@ -75,9 +75,6 @@
// All the methods below wrap the mPlayer instance.
- virtual status_t setVideoSurface(const android::sp<android::Surface>& s) {
- return mPlayer->setVideoSurface(s);
- }
virtual status_t setVideoSurfaceTexture(
const android::sp<android::ISurfaceTexture>& st) {
return mPlayer->setVideoSurfaceTexture(st);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 70208f8..2a5c0a6 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -99,12 +99,6 @@
msg->post();
}
-void NuPlayer::setVideoSurface(const sp<Surface> &surface) {
- sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
- msg->setObject("native-window", new NativeWindowWrapper(surface));
- msg->post();
-}
-
void NuPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
sp<SurfaceTextureClient> surfaceTextureClient(surfaceTexture != NULL ?
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index f90759d..f23deea 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -42,7 +42,6 @@
void setDataSource(
const char *url, const KeyedVector<String8, String8> *headers);
- void setVideoSurface(const sp<Surface> &surface);
void setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture);
void setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink);
void start();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 452ba99..5aa99bf 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -89,12 +89,6 @@
return OK;
}
-status_t NuPlayerDriver::setVideoSurface(const sp<Surface> &surface) {
- mPlayer->setVideoSurface(surface);
-
- return OK;
-}
-
status_t NuPlayerDriver::setVideoSurfaceTexture(
const sp<ISurfaceTexture> &surfaceTexture) {
mPlayer->setVideoSurfaceTexture(surfaceTexture);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index aaa3de0..4a0026c 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -37,7 +37,6 @@
virtual status_t setDataSource(const sp<IStreamSource> &source);
- virtual status_t setVideoSurface(const sp<Surface> &surface);
virtual status_t setVideoSurfaceTexture(
const sp<ISurfaceTexture> &surfaceTexture);
virtual status_t prepare();
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index f37e75b..7d9d7ed 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -1139,18 +1139,9 @@
return (mFlags & PLAYING) || (mFlags & CACHE_UNDERRUN);
}
-status_t AwesomePlayer::setSurface(const sp<Surface> &surface) {
- Mutex::Autolock autoLock(mLock);
-
- mSurface = surface;
- return setNativeWindow_l(surface);
-}
-
status_t AwesomePlayer::setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
Mutex::Autolock autoLock(mLock);
- mSurface.clear();
-
status_t err;
if (surfaceTexture != NULL) {
err = setNativeWindow_l(new SurfaceTextureClient(surfaceTexture));
diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp
index 1ba79e5..e4de20a 100644
--- a/media/libstagefright/CameraSourceTimeLapse.cpp
+++ b/media/libstagefright/CameraSourceTimeLapse.cpp
@@ -257,6 +257,12 @@
mForceRead = false;
*timestampUs =
mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
+
+ // Really make sure that this video recording frame will not be dropped.
+ if (*timestampUs < mStartTimeUs) {
+ LOGI("set timestampUs to start time stamp %lld us", mStartTimeUs);
+ *timestampUs = mStartTimeUs;
+ }
return false;
}
}
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 7d6bcad..c13d6cb 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -81,7 +81,6 @@
bool isPlaying() const;
- status_t setSurface(const sp<Surface> &surface);
status_t setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture);
void setAudioSink(const sp<MediaPlayerBase::AudioSink> &audioSink);
status_t setLooping(bool shouldLoop);
@@ -154,7 +153,6 @@
bool mUIDValid;
uid_t mUID;
- sp<Surface> mSurface;
sp<ANativeWindow> mNativeWindow;
sp<MediaPlayerBase::AudioSink> mAudioSink;
diff --git a/media/tests/players/invoke_mock_media_player.cpp b/media/tests/players/invoke_mock_media_player.cpp
index ed3051b..a6fdeea 100644
--- a/media/tests/players/invoke_mock_media_player.cpp
+++ b/media/tests/players/invoke_mock_media_player.cpp
@@ -68,7 +68,6 @@
}
virtual status_t setDataSource(int fd, int64_t offset, int64_t length) {return OK;}
- virtual status_t setVideoSurface(const sp<Surface>& surface) {return OK;}
virtual status_t setVideoSurfaceTexture(
const sp<ISurfaceTexture>& surfaceTexture) {return OK;}
virtual status_t prepare() {return OK;}
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 3920257..0891525 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -21,7 +21,7 @@
<integer name="def_screen_off_timeout">60000</integer>
<bool name="def_airplane_mode_on">false</bool>
<!-- Comma-separated list of bluetooth, wifi, and cell. -->
- <string name="def_airplane_mode_radios" translatable="false">cell,bluetooth,wifi,nfc</string>
+ <string name="def_airplane_mode_radios" translatable="false">cell,bluetooth,wifi,nfc,wimax</string>
<string name="airplane_mode_toggleable_radios" translatable="false">bluetooth,wifi,nfc</string>
<bool name="def_auto_time">true</bool>
<bool name="def_auto_time_zone">true</bool>
@@ -133,4 +133,8 @@
<bool name="def_dtmf_tones_enabled">true</bool>
<!-- Default for UI touch sounds enabled -->
<bool name="def_sound_effects_enabled">true</bool>
+
+ <!-- Default for Messaging app notifications enabled -->
+ <bool name="def_messaging_app_notifications_on">true</bool>
+
</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 5495d08..44194f0 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -1472,6 +1472,10 @@
loadBooleanSetting(stmt, Settings.Secure.TOUCH_EXPLORATION_ENABLED,
R.bool.def_touch_exploration_enabled);
+
+ loadBooleanSetting(stmt, Settings.Secure.MESSAGING_APP_NOTIFICATIONS,
+ R.bool.def_messaging_app_notifications_on);
+
} finally {
if (stmt != null) stmt.close();
}
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0.png
new file mode 100644
index 0000000..f24d801
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0_fully.png
new file mode 100644
index 0000000..66eb5db
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1.png
new file mode 100644
index 0000000..edff74a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1_fully.png
new file mode 100644
index 0000000..1cdd4eb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2.png
new file mode 100644
index 0000000..95fdaf9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2_fully.png
new file mode 100644
index 0000000..8678e39
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3.png
new file mode 100644
index 0000000..1d2d290
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png
new file mode 100644
index 0000000..c2e4b78
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png
new file mode 100644
index 0000000..51b839f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_idle.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_idle.png
new file mode 100644
index 0000000..b20c5c7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_idle.png
Binary files differ
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml
index fecef3d..46f4c39 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml
@@ -39,39 +39,39 @@
<ImageView
android:id="@+id/bluetooth"
- android:layout_height="32dp"
- android:layout_width="32dp"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
android:scaleType="centerInside"
- android:baseline="22dp"
+ android:baseline="18dp"
android:visibility="gone"
android:contentDescription="@null"
/>
<FrameLayout
android:id="@+id/netwerk"
- android:layout_height="32dp"
- android:layout_width="32dp"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
android:layout_marginRight="4dp"
>
<ImageView
android:id="@+id/network_signal"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
android:contentDescription="@null"
/>
<ImageView
android:id="@+id/network_type"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
android:contentDescription="@null"
/>
<ImageView
android:id="@+id/network_direction"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
android:contentDescription="@null"
/>
@@ -91,12 +91,14 @@
<ImageView
android:id="@+id/battery"
- android:layout_height="32dp"
- android:layout_width="32dp"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
android:scaleType="centerInside"
android:layout_toRightOf="@id/network_text"
android:layout_alignBaseline="@id/network_signal"
- android:baseline="22dp"
+ android:baseline="18dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:contentDescription="@null"
/>
diff --git a/packages/SystemUI/res/layout/signal_cluster_view.xml b/packages/SystemUI/res/layout/signal_cluster_view.xml
index eb644b3..93ac22e 100644
--- a/packages/SystemUI/res/layout/signal_cluster_view.xml
+++ b/packages/SystemUI/res/layout/signal_cluster_view.xml
@@ -52,6 +52,27 @@
android:id="@+id/spacer"
/>
<FrameLayout
+ android:id="@+id/wimax_combo"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_marginRight="-6dp"
+ >
+ <ImageView
+ android:id="@+id/wimax_signal"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_centerVertical="true"
+ android:scaleType="center"
+ />
+ <ImageView
+ android:id="@+id/wimax_inout"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center|bottom"
+ />
+ </FrameLayout>
+ <FrameLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 1a6cae2..a0d7b13 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -256,7 +256,12 @@
<!-- Content description of the WIFI signal when it is three bars for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_wifi_three_bars">Wi-Fi three bars.</string>
<!-- Content description of the WIFI signal when it is full for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_wifi_signal_full">Wi-Fi signal full.</string>
+ <string name="accessibility_wifi_signal_full">WiFi signal full.</string>
+ <string name="accessibility_no_wimax">No WiMAX.</string>
+ <string name="accessibility_wimax_one_bar">WiMAX one bar.</string>
+ <string name="accessibility_wimax_two_bars">WiMAX two bars.</string>
+ <string name="accessibility_wimax_three_bars">WiMAX three bars.</string>
+ <string name="accessibility_wimax_signal_full">WiMAX signal full.</string>
<!-- Content description of the data connection type GPRS for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_data_connection_gprs">GPRS</string>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index c6a59d3..b0e6968 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -350,7 +350,11 @@
(SignalClusterView)sb.findViewById(R.id.signal_cluster);
mNetworkController.addSignalCluster(signalCluster);
signalCluster.setNetworkController(mNetworkController);
-
+ final ImageView wimaxRSSI =
+ (ImageView)sb.findViewById(R.id.wimax_signal);
+ if (wimaxRSSI != null) {
+ mNetworkController.addWimaxIconView(wimaxRSSI);
+ }
// Recents Panel
mRecentTasksLoader = new RecentTasksLoader(context);
updateRecentsPanel();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityContentDescriptions.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityContentDescriptions.java
index 13fb03e..f45426b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityContentDescriptions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityContentDescriptions.java
@@ -34,4 +34,11 @@
R.string.accessibility_wifi_three_bars,
R.string.accessibility_wifi_signal_full
};
+ static final int[] WIMAX_CONNECTION_STRENGTH = {
+ R.string.accessibility_no_wimax,
+ R.string.accessibility_wimax_one_bar,
+ R.string.accessibility_wimax_two_bars,
+ R.string.accessibility_wimax_three_bars,
+ R.string.accessibility_wimax_signal_full
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index a305816..f77e93f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -31,6 +31,7 @@
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
+import android.net.wimax.WimaxManagerConstants;
import android.os.Binder;
import android.os.Handler;
import android.os.Message;
@@ -90,6 +91,7 @@
String mContentDescriptionPhoneSignal;
String mContentDescriptionWifi;
+ String mContentDescriptionWimax;
String mContentDescriptionCombinedSignal;
String mContentDescriptionDataType;
@@ -108,6 +110,14 @@
private int mBluetoothTetherIconId =
com.android.internal.R.drawable.stat_sys_tether_bluetooth;
+ //wimax
+ private boolean mIsWimaxEnabled = false;
+ private boolean mWimaxConnected = false;
+ private boolean mWimaxIdle = false;
+ private int mWimaxIconId = 0;
+ private int mWimaxSignal = 0;
+ private int mWimaxState = 0;
+ private int mWimaxExtraState = 0;
// data connectivity (regardless of state, can we access the internet?)
// state of inet connection - 0 not connected, 100 connected
private int mInetCondition = 0;
@@ -121,6 +131,7 @@
ArrayList<ImageView> mDataDirectionIconViews = new ArrayList<ImageView>();
ArrayList<ImageView> mDataDirectionOverlayIconViews = new ArrayList<ImageView>();
ArrayList<ImageView> mWifiIconViews = new ArrayList<ImageView>();
+ ArrayList<ImageView> mWimaxIconViews = new ArrayList<ImageView>();
ArrayList<ImageView> mCombinedSignalIconViews = new ArrayList<ImageView>();
ArrayList<ImageView> mDataTypeIconViews = new ArrayList<ImageView>();
ArrayList<TextView> mLabelViews = new ArrayList<TextView>();
@@ -129,6 +140,7 @@
int mLastDataDirectionIconId = -1;
int mLastDataDirectionOverlayIconId = -1;
int mLastWifiIconId = -1;
+ int mLastWimaxIconId = -1;
int mLastCombinedSignalIconId = -1;
int mLastDataTypeIconId = -1;
String mLastLabel = "";
@@ -164,6 +176,7 @@
// set up the default wifi icon, used when no radios have ever appeared
updateWifiIcons();
+ updateWimaxIcons();
// telephony
mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
@@ -200,6 +213,13 @@
filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ boolean isWimaxConfigEnabled = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_wimaxEnabled);
+ if(isWimaxConfigEnabled) {
+ filter.addAction(WimaxManagerConstants.WIMAX_NETWORK_STATE_CHANGED_ACTION);
+ filter.addAction(WimaxManagerConstants.SIGNAL_LEVEL_CHANGED_ACTION);
+ filter.addAction(WimaxManagerConstants.NET_4G_STATE_CHANGED_ACTION);
+ }
context.registerReceiver(this, filter);
// AIRPLANE_MODE_CHANGED is sent at boot; we've probably already missed it
@@ -224,6 +244,9 @@
public void addWifiIconView(ImageView v) {
mWifiIconViews.add(v);
}
+ public void addWimaxIconView(ImageView v) {
+ mWimaxIconViews.add(v);
+ }
public void addCombinedSignalIconView(ImageView v) {
mCombinedSignalIconViews.add(v);
@@ -285,6 +308,11 @@
} else if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
updateAirplaneMode();
refreshViews();
+ } else if (action.equals(WimaxManagerConstants.NET_4G_STATE_CHANGED_ACTION) ||
+ action.equals(WimaxManagerConstants.SIGNAL_LEVEL_CHANGED_ACTION) ||
+ action.equals(WimaxManagerConstants.WIMAX_NETWORK_STATE_CHANGED_ACTION)) {
+ updateWimaxState(intent);
+ refreshViews();
}
}
@@ -735,6 +763,51 @@
}
+ // ===== Wimax ===================================================================
+
+ private final void updateWimaxState(Intent intent) {
+ final String action = intent.getAction();
+ boolean wasConnected = mWimaxConnected;
+ if (action.equals(WimaxManagerConstants.NET_4G_STATE_CHANGED_ACTION)) {
+ int wimaxStatus = intent.getIntExtra(WimaxManagerConstants.EXTRA_4G_STATE,
+ WimaxManagerConstants.NET_4G_STATE_UNKNOWN);
+ mIsWimaxEnabled = (wimaxStatus ==
+ WimaxManagerConstants.NET_4G_STATE_ENABLED)? true : false;
+ } else if (action.equals(WimaxManagerConstants.SIGNAL_LEVEL_CHANGED_ACTION)) {
+ mWimaxSignal = intent.getIntExtra(WimaxManagerConstants.EXTRA_NEW_SIGNAL_LEVEL, 0);
+ } else if (action.equals(WimaxManagerConstants.WIMAX_NETWORK_STATE_CHANGED_ACTION)) {
+ mWimaxState = intent.getIntExtra(WimaxManagerConstants.EXTRA_WIMAX_STATE,
+ WimaxManagerConstants.NET_4G_STATE_UNKNOWN);
+ mWimaxExtraState = intent.getIntExtra(
+ WimaxManagerConstants.EXTRA_WIMAX_STATE_DETAIL,
+ WimaxManagerConstants.NET_4G_STATE_UNKNOWN);
+ mWimaxConnected = (mWimaxState ==
+ WimaxManagerConstants.WIMAX_STATE_CONNECTED) ? true : false;
+ mWimaxIdle = (mWimaxExtraState == WimaxManagerConstants.WIMAX_IDLE)? true : false;
+ }
+ updateWimaxIcons();
+ }
+ private void updateWimaxIcons() {
+ Slog.d(TAG, "in .... updateWimaxIcons function : "+mIsWimaxEnabled);
+ if (mIsWimaxEnabled) {
+ if (mWimaxConnected) {
+ Slog.d(TAG, "in .... updateWimaxIcons function WiMAX COnnected");
+ if (mWimaxIdle)
+ mWimaxIconId = WimaxIcons.WIMAX_IDLE;
+ else
+ mWimaxIconId = WimaxIcons.WIMAX_SIGNAL_STRENGTH[mInetCondition][mWimaxSignal];
+ mContentDescriptionWimax = mContext.getString(
+ AccessibilityContentDescriptions.WIMAX_CONNECTION_STRENGTH[mWimaxSignal]);
+ } else {
+ Slog.d(TAG, "in .... updateWimaxIcons function WiMAX Disconnected");
+ mWimaxIconId = WimaxIcons.WIMAX_DISCONNECTED;
+ mContentDescriptionWimax = mContext.getString(R.string.accessibility_no_wimax);
+ }
+ } else {
+ Slog.d(TAG, "in .... updateWimaxIcons function wimax icon id 0");
+ mWimaxIconId = 0;
+ }
+ }
// ===== Full or limited Internet connectivity ==================================
private void updateConnectivity(Intent intent) {
@@ -761,6 +834,7 @@
// We want to update all the icons, all at once, for any condition change
updateDataNetType();
+ updateWimaxIcons();
updateDataIcon();
updateTelephonySignalStrength();
updateWifiIcons();
@@ -945,6 +1019,21 @@
}
}
+ // the wimax icon on phones
+ if (mLastWimaxIconId != mWimaxIconId) {
+ mLastWimaxIconId = mWimaxIconId;
+ N = mWimaxIconViews.size();
+ for (int i=0; i<N; i++) {
+ final ImageView v = mWimaxIconViews.get(i);
+ if (mWimaxIconId == 0) {
+ v.setVisibility(View.INVISIBLE);
+ } else {
+ v.setVisibility(View.VISIBLE);
+ v.setImageResource(mWimaxIconId);
+ v.setContentDescription(mContentDescriptionWimax);
+ }
+ }
+ }
// the combined data signal icon
if (mLastCombinedSignalIconId != combinedSignalIconId) {
mLastCombinedSignalIconId = combinedSignalIconId;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WimaxIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WimaxIcons.java
new file mode 100644
index 0000000..8605489
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WimaxIcons.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2008 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.systemui.statusbar.policy;
+
+import com.android.systemui.R;
+
+class WimaxIcons {
+ static final int[][] WIMAX_SIGNAL_STRENGTH = {
+ { R.drawable.stat_sys_data_wimax_signal_0,
+ R.drawable.stat_sys_data_wimax_signal_1,
+ R.drawable.stat_sys_data_wimax_signal_2,
+ R.drawable.stat_sys_data_wimax_signal_3 },
+ { R.drawable.stat_sys_data_wimax_signal_0_fully,
+ R.drawable.stat_sys_data_wimax_signal_1_fully,
+ R.drawable.stat_sys_data_wimax_signal_2_fully,
+ R.drawable.stat_sys_data_wimax_signal_3_fully }
+ };
+
+ static final int WIMAX_DISCONNECTED =
+ R.drawable.stat_sys_data_wimax_signal_disconnected;
+ static final int WIMAX_IDLE = R.drawable.stat_sys_data_wimax_signal_idle;
+ static final int WIFI_LEVEL_COUNT = WIMAX_SIGNAL_STRENGTH[0].length;
+}
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index 3469483..24a2420 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -34,6 +34,7 @@
import android.widget.*;
import android.util.Log;
import android.media.AudioManager;
+import android.provider.MediaStore;
import android.provider.Settings;
import java.io.File;
@@ -225,9 +226,10 @@
mCallback.goToUnlockScreen();
} else if (target == 2 || target == 3) { // 2 = alt/portrait, 3 = alt/landscape
if (!mCameraDisabled) {
- // Broadcast an intent to start the Camera
- Intent intent = new Intent(Intent.ACTION_CAMERA_BUTTON, null);
- mContext.sendOrderedBroadcast(intent, null);
+ // Start the Camera
+ Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
mCallback.goToUnlockScreen();
} else {
toggleRingMode();
diff --git a/preloaded-classes b/preloaded-classes
index 31d49ce..c29ba15 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -18,7 +18,12 @@
android.accounts.IAccountManagerResponse$Stub
android.animation.Animator
android.animation.Animator$AnimatorListener
+android.animation.AnimatorInflater
android.animation.AnimatorListenerAdapter
+android.animation.AnimatorSet
+android.animation.AnimatorSet$AnimatorSetListener
+android.animation.AnimatorSet$Builder
+android.animation.AnimatorSet$Node
android.animation.FloatEvaluator
android.animation.FloatKeyframeSet
android.animation.IntEvaluator
@@ -57,6 +62,7 @@
android.app.ActivityThread$GcIdler
android.app.ActivityThread$H
android.app.ActivityThread$Idler
+android.app.ActivityThread$Profiler
android.app.ActivityThread$ProviderClientRecord
android.app.ActivityThread$ProviderRefCount
android.app.ActivityThread$ReceiverData
@@ -71,6 +77,8 @@
android.app.ApplicationPackageManager
android.app.ApplicationPackageManager$ResourceName
android.app.ApplicationThreadNative
+android.app.BackStackRecord
+android.app.BackStackRecord$Op
android.app.ContextImpl
android.app.ContextImpl$1
android.app.ContextImpl$10
@@ -111,9 +119,15 @@
android.app.Dialog
android.app.Dialog$1
android.app.Dialog$ListenersHandler
+android.app.DialogFragment
+android.app.Fragment
android.app.FragmentManager
+android.app.FragmentManager$BackStackEntry
android.app.FragmentManagerImpl
android.app.FragmentManagerImpl$1
+android.app.FragmentManagerImpl$2
+android.app.FragmentManagerImpl$3
+android.app.FragmentTransaction
android.app.IActivityManager
android.app.IActivityManager$ContentProviderHolder
android.app.IActivityManager$ContentProviderHolder$1
@@ -134,6 +148,10 @@
android.app.IntentReceiverLeaked
android.app.IntentService
android.app.IntentService$ServiceHandler
+android.app.ListActivity
+android.app.ListActivity$1
+android.app.ListActivity$2
+android.app.ListFragment
android.app.LoadedApk
android.app.LoadedApk$ReceiverDispatcher
android.app.LoadedApk$ReceiverDispatcher$Args
@@ -328,6 +346,7 @@
android.graphics.AvoidXfermode
android.graphics.Bitmap
android.graphics.Bitmap$1
+android.graphics.Bitmap$2
android.graphics.Bitmap$BitmapFinalizer
android.graphics.Bitmap$Config
android.graphics.BitmapFactory
@@ -719,6 +738,7 @@
android.text.style.MetricAffectingSpan
android.text.style.ParagraphStyle
android.text.style.ReplacementSpan
+android.text.style.SpellCheckSpan
android.text.style.StyleSpan
android.text.style.SuggestionSpan
android.text.style.UpdateAppearance
@@ -870,6 +890,7 @@
android.view.View$OnTouchListener
android.view.View$PerformClick
android.view.View$ScrollabilityCache
+android.view.View$TransformationInfo
android.view.View$UnsetPressedState
android.view.ViewConfiguration
android.view.ViewGroup
@@ -934,6 +955,7 @@
android.view.inputmethod.ExtractedText
android.view.inputmethod.ExtractedText$1
android.view.inputmethod.InputConnection
+android.view.inputmethod.InputConnectionWrapper
android.view.inputmethod.InputMethodManager
android.view.inputmethod.InputMethodManager$1
android.view.inputmethod.InputMethodManager$ControlledInputConnectionWrapper
@@ -946,12 +968,16 @@
android.widget.AbsListView
android.widget.AbsListView$1
android.widget.AbsListView$2
+android.widget.AbsListView$3
android.widget.AbsListView$AdapterDataSetObserver
android.widget.AbsListView$CheckForTap
+android.widget.AbsListView$FlingRunnable
+android.widget.AbsListView$FlingRunnable$1
android.widget.AbsListView$LayoutParams
android.widget.AbsListView$OnScrollListener
android.widget.AbsListView$PerformClick
android.widget.AbsListView$RecycleBin
+android.widget.AbsListView$RecyclerListener
android.widget.AbsListView$SavedState
android.widget.AbsListView$SavedState$1
android.widget.AbsListView$SelectionBoundsAdjuster
@@ -975,13 +1001,19 @@
android.widget.Checkable
android.widget.CheckedTextView
android.widget.CompoundButton
+android.widget.CompoundButton$OnCheckedChangeListener
android.widget.CursorAdapter
android.widget.CursorFilter$CursorFilterClient
+android.widget.EdgeEffect
android.widget.EdgeGlow
android.widget.EditText
android.widget.ExpandableListView
+android.widget.FastScroller
+android.widget.FastScroller$1
+android.widget.FastScroller$ScrollFade
android.widget.Filter
android.widget.Filter$FilterListener
+android.widget.Filter$FilterResults
android.widget.Filter$ResultsHandler
android.widget.Filterable
android.widget.FrameLayout
@@ -1030,17 +1062,30 @@
android.widget.Spinner
android.widget.SpinnerAdapter
android.widget.StackView
+android.widget.Switch
android.widget.TabHost
+android.widget.TabHost$ContentStrategy
+android.widget.TabHost$FactoryContentStrategy
+android.widget.TabHost$IndicatorStrategy
+android.widget.TabHost$LabelAndIconIndicatorStrategy
+android.widget.TabHost$OnTabChangeListener
+android.widget.TabHost$TabContentFactory
+android.widget.TabHost$TabSpec
+android.widget.TabHost$ViewIndicatorStrategy
android.widget.TabWidget
+android.widget.TabWidget$OnTabSelectionChanged
+android.widget.TabWidget$TabClickListener
android.widget.TableLayout
android.widget.TableRow
android.widget.TextView
+android.widget.TextView$2
android.widget.TextView$3
android.widget.TextView$Blink
android.widget.TextView$BufferType
android.widget.TextView$ChangeWatcher
android.widget.TextView$CharWrapper
android.widget.TextView$Drawables
+android.widget.TextView$EasyEditSpanController
android.widget.TextView$InputContentType
android.widget.TextView$InputMethodState
android.widget.TextView$OnEditorActionListener
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 69560e5..96e8eb9 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -2066,7 +2066,16 @@
// The first time a track is added we wait
// for all its buffers to be filled before processing it
mAudioMixer->setActiveTrack(track->name());
- if (cblk->framesReady() && track->isReady() &&
+ // make sure that we have enough frames to mix one full buffer
+ uint32_t minFrames = 1;
+ if (!track->isStopped() && !track->isPausing()) {
+ if (t->sampleRate() == (int)mSampleRate) {
+ minFrames = mFrameCount;
+ } else {
+ minFrames = (mFrameCount * t->sampleRate()) / mSampleRate + 1;
+ }
+ }
+ if ((cblk->framesReady() >= minFrames) && track->isReady() &&
!track->isPaused() && !track->isTerminated())
{
//LOGV("track %d u=%08x, s=%08x [OK] on thread %p", track->name(), cblk->user, cblk->server, this);
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 8c42f31..4af6112 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -26,8 +26,10 @@
import android.bluetooth.BluetoothTetheringDataTracker;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.ConnectivityManager;
import android.net.DummyDataStateTracker;
@@ -51,6 +53,7 @@
import android.net.ProxyProperties;
import android.net.RouteInfo;
import android.net.wifi.WifiStateTracker;
+import android.net.wimax.WimaxManagerConstants;
import android.os.Binder;
import android.os.FileUtils;
import android.os.Handler;
@@ -78,10 +81,14 @@
import com.android.server.connectivity.Vpn;
import com.google.android.collect.Lists;
import com.google.android.collect.Sets;
-
+import dalvik.system.DexClassLoader;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.InvocationTargetException;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
@@ -491,6 +498,12 @@
mNetTrackers[netType] = BluetoothTetheringDataTracker.getInstance();
mNetTrackers[netType].startMonitoring(context, mHandler);
break;
+ case ConnectivityManager.TYPE_WIMAX:
+ mNetTrackers[netType] = makeWimaxStateTracker();
+ if (mNetTrackers[netType]!= null) {
+ mNetTrackers[netType].startMonitoring(context, mHandler);
+ }
+ break;
case ConnectivityManager.TYPE_ETHERNET:
mNetTrackers[netType] = EthernetDataTracker.getInstance();
mNetTrackers[netType].startMonitoring(context, mHandler);
@@ -531,7 +544,81 @@
loadGlobalProxy();
}
+private NetworkStateTracker makeWimaxStateTracker() {
+ //Initialize Wimax
+ DexClassLoader wimaxClassLoader;
+ Class wimaxStateTrackerClass = null;
+ Class wimaxServiceClass = null;
+ Class wimaxManagerClass;
+ String wimaxJarLocation;
+ String wimaxLibLocation;
+ String wimaxManagerClassName;
+ String wimaxServiceClassName;
+ String wimaxStateTrackerClassName;
+ NetworkStateTracker wimaxStateTracker = null;
+
+ boolean isWimaxEnabled = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_wimaxEnabled);
+
+ if (isWimaxEnabled) {
+ try {
+ wimaxJarLocation = mContext.getResources().getString(
+ com.android.internal.R.string.config_wimaxServiceJarLocation);
+ wimaxLibLocation = mContext.getResources().getString(
+ com.android.internal.R.string.config_wimaxNativeLibLocation);
+ wimaxManagerClassName = mContext.getResources().getString(
+ com.android.internal.R.string.config_wimaxManagerClassname);
+ wimaxServiceClassName = mContext.getResources().getString(
+ com.android.internal.R.string.config_wimaxServiceClassname);
+ wimaxStateTrackerClassName = mContext.getResources().getString(
+ com.android.internal.R.string.config_wimaxStateTrackerClassname);
+
+ log("wimaxJarLocation: " + wimaxJarLocation);
+ wimaxClassLoader = new DexClassLoader(wimaxJarLocation,
+ new ContextWrapper(mContext).getCacheDir().getAbsolutePath(),
+ wimaxLibLocation, ClassLoader.getSystemClassLoader());
+
+ try {
+ wimaxManagerClass = wimaxClassLoader.loadClass(wimaxManagerClassName);
+ wimaxStateTrackerClass = wimaxClassLoader.loadClass(wimaxStateTrackerClassName);
+ wimaxServiceClass = wimaxClassLoader.loadClass(wimaxServiceClassName);
+ } catch (ClassNotFoundException ex) {
+ loge("Exception finding Wimax classes: " + ex.toString());
+ return null;
+ }
+ } catch(Resources.NotFoundException ex) {
+ loge("Wimax Resources does not exist!!! ");
+ return null;
+ }
+
+ try {
+ log("Starting Wimax Service... ");
+
+ Constructor wmxStTrkrConst = wimaxStateTrackerClass.getConstructor
+ (new Class[] {Context.class, Handler.class});
+ wimaxStateTracker = (NetworkStateTracker)wmxStTrkrConst.newInstance(mContext,
+ mHandler);
+
+ Constructor wmxSrvConst = wimaxServiceClass.getDeclaredConstructor
+ (new Class[] {Context.class, wimaxStateTrackerClass});
+ wmxSrvConst.setAccessible(true);
+ IBinder svcInvoker = (IBinder)wmxSrvConst.newInstance(mContext, wimaxStateTracker);
+ wmxSrvConst.setAccessible(false);
+
+ ServiceManager.addService(WimaxManagerConstants.WIMAX_SERVICE, svcInvoker);
+
+ } catch(Exception ex) {
+ loge("Exception creating Wimax classes: " + ex.toString());
+ return null;
+ }
+ } else {
+ loge("Wimax is not enabled or not added to the network attributes!!! ");
+ return null;
+ }
+
+ return wimaxStateTracker;
+ }
/**
* Sets the preferred network.
* @param preference the new preference
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index e49acaf..423a78f 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -81,6 +81,9 @@
private String[] mTetherableBluetoothRegexs;
private Collection<Integer> mUpstreamIfaceTypes;
+ // used to synchronize public access to members
+ private Object mPublicSync;
+
private static final Integer MOBILE_TYPE = new Integer(ConnectivityManager.TYPE_MOBILE);
private static final Integer HIPRI_TYPE = new Integer(ConnectivityManager.TYPE_MOBILE_HIPRI);
private static final Integer DUN_TYPE = new Integer(ConnectivityManager.TYPE_MOBILE_DUN);
@@ -135,6 +138,8 @@
mConnService = connService;
mLooper = looper;
+ mPublicSync = new Object();
+
mIfaces = new HashMap<String, TetherInterfaceSM>();
// make our own thread so we don't anr the system
@@ -172,18 +177,25 @@
}
void updateConfiguration() {
- mTetherableUsbRegexs = mContext.getResources().getStringArray(
+ String[] tetherableUsbRegexs = mContext.getResources().getStringArray(
com.android.internal.R.array.config_tether_usb_regexs);
- mTetherableWifiRegexs = mContext.getResources().getStringArray(
+ String[] tetherableWifiRegexs = mContext.getResources().getStringArray(
com.android.internal.R.array.config_tether_wifi_regexs);
- mTetherableBluetoothRegexs = mContext.getResources().getStringArray(
+ String[] tetherableBluetoothRegexs = mContext.getResources().getStringArray(
com.android.internal.R.array.config_tether_bluetooth_regexs);
int ifaceTypes[] = mContext.getResources().getIntArray(
com.android.internal.R.array.config_tether_upstream_types);
- mUpstreamIfaceTypes = new ArrayList();
+ Collection<Integer> upstreamIfaceTypes = new ArrayList();
for (int i : ifaceTypes) {
- mUpstreamIfaceTypes.add(new Integer(i));
+ upstreamIfaceTypes.add(new Integer(i));
+ }
+
+ synchronized (mPublicSync) {
+ mTetherableUsbRegexs = tetherableUsbRegexs;
+ mTetherableWifiRegexs = tetherableWifiRegexs;
+ mTetherableBluetoothRegexs = tetherableBluetoothRegexs;
+ mUpstreamIfaceTypes = upstreamIfaceTypes;
}
// check if the upstream type list needs to be modified due to secure-settings
@@ -194,17 +206,17 @@
if (VDBG) Log.d(TAG, "interfaceStatusChanged " + iface + ", " + up);
boolean found = false;
boolean usb = false;
- if (isWifi(iface)) {
- found = true;
- } else if (isUsb(iface)) {
- found = true;
- usb = true;
- } else if (isBluetooth(iface)) {
- found = true;
- }
- if (found == false) return;
+ synchronized (mPublicSync) {
+ if (isWifi(iface)) {
+ found = true;
+ } else if (isUsb(iface)) {
+ found = true;
+ usb = true;
+ } else if (isBluetooth(iface)) {
+ found = true;
+ }
+ if (found == false) return;
- synchronized (mIfaces) {
TetherInterfaceSM sm = mIfaces.get(iface);
if (up) {
if (sm == null) {
@@ -231,46 +243,52 @@
}
private boolean isUsb(String iface) {
- for (String regex : mTetherableUsbRegexs) {
- if (iface.matches(regex)) return true;
+ synchronized (mPublicSync) {
+ for (String regex : mTetherableUsbRegexs) {
+ if (iface.matches(regex)) return true;
+ }
+ return false;
}
- return false;
}
public boolean isWifi(String iface) {
- for (String regex : mTetherableWifiRegexs) {
- if (iface.matches(regex)) return true;
+ synchronized (mPublicSync) {
+ for (String regex : mTetherableWifiRegexs) {
+ if (iface.matches(regex)) return true;
+ }
+ return false;
}
- return false;
}
public boolean isBluetooth(String iface) {
- for (String regex : mTetherableBluetoothRegexs) {
- if (iface.matches(regex)) return true;
+ synchronized (mPublicSync) {
+ for (String regex : mTetherableBluetoothRegexs) {
+ if (iface.matches(regex)) return true;
+ }
+ return false;
}
- return false;
}
public void interfaceAdded(String iface) {
if (VDBG) Log.d(TAG, "interfaceAdded " + iface);
boolean found = false;
boolean usb = false;
- if (isWifi(iface)) {
- found = true;
- }
- if (isUsb(iface)) {
- found = true;
- usb = true;
- }
- if (isBluetooth(iface)) {
- found = true;
- }
- if (found == false) {
- if (VDBG) Log.d(TAG, iface + " is not a tetherable iface, ignoring");
- return;
- }
+ synchronized (mPublicSync) {
+ if (isWifi(iface)) {
+ found = true;
+ }
+ if (isUsb(iface)) {
+ found = true;
+ usb = true;
+ }
+ if (isBluetooth(iface)) {
+ found = true;
+ }
+ if (found == false) {
+ if (VDBG) Log.d(TAG, iface + " is not a tetherable iface, ignoring");
+ return;
+ }
- synchronized (mIfaces) {
TetherInterfaceSM sm = mIfaces.get(iface);
if (sm != null) {
if (VDBG) Log.d(TAG, "active iface (" + iface + ") reported as added, ignoring");
@@ -285,7 +303,7 @@
public void interfaceRemoved(String iface) {
if (VDBG) Log.d(TAG, "interfaceRemoved " + iface);
- synchronized (mIfaces) {
+ synchronized (mPublicSync) {
TetherInterfaceSM sm = mIfaces.get(iface);
if (sm == null) {
if (VDBG) {
@@ -303,7 +321,7 @@
public int tether(String iface) {
if (DBG) Log.d(TAG, "Tethering " + iface);
TetherInterfaceSM sm = null;
- synchronized (mIfaces) {
+ synchronized (mPublicSync) {
sm = mIfaces.get(iface);
}
if (sm == null) {
@@ -321,7 +339,7 @@
public int untether(String iface) {
if (DBG) Log.d(TAG, "Untethering " + iface);
TetherInterfaceSM sm = null;
- synchronized (mIfaces) {
+ synchronized (mPublicSync) {
sm = mIfaces.get(iface);
}
if (sm == null) {
@@ -338,16 +356,19 @@
public int getLastTetherError(String iface) {
TetherInterfaceSM sm = null;
- synchronized (mIfaces) {
+ synchronized (mPublicSync) {
sm = mIfaces.get(iface);
+ if (sm == null) {
+ Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface +
+ ", ignoring");
+ return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
+ }
+ return sm.getLastError();
}
- if (sm == null) {
- Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface + ", ignoring");
- return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
- }
- return sm.getLastError();
}
+ // TODO - move all private methods used only by the state machine into the state machine
+ // to clarify what needs synchronized protection.
private void sendTetherStateChangedBroadcast() {
try {
if (!mConnService.isTetheringSupported()) return;
@@ -363,7 +384,7 @@
boolean usbTethered = false;
boolean bluetoothTethered = false;
- synchronized (mIfaces) {
+ synchronized (mPublicSync) {
Set ifaces = mIfaces.keySet();
for (Object iface : ifaces) {
TetherInterfaceSM sm = mIfaces.get(iface);
@@ -469,7 +490,7 @@
public void onReceive(Context content, Intent intent) {
String action = intent.getAction();
if (action.equals(UsbManager.ACTION_USB_STATE)) {
- synchronized (Tethering.this) {
+ synchronized (Tethering.this.mPublicSync) {
boolean usbConnected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false);
mRndisEnabled = intent.getBooleanExtra(UsbManager.USB_FUNCTION_RNDIS, false);
// start tethering if we have a request pending
@@ -545,6 +566,7 @@
return true;
}
+ // TODO - return copies so people can't tamper
public String[] getTetherableUsbRegexs() {
return mTetherableUsbRegexs;
}
@@ -561,7 +583,7 @@
if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")");
UsbManager usbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);
- synchronized (this) {
+ synchronized (mPublicSync) {
if (enable) {
if (mRndisEnabled) {
tetherUsb(true);
@@ -581,11 +603,14 @@
}
public int[] getUpstreamIfaceTypes() {
- updateConfiguration();
- int values[] = new int[mUpstreamIfaceTypes.size()];
- Iterator<Integer> iterator = mUpstreamIfaceTypes.iterator();
- for (int i=0; i < mUpstreamIfaceTypes.size(); i++) {
- values[i] = iterator.next();
+ int values[];
+ synchronized (mPublicSync) {
+ updateConfiguration();
+ values = new int[mUpstreamIfaceTypes.size()];
+ Iterator<Integer> iterator = mUpstreamIfaceTypes.iterator();
+ for (int i=0; i < mUpstreamIfaceTypes.size(); i++) {
+ values[i] = iterator.next();
+ }
}
return values;
}
@@ -593,43 +618,46 @@
public void checkDunRequired() {
int secureSetting = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.TETHER_DUN_REQUIRED, 2);
- // 2 = not set, 0 = DUN not required, 1 = DUN required
- if (secureSetting != 2) {
- int requiredApn = (secureSetting == 1 ?
- ConnectivityManager.TYPE_MOBILE_DUN :
- ConnectivityManager.TYPE_MOBILE_HIPRI);
- if (requiredApn == ConnectivityManager.TYPE_MOBILE_DUN) {
- while (mUpstreamIfaceTypes.contains(MOBILE_TYPE)) {
- mUpstreamIfaceTypes.remove(MOBILE_TYPE);
- }
- while (mUpstreamIfaceTypes.contains(HIPRI_TYPE)) {
- mUpstreamIfaceTypes.remove(HIPRI_TYPE);
- }
- if (mUpstreamIfaceTypes.contains(DUN_TYPE) == false) {
- mUpstreamIfaceTypes.add(DUN_TYPE);
- }
- } else {
- while (mUpstreamIfaceTypes.contains(DUN_TYPE)) {
- mUpstreamIfaceTypes.remove(DUN_TYPE);
- }
- if (mUpstreamIfaceTypes.contains(MOBILE_TYPE) == false) {
- mUpstreamIfaceTypes.add(MOBILE_TYPE);
- }
- if (mUpstreamIfaceTypes.contains(HIPRI_TYPE) == false) {
- mUpstreamIfaceTypes.add(HIPRI_TYPE);
+ synchronized (mPublicSync) {
+ // 2 = not set, 0 = DUN not required, 1 = DUN required
+ if (secureSetting != 2) {
+ int requiredApn = (secureSetting == 1 ?
+ ConnectivityManager.TYPE_MOBILE_DUN :
+ ConnectivityManager.TYPE_MOBILE_HIPRI);
+ if (requiredApn == ConnectivityManager.TYPE_MOBILE_DUN) {
+ while (mUpstreamIfaceTypes.contains(MOBILE_TYPE)) {
+ mUpstreamIfaceTypes.remove(MOBILE_TYPE);
+ }
+ while (mUpstreamIfaceTypes.contains(HIPRI_TYPE)) {
+ mUpstreamIfaceTypes.remove(HIPRI_TYPE);
+ }
+ if (mUpstreamIfaceTypes.contains(DUN_TYPE) == false) {
+ mUpstreamIfaceTypes.add(DUN_TYPE);
+ }
+ } else {
+ while (mUpstreamIfaceTypes.contains(DUN_TYPE)) {
+ mUpstreamIfaceTypes.remove(DUN_TYPE);
+ }
+ if (mUpstreamIfaceTypes.contains(MOBILE_TYPE) == false) {
+ mUpstreamIfaceTypes.add(MOBILE_TYPE);
+ }
+ if (mUpstreamIfaceTypes.contains(HIPRI_TYPE) == false) {
+ mUpstreamIfaceTypes.add(HIPRI_TYPE);
+ }
}
}
- }
- if (mUpstreamIfaceTypes.contains(DUN_TYPE)) {
- mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_MOBILE_DUN;
- } else {
- mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_MOBILE_HIPRI;
+ if (mUpstreamIfaceTypes.contains(DUN_TYPE)) {
+ mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_MOBILE_DUN;
+ } else {
+ mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_MOBILE_HIPRI;
+ }
}
}
+ // TODO review API - maybe return ArrayList<String> here and below?
public String[] getTetheredIfaces() {
ArrayList<String> list = new ArrayList<String>();
- synchronized (mIfaces) {
+ synchronized (mPublicSync) {
Set keys = mIfaces.keySet();
for (Object key : keys) {
TetherInterfaceSM sm = mIfaces.get(key);
@@ -647,7 +675,7 @@
public String[] getTetheredIfacePairs() {
final ArrayList<String> list = Lists.newArrayList();
- synchronized (mIfaces) {
+ synchronized (mPublicSync) {
for (TetherInterfaceSM sm : mIfaces.values()) {
if (sm.isTethered()) {
list.add(sm.mMyUpstreamIfaceName);
@@ -660,7 +688,7 @@
public String[] getTetherableIfaces() {
ArrayList<String> list = new ArrayList<String>();
- synchronized (mIfaces) {
+ synchronized (mPublicSync) {
Set keys = mIfaces.keySet();
for (Object key : keys) {
TetherInterfaceSM sm = mIfaces.get(key);
@@ -678,7 +706,7 @@
public String[] getErroredIfaces() {
ArrayList<String> list = new ArrayList<String>();
- synchronized (mIfaces) {
+ synchronized (mPublicSync) {
Set keys = mIfaces.keySet();
for (Object key : keys) {
TetherInterfaceSM sm = mIfaces.get(key);
@@ -777,43 +805,54 @@
return res;
}
- public synchronized int getLastError() {
- return mLastError;
+ public int getLastError() {
+ synchronized (Tethering.this.mPublicSync) {
+ return mLastError;
+ }
}
- private synchronized void setLastError(int error) {
- mLastError = error;
+ private void setLastError(int error) {
+ synchronized (Tethering.this.mPublicSync) {
+ mLastError = error;
- if (isErrored()) {
- if (mUsb) {
- // note everything's been unwound by this point so nothing to do on
- // further error..
- Tethering.this.configureUsbIface(false);
+ if (isErrored()) {
+ if (mUsb) {
+ // note everything's been unwound by this point so nothing to do on
+ // further error..
+ Tethering.this.configureUsbIface(false);
+ }
}
}
}
- // synchronized between this getter and the following setter
- public synchronized boolean isAvailable() {
- return mAvailable;
+ public boolean isAvailable() {
+ synchronized (Tethering.this.mPublicSync) {
+ return mAvailable;
+ }
}
- private synchronized void setAvailable(boolean available) {
- mAvailable = available;
+ private void setAvailable(boolean available) {
+ synchronized (Tethering.this.mPublicSync) {
+ mAvailable = available;
+ }
}
- // synchronized between this getter and the following setter
- public synchronized boolean isTethered() {
- return mTethered;
+ public boolean isTethered() {
+ synchronized (Tethering.this.mPublicSync) {
+ return mTethered;
+ }
}
- private synchronized void setTethered(boolean tethered) {
- mTethered = tethered;
+ private void setTethered(boolean tethered) {
+ synchronized (Tethering.this.mPublicSync) {
+ mTethered = tethered;
+ }
}
- // synchronized between this getter and the following setter
- public synchronized boolean isErrored() {
- return (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR);
+ public boolean isErrored() {
+ synchronized (Tethering.this.mPublicSync) {
+ return (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR);
+ }
}
class InitialState extends State {
@@ -922,7 +961,7 @@
sendTetherStateChangedBroadcast();
}
- void cleanupUpstream() {
+ private void cleanupUpstream() {
if (mMyUpstreamIfaceName != null) {
// note that we don't care about errors here.
// sometimes interfaces are gone before we get
@@ -1237,21 +1276,23 @@
updateConfiguration();
- if (VDBG) {
- Log.d(TAG, "chooseUpstreamType has upstream iface types:");
- for (Integer netType : mUpstreamIfaceTypes) {
- Log.d(TAG, " " + netType);
+ synchronized (mPublicSync) {
+ if (VDBG) {
+ Log.d(TAG, "chooseUpstreamType has upstream iface types:");
+ for (Integer netType : mUpstreamIfaceTypes) {
+ Log.d(TAG, " " + netType);
+ }
}
- }
- for (Integer netType : mUpstreamIfaceTypes) {
- NetworkInfo info = null;
- try {
- info = mConnService.getNetworkInfo(netType.intValue());
- } catch (RemoteException e) { }
- if ((info != null) && info.isConnected()) {
- upType = netType.intValue();
- break;
+ for (Integer netType : mUpstreamIfaceTypes) {
+ NetworkInfo info = null;
+ try {
+ info = mConnService.getNetworkInfo(netType.intValue());
+ } catch (RemoteException e) { }
+ if ((info != null) && info.isConnected()) {
+ upType = netType.intValue();
+ break;
+ }
}
}
@@ -1479,14 +1520,14 @@
return;
}
- pw.println("mUpstreamIfaceTypes: ");
- for (Integer netType : mUpstreamIfaceTypes) {
- pw.println(" " + netType);
- }
+ synchronized (mPublicSync) {
+ pw.println("mUpstreamIfaceTypes: ");
+ for (Integer netType : mUpstreamIfaceTypes) {
+ pw.println(" " + netType);
+ }
- pw.println();
- pw.println("Tether state:");
- synchronized (mIfaces) {
+ pw.println();
+ pw.println("Tether state:");
for (Object o : mIfaces.values()) {
pw.println(" "+o.toString());
}
diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java
index 131f11c..8fc9a70 100644
--- a/services/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -88,13 +88,14 @@
try {
try {
mSurface = new Surface(session, 0, "FreezeSurface",
- -1, mWidth, mHeight, PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT);
+ -1, mWidth, mHeight, PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
if (mSurface == null || !mSurface.isValid()) {
// Screenshot failed, punt.
mSurface = null;
return;
}
mSurface.setLayer(FREEZE_LAYER + 1);
+ mSurface.show();
} catch (Surface.OutOfResourcesException e) {
Slog.w(TAG, "Unable to allocate freeze surface", e);
}
diff --git a/services/surfaceflinger/LayerScreenshot.cpp b/services/surfaceflinger/LayerScreenshot.cpp
index e30ccbf..68e6660 100644
--- a/services/surfaceflinger/LayerScreenshot.cpp
+++ b/services/surfaceflinger/LayerScreenshot.cpp
@@ -27,6 +27,7 @@
#include "SurfaceFlinger.h"
#include "DisplayHardware/DisplayHardware.h"
+
namespace android {
// ---------------------------------------------------------------------------
@@ -45,23 +46,64 @@
}
}
+status_t LayerScreenshot::captureLocked() {
+ GLfloat u, v;
+ status_t result = mFlinger->renderScreenToTextureLocked(0, &mTextureName, &u, &v);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ initTexture(u, v);
+ return NO_ERROR;
+}
+
status_t LayerScreenshot::capture() {
GLfloat u, v;
status_t result = mFlinger->renderScreenToTexture(0, &mTextureName, &u, &v);
if (result != NO_ERROR) {
return result;
}
+ initTexture(u, v);
+ return NO_ERROR;
+}
+void LayerScreenshot::initTexture(GLfloat u, GLfloat v) {
glBindTexture(GL_TEXTURE_2D, mTextureName);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
mTexCoords[0] = 0; mTexCoords[1] = v;
mTexCoords[2] = 0; mTexCoords[3] = 0;
mTexCoords[4] = u; mTexCoords[5] = 0;
mTexCoords[6] = u; mTexCoords[7] = v;
+}
- return NO_ERROR;
+void LayerScreenshot::initStates(uint32_t w, uint32_t h, uint32_t flags) {
+ LayerBaseClient::initStates(w, h, flags);
+ if (!(flags & ISurfaceComposer::eHidden)) {
+ capture();
+ }
+}
+
+uint32_t LayerScreenshot::doTransaction(uint32_t flags)
+{
+ const Layer::State& draw(drawingState());
+ const Layer::State& curr(currentState());
+
+ if (draw.flags & ISurfaceComposer::eLayerHidden) {
+ if (!(curr.flags & ISurfaceComposer::eLayerHidden)) {
+ // we're going from hidden to visible
+ status_t err = captureLocked();
+ if (err != NO_ERROR) {
+ LOGW("createScreenshotSurface failed (%s)", strerror(-err));
+ }
+ }
+ } else if (curr.flags & ISurfaceComposer::eLayerHidden) {
+ // we're going from visible to hidden
+ if (mTextureName) {
+ glDeleteTextures(1, &mTextureName);
+ mTextureName = 0;
+ }
+ }
+ return LayerBaseClient::doTransaction(flags);
}
void LayerScreenshot::onDraw(const Region& clip) const
diff --git a/services/surfaceflinger/LayerScreenshot.h b/services/surfaceflinger/LayerScreenshot.h
index e3a2b19..ab90047 100644
--- a/services/surfaceflinger/LayerScreenshot.h
+++ b/services/surfaceflinger/LayerScreenshot.h
@@ -41,12 +41,18 @@
status_t capture();
+ virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
+ virtual uint32_t doTransaction(uint32_t flags);
virtual void onDraw(const Region& clip) const;
virtual bool isOpaque() const { return false; }
virtual bool isSecure() const { return false; }
virtual bool isProtectedByApp() const { return false; }
virtual bool isProtectedByDRM() const { return false; }
virtual const char* getTypeId() const { return "LayerScreenshot"; }
+
+private:
+ status_t captureLocked();
+ void initTexture(GLfloat u, GLfloat v);
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a6d4147..8f4fdb8 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1360,11 +1360,6 @@
uint32_t w, uint32_t h, uint32_t flags)
{
sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
- status_t err = layer->capture();
- if (err != NO_ERROR) {
- layer.clear();
- LOGW("createScreenshotSurface failed (%s)", strerror(-err));
- }
return layer;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index ea5bfa7..17028db 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -186,6 +186,8 @@
status_t renderScreenToTexture(DisplayID dpy,
GLuint* textureName, GLfloat* uOut, GLfloat* vOut);
+ status_t renderScreenToTextureLocked(DisplayID dpy,
+ GLuint* textureName, GLfloat* uOut, GLfloat* vOut);
status_t postMessageAsync(const sp<MessageBase>& msg,
nsecs_t reltime=0, uint32_t flags = 0);
@@ -328,8 +330,6 @@
status_t turnElectronBeamOnImplLocked(int32_t mode);
status_t electronBeamOffAnimationImplLocked();
status_t electronBeamOnAnimationImplLocked();
- status_t renderScreenToTextureLocked(DisplayID dpy,
- GLuint* textureName, GLfloat* uOut, GLfloat* vOut);
void debugFlashRegions();
void debugShowFPS() const;
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
index 171b371..3dd57ee 100644
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ b/telephony/java/com/android/internal/telephony/CallManager.java
@@ -379,18 +379,19 @@
mode = AudioManager.MODE_RINGTONE;
break;
case OFFHOOK:
- Phone fgPhone = getFgPhone();
- // While foreground call is in DIALING,
- // ALERTING, ACTIVE and DISCONNECTING state
- if (getActiveFgCallState() != Call.State.IDLE
- && getActiveFgCallState() != Call.State.DISCONNECTED) {
- if (fgPhone instanceof SipPhone) {
- // enable IN_COMMUNICATION audio mode for sipPhone
- mode = AudioManager.MODE_IN_COMMUNICATION;
- } else {
- // enable IN_CALL audio mode for telephony
- mode = AudioManager.MODE_IN_CALL;
- }
+ Phone offhookPhone = getFgPhone();
+ if (getActiveFgCallState() == Call.State.IDLE) {
+ // There is no active Fg calls, the OFFHOOK state
+ // is set by the Bg call. So set the phone to bgPhone.
+ offhookPhone = getBgPhone();
+ }
+
+ if (offhookPhone instanceof SipPhone) {
+ // enable IN_COMMUNICATION audio mode for sipPhone
+ mode = AudioManager.MODE_IN_COMMUNICATION;
+ } else {
+ // enable IN_CALL audio mode for telephony
+ mode = AudioManager.MODE_IN_CALL;
}
break;
}
diff --git a/tests/FrameworkPerf/AndroidManifest.xml b/tests/FrameworkPerf/AndroidManifest.xml
index aa663f3..e88f4fb 100644
--- a/tests/FrameworkPerf/AndroidManifest.xml
+++ b/tests/FrameworkPerf/AndroidManifest.xml
@@ -13,6 +13,10 @@
</activity>
<service android:name="SchedulerService">
</service>
+ <service android:name="TestService" android:process=":test">
+ </service>
+ <service android:name="LocalTestService">
+ </service>
<receiver android:name="Receiver" android:exported="true">
</receiver>
</application>
diff --git a/tests/FrameworkPerf/res/layout/main.xml b/tests/FrameworkPerf/res/layout/main.xml
index 62b1a7a..7812648 100644
--- a/tests/FrameworkPerf/res/layout/main.xml
+++ b/tests/FrameworkPerf/res/layout/main.xml
@@ -91,6 +91,11 @@
android:layout_height="wrap_content"
android:text="@string/stop"
/>
+ <CheckBox android:id="@+id/local"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Local"
+ />
</LinearLayout>
<TextView android:id="@+id/log"
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java b/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java
index 3979902..175f227 100644
--- a/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java
@@ -17,191 +17,123 @@
package com.android.frameworkperf;
import android.app.Activity;
-import android.content.Context;
+import android.content.ComponentName;
import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
+import android.content.ServiceConnection;
+import android.os.Binder;
import android.os.Bundle;
-import android.os.FileUtils;
import android.os.Handler;
-import android.os.Looper;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
import android.os.PowerManager;
-import android.os.Process;
-import android.os.SystemClock;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
+import android.os.RemoteException;
import android.util.Log;
-import android.util.Xml;
-import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
+import android.widget.CheckBox;
import android.widget.Spinner;
import android.widget.TextView;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.RandomAccessFile;
import java.util.ArrayList;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
/**
* So you thought sync used up your battery life.
*/
public class FrameworkPerfActivity extends Activity
implements AdapterView.OnItemSelectedListener {
static final String TAG = "Perf";
-
- final Handler mHandler = new Handler();
+ static final boolean DEBUG = false;
Spinner mFgSpinner;
Spinner mBgSpinner;
TextView mTestTime;
Button mStartButton;
Button mStopButton;
+ CheckBox mLocalCheckBox;
TextView mLog;
PowerManager.WakeLock mPartialWakeLock;
long mMaxRunTime = 5000;
boolean mStarted;
- final TestRunner mRunner = new TestRunner();
-
- final Op[] mOpPairs = new Op[] {
- new MethodCallOp(), new NoOp(),
- new MethodCallOp(), new CpuOp(),
- new MethodCallOp(), new SchedulerOp(),
- new MethodCallOp(), new GcOp(),
- new MethodCallOp(), new CreateFileOp(),
- new MethodCallOp(), new CreateWriteFileOp(),
- new MethodCallOp(), new CreateWriteSyncFileOp(),
- new MethodCallOp(), new WriteFileOp(),
- new MethodCallOp(), new ReadFileOp(),
- new SchedulerOp(), new SchedulerOp(),
- new GcOp(), new NoOp(),
- new IpcOp(), new NoOp(),
- new IpcOp(), new CpuOp(),
- new IpcOp(), new SchedulerOp(),
- new IpcOp(), new GcOp(),
- new IpcOp(), new CreateFileOp(),
- new IpcOp(), new CreateWriteFileOp(),
- new IpcOp(), new CreateWriteSyncFileOp(),
- new IpcOp(), new WriteFileOp(),
- new IpcOp(), new ReadFileOp(),
- new CreateFileOp(), new NoOp(),
- new CreateWriteFileOp(), new NoOp(),
- new CreateWriteSyncFileOp(), new NoOp(),
- new WriteFileOp(), new NoOp(),
- new ReadFileOp(), new NoOp(),
- new WriteFileOp(), new CreateWriteFileOp(),
- new ReadFileOp(), new CreateWriteFileOp(),
- new WriteFileOp(), new CreateWriteSyncFileOp(),
- new ReadFileOp(), new CreateWriteSyncFileOp(),
- new WriteFileOp(), new WriteFileOp(),
- new WriteFileOp(), new ReadFileOp(),
- new ReadFileOp(), new WriteFileOp(),
- new ReadFileOp(), new ReadFileOp(),
- new OpenXmlResOp(), new NoOp(),
- new ReadXmlAttrsOp(), new NoOp(),
- new ParseXmlResOp(), new NoOp(),
- new ParseLargeXmlResOp(), new NoOp(),
- new LayoutInflaterOp(), new NoOp(),
- new LayoutInflaterLargeOp(), new NoOp(),
- new LayoutInflaterViewOp(), new NoOp(),
- new LayoutInflaterButtonOp(), new NoOp(),
- new LayoutInflaterImageButtonOp(), new NoOp(),
- new CreateBitmapOp(), new NoOp(),
- new CreateRecycleBitmapOp(), new NoOp(),
- new LoadSmallBitmapOp(), new NoOp(),
- new LoadRecycleSmallBitmapOp(), new NoOp(),
- new LoadLargeBitmapOp(), new NoOp(),
- new LoadRecycleLargeBitmapOp(), new NoOp(),
- new LoadSmallScaledBitmapOp(), new NoOp(),
- new LoadLargeScaledBitmapOp(), new NoOp(),
- };
-
- final Op[] mAvailOps = new Op[] {
- null,
- new NoOp(),
- new CpuOp(),
- new SchedulerOp(),
- new MethodCallOp(),
- new IpcOp(),
- new CreateFileOp(),
- new CreateWriteFileOp(),
- new CreateWriteSyncFileOp(),
- new WriteFileOp(),
- new ReadFileOp(),
- new OpenXmlResOp(),
- new ReadXmlAttrsOp(),
- new ParseXmlResOp(),
- new ParseLargeXmlResOp(),
- new LayoutInflaterOp(),
- new LayoutInflaterLargeOp(),
- new LayoutInflaterViewOp(),
- new LayoutInflaterButtonOp(),
- new LayoutInflaterImageButtonOp(),
- new CreateBitmapOp(),
- new CreateRecycleBitmapOp(),
- new LoadSmallBitmapOp(),
- new LoadRecycleSmallBitmapOp(),
- new LoadLargeBitmapOp(),
- new LoadRecycleLargeBitmapOp(),
- new LoadSmallScaledBitmapOp(),
- new LoadLargeScaledBitmapOp(),
- };
-
final String[] mAvailOpLabels;
final String[] mAvailOpDescriptions;
- Op mFgTest;
- Op mBgTest;
+ int mFgTestIndex = -1;
+ int mBgTestIndex = -1;
+ TestService.Op mFgTest;
+ TestService.Op mBgTest;
int mCurOpIndex = 0;
-
- class RunResult {
- final String name;
- final String fgLongName;
- final String bgLongName;
- final long fgTime;
- final long fgOps;
- final long bgTime;
- final long bgOps;
-
- RunResult(TestRunner op) {
- name = op.getName();
- fgLongName = op.getForegroundLongName();
- bgLongName = op.getBackgroundLongName();
- fgTime = op.getForegroundTime();
- fgOps = op.getForegroundOps();
- bgTime = op.getBackgroundTime();
- bgOps = op.getBackgroundOps();
- }
-
- float getFgMsPerOp() {
- return fgOps != 0 ? (fgTime / (float)fgOps) : 0;
- }
-
- float getBgMsPerOp() {
- return bgOps != 0 ? (bgTime / (float)bgOps) : 0;
- }
- }
+ TestConnection mCurConnection;
+ boolean mConnectionBound;
final ArrayList<RunResult> mResults = new ArrayList<RunResult>();
+ class TestConnection implements ServiceConnection, IBinder.DeathRecipient {
+ Messenger mService;
+ boolean mLinked;
+
+ @Override public void onServiceConnected(ComponentName name, IBinder service) {
+ try {
+ if (!(service instanceof Binder)) {
+ // If remote, we'll be killing ye.
+ service.linkToDeath(this, 0);
+ mLinked = true;
+ }
+ mService = new Messenger(service);
+ dispatchCurOp(this);
+ } catch (RemoteException e) {
+ // Whoops, service has disappeared... try starting again.
+ Log.w(TAG, "Test service died, starting again");
+ startCurOp();
+ }
+ }
+
+ @Override public void onServiceDisconnected(ComponentName name) {
+ }
+
+ @Override public void binderDied() {
+ cleanup();
+ connectionDied(this);
+ }
+
+ void cleanup() {
+ if (mLinked) {
+ mLinked = false;
+ mService.getBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ static final int MSG_DO_NEXT_TEST = 1000;
+
+ final Handler mHandler = new Handler() {
+ @Override public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case TestService.RES_TEST_FINISHED: {
+ Bundle bundle = (Bundle)msg.obj;
+ bundle.setClassLoader(getClassLoader());
+ RunResult res = (RunResult)bundle.getParcelable("res");
+ completeCurOp(res);
+ } break;
+ case MSG_DO_NEXT_TEST: {
+ startCurOp();
+ } break;
+ }
+ }
+ };
+
+ final Messenger mMessenger = new Messenger(mHandler);
+
public FrameworkPerfActivity() {
- mAvailOpLabels = new String[mAvailOps.length];
- mAvailOpDescriptions = new String[mAvailOps.length];
- for (int i=0; i<mAvailOps.length; i++) {
- Op op = mAvailOps[i];
+ mAvailOpLabels = new String[TestService.mAvailOps.length];
+ mAvailOpDescriptions = new String[TestService.mAvailOps.length];
+ for (int i=0; i<TestService.mAvailOps.length; i++) {
+ TestService.Op op = TestService.mAvailOps[i];
if (op == null) {
mAvailOpLabels[i] = "All";
mAvailOpDescriptions[i] = "All tests";
@@ -251,6 +183,7 @@
}
});
mStopButton.setEnabled(false);
+ mLocalCheckBox = (CheckBox)findViewById(R.id.local);
mLog = (TextView)findViewById(R.id.log);
@@ -262,11 +195,13 @@
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (parent == mFgSpinner || parent == mBgSpinner) {
- Op op = mAvailOps[position];
+ TestService.Op op = TestService.mAvailOps[position];
if (parent == mFgSpinner) {
+ mFgTestIndex = position;
mFgTest = op;
((TextView)findViewById(R.id.fgtext)).setText(mAvailOpDescriptions[position]);
} else {
+ mBgTestIndex = position;
mBgTest = op;
((TextView)findViewById(R.id.bgtext)).setText(mAvailOpDescriptions[position]);
}
@@ -291,64 +226,140 @@
}
}
- void startCurOp() {
- Op fgOp, bgOp;
- if (mFgTest == null && mBgTest == null) {
- fgOp = mOpPairs[mCurOpIndex];
- bgOp = mOpPairs[mCurOpIndex+1];
- } else if (mFgTest != null && mBgTest != null) {
- fgOp = mFgTest;
- bgOp = mBgTest;
- } else if (mFgTest != null) {
- // Skip null test.
- if (mCurOpIndex == 0) {
- mCurOpIndex = 1;
- }
- fgOp = mFgTest;
- bgOp = mAvailOps[mCurOpIndex];
+ void dispatchCurOp(TestConnection conn) {
+ if (mCurConnection != conn) {
+ Log.w(TAG, "Dispatching on invalid connection: " + conn);
+ return;
+ }
+ TestArgs args = new TestArgs();
+ args.maxTime = mMaxRunTime;
+ if (mFgTestIndex == 0 && mBgTestIndex == 0) {
+ args.combOp = mCurOpIndex;
+ } else if (mFgTestIndex != 0 && mBgTestIndex != 0) {
+ args.fgOp = mFgTestIndex;
+ args.bgOp = mBgTestIndex;
} else {
// Skip null test.
if (mCurOpIndex == 0) {
mCurOpIndex = 1;
}
- fgOp = mAvailOps[mCurOpIndex];
- bgOp = mBgTest;
- }
- mRunner.run(mHandler, fgOp, bgOp, new Runnable() {
- @Override public void run() {
- RunResult result = new RunResult(mRunner);
- log(String.format("%s: fg=%d*%gms/op (%dms) / bg=%d*%gms/op (%dms)",
- result.name, result.fgOps, result.getFgMsPerOp(), result.fgTime,
- result.bgOps, result.getBgMsPerOp(), result.bgTime));
- mResults.add(result);
- if (!mStarted) {
- log("Stop");
- stopRunning();
- return;
- }
- if (mFgTest != null && mBgTest != null) {
- log("Finished");
- stopRunning();
- return;
- }
- if (mFgTest == null && mBgTest == null) {
- mCurOpIndex+=2;
- if (mCurOpIndex >= mOpPairs.length) {
- log("Finished");
- stopRunning();
- return;
- }
- } else {
- mCurOpIndex++;
- if (mCurOpIndex >= mAvailOps.length) {
- log("Finished");
- stopRunning();
- return;
- }
- }
- startCurOp();
+ if (mFgTestIndex != 0) {
+ args.fgOp = mFgTestIndex;
+ args.bgOp = mCurOpIndex;
+ } else {
+ args.fgOp = mCurOpIndex;
+ args.bgOp = mFgTestIndex;
}
- });
+ }
+ Bundle bundle = new Bundle();
+ bundle.putParcelable("args", args);
+ Message msg = Message.obtain(null, TestService.CMD_START_TEST, bundle);
+ msg.replyTo = mMessenger;
+ try {
+ conn.mService.send(msg);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failure communicating with service", e);
+ }
+ }
+
+ void completeCurOp(RunResult result) {
+ log(String.format("%s: fg=%d*%gms/op (%dms) / bg=%d*%gms/op (%dms)",
+ result.name, result.fgOps, result.getFgMsPerOp(), result.fgTime,
+ result.bgOps, result.getBgMsPerOp(), result.bgTime));
+ mResults.add(result);
+ if (!mStarted) {
+ log("Stop");
+ stopRunning();
+ return;
+ }
+ if (mFgTest != null && mBgTest != null) {
+ log("Finished");
+ stopRunning();
+ return;
+ }
+ if (mFgTest == null && mBgTest == null) {
+ mCurOpIndex+=2;
+ if (mCurOpIndex >= TestService.mOpPairs.length) {
+ log("Finished");
+ stopRunning();
+ return;
+ }
+ } else {
+ mCurOpIndex++;
+ if (mCurOpIndex >= TestService.mAvailOps.length) {
+ log("Finished");
+ stopRunning();
+ return;
+ }
+ }
+ startCurOp();
+ }
+
+ void disconnect() {
+ final TestConnection conn = mCurConnection;
+ if (conn != null) {
+ if (DEBUG) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Log.i(TAG, "Unbinding " + conn, here);
+ }
+ if (mConnectionBound) {
+ unbindService(conn);
+ mConnectionBound = false;
+ }
+ if (conn.mLinked) {
+ Message msg = Message.obtain(null, TestService.CMD_TERMINATE);
+ try {
+ conn.mService.send(msg);
+ return;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Test service aleady died when terminating");
+ }
+ }
+ conn.cleanup();
+ }
+ connectionDied(conn);
+ }
+
+ void connectionDied(TestConnection conn) {
+ if (mCurConnection == conn) {
+ // Now that we know the test process has died, we can commence
+ // the next test. Just give a little delay to allow the activity
+ // manager to know it has died as well (not a disaster if it hasn't
+ // yet, though).
+ if (mConnectionBound) {
+ unbindService(conn);
+ }
+ mCurConnection = null;
+ mHandler.sendMessageDelayed(Message.obtain(null, MSG_DO_NEXT_TEST), 100);
+ }
+ }
+
+ void startCurOp() {
+ if (DEBUG) Log.i(TAG, "startCurOp: mCurConnection=" + mCurConnection);
+ if (mCurConnection != null) {
+ disconnect();
+ return;
+ }
+ if (mStarted) {
+ mHandler.removeMessages(TestService.RES_TEST_FINISHED);
+ mHandler.removeMessages(TestService.RES_TERMINATED);
+ mHandler.removeMessages(MSG_DO_NEXT_TEST);
+ mCurConnection = new TestConnection();
+ Intent intent;
+ if (mLocalCheckBox.isChecked()) {
+ intent = new Intent(this, LocalTestService.class);
+ } else {
+ intent = new Intent(this, TestService.class);
+ }
+ if (DEBUG) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Log.i(TAG, "Binding " + mCurConnection, here);
+ }
+ bindService(intent, mCurConnection, BIND_AUTO_CREATE|BIND_IMPORTANT);
+ mConnectionBound = true;
+ }
}
void startRunning() {
@@ -357,6 +368,7 @@
mStarted = true;
mStartButton.setEnabled(false);
mStopButton.setEnabled(true);
+ mLocalCheckBox.setEnabled(false);
mTestTime.setEnabled(false);
mFgSpinner.setEnabled(false);
mBgSpinner.setEnabled(false);
@@ -371,9 +383,11 @@
void stopRunning() {
if (mStarted) {
+ disconnect();
mStarted = false;
mStartButton.setEnabled(true);
mStopButton.setEnabled(false);
+ mLocalCheckBox.setEnabled(true);
mTestTime.setEnabled(true);
mFgSpinner.setEnabled(true);
mBgSpinner.setEnabled(true);
@@ -412,842 +426,4 @@
mLog.setText(mLog.getText() + "\n" + s);
Log.i(TAG, s);
}
-
- enum BackgroundMode {
- NOTHING,
- CPU,
- SCHEDULER
- };
-
- public class TestRunner {
- Handler mHandler;
- Op mForegroundOp;
- Op mBackgroundOp;
- Runnable mDoneCallback;
-
- RunnerThread mBackgroundThread;
- RunnerThread mForegroundThread;
- long mStartTime;
-
- boolean mBackgroundRunning;
- boolean mForegroundRunning;
-
- long mBackgroundEndTime;
- long mBackgroundOps;
- long mForegroundEndTime;
- long mForegroundOps;
-
- public TestRunner() {
- }
-
- public String getForegroundName() {
- return mForegroundOp.getName();
- }
-
- public String getBackgroundName() {
- return mBackgroundOp.getName();
- }
-
- public String getName() {
- String fgName = mForegroundOp.getName();
- String bgName = mBackgroundOp.getName();
- StringBuilder res = new StringBuilder();
- if (fgName != null) {
- res.append(fgName);
- res.append("Fg");
- }
- if (bgName != null) {
- res.append(bgName);
- res.append("Bg");
- }
- return res.toString();
- }
-
- public String getForegroundLongName() {
- return mForegroundOp.getLongName();
- }
-
- public String getBackgroundLongName() {
- return mBackgroundOp.getLongName();
- }
-
- public void run(Handler handler, Op foreground, Op background, Runnable doneCallback) {
- mHandler = handler;
- mForegroundOp = foreground;
- mBackgroundOp = background;
- mDoneCallback = doneCallback;
- mBackgroundThread = new RunnerThread("background", new Runnable() {
- @Override public void run() {
- boolean running;
- int ops = 0;
- do {
- running = mBackgroundOp.onRun();
- ops++;
- } while (evalRepeat(running, true) && running);
- mBackgroundEndTime = SystemClock.uptimeMillis();
- mBackgroundOps = ops * mBackgroundOp.getOpsPerRun();
- threadFinished(false);
- }
- }, Process.THREAD_PRIORITY_BACKGROUND);
- mForegroundThread = new RunnerThread("background", new Runnable() {
- @Override public void run() {
- boolean running;
- int ops = 0;
- do {
- running = mForegroundOp.onRun();
- ops++;
- } while (evalRepeat(true, running) && running);
- mForegroundEndTime = SystemClock.uptimeMillis();
- mForegroundOps = ops * mForegroundOp.getOpsPerRun();
- threadFinished(true);
- }
- }, Process.THREAD_PRIORITY_FOREGROUND);
-
- mForegroundOp.onInit(FrameworkPerfActivity.this, true);
- mBackgroundOp.onInit(FrameworkPerfActivity.this, false);
-
- synchronized (this) {
- mStartTime = SystemClock.uptimeMillis();
- mBackgroundRunning = true;
- mForegroundRunning = true;
- }
-
- mBackgroundThread.start();
- mForegroundThread.start();
- }
-
- public long getForegroundTime() {
- return mForegroundEndTime-mStartTime;
- }
-
- public long getForegroundOps() {
- return mForegroundOps;
- }
-
- public long getBackgroundTime() {
- return mBackgroundEndTime-mStartTime;
- }
-
- public long getBackgroundOps() {
- return mBackgroundOps;
- }
-
- private boolean evalRepeat(boolean bgRunning, boolean fgRunning) {
- synchronized (this) {
- if (!bgRunning) {
- mBackgroundRunning = false;
- }
- if (!fgRunning) {
- mForegroundRunning = false;
- }
- if (!mBackgroundRunning && !mForegroundRunning) {
- return false;
- }
- long now = SystemClock.uptimeMillis();
- if (now > (mStartTime+mMaxRunTime)) {
- return false;
- }
- return true;
- }
- }
-
- private void threadFinished(boolean foreground) {
- synchronized (this) {
- if (foreground) {
- mForegroundRunning = false;
- } else {
- mBackgroundRunning = false;
- }
- if (!mBackgroundRunning && !mForegroundRunning) {
- mHandler.post(new Runnable() {
- @Override public void run() {
- mForegroundOp.onTerm(FrameworkPerfActivity.this);
- mBackgroundOp.onTerm(FrameworkPerfActivity.this);
- if (mDoneCallback != null) {
- mDoneCallback.run();
- }
- }
- });
- }
- }
- }
- }
-
- class RunnerThread extends Thread {
- private final Runnable mOp;
- private final int mPriority;
-
- RunnerThread(String name, Runnable op, int priority) {
- super(name);
- mOp = op;
- mPriority = priority;
- }
-
- public void run() {
- Process.setThreadPriority(mPriority);
- mOp.run();
- }
- }
-
- static public abstract class Op {
- final String mName;
- final String mLongName;
-
- public Op(String name, String longName) {
- mName = name;
- mLongName = longName;
- }
-
- public String getName() {
- return mName;
- }
-
- public String getLongName() {
- return mLongName;
- }
-
- void onInit(Context context, boolean foreground) {
- }
-
- abstract boolean onRun();
-
- void onTerm(Context context) {
- }
-
- int getOpsPerRun() {
- return 1;
- }
- }
-
- static class NoOp extends Op {
- NoOp() {
- super(null, "Nothing");
- }
-
- boolean onRun() {
- return false;
- }
-
- int getOpsPerRun() {
- return 0;
- }
- }
-
- static class CpuOp extends Op {
- CpuOp() {
- super("CPU", "Consume CPU");
- }
-
- boolean onRun() {
- return true;
- }
- }
-
- static class SchedulerOp extends Op {
- SchedulerOp() {
- super("Sched", "Change scheduler group");
- }
-
- boolean onRun() {
- Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
- Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
- return true;
- }
- }
-
- static class GcOp extends Op {
- GcOp() {
- super("Gc", "Run garbage collector");
- }
-
- boolean onRun() {
- byte[] stuff = new byte[1024*1024];
- return true;
- }
- }
-
- static class MethodCallOp extends Op {
- MethodCallOp() {
- super("MethodCall", "Method call");
- }
-
- boolean onRun() {
- final int N = getOpsPerRun();
- for (int i=0; i<N; i++) {
- someFunc(i);
- }
- return true;
- }
-
- int someFunc(int foo) {
- return 0;
- }
-
- int getOpsPerRun() {
- return 500;
- }
- }
-
- static class IpcOp extends Op {
- PackageManager mPm;
- String mProcessName;
-
- IpcOp() {
- super("Ipc", "IPC to system process");
- }
-
- void onInit(Context context, boolean foreground) {
- mPm = context.getPackageManager();
- mProcessName = context.getApplicationInfo().processName;
- }
-
- boolean onRun() {
- final int N = getOpsPerRun();
- for (int i=0; i<N; i++) {
- mPm.queryContentProviders(mProcessName, Process.myUid(), 0);
- }
- return true;
- }
-
- int getOpsPerRun() {
- return 100;
- }
- }
-
- static class OpenXmlResOp extends Op {
- Context mContext;
-
- OpenXmlResOp() {
- super("OpenXmlRes", "Open (and close) an XML resource");
- }
-
- void onInit(Context context, boolean foreground) {
- mContext = context;
- }
-
- boolean onRun() {
- XmlResourceParser parser = mContext.getResources().getLayout(R.xml.simple);
- parser.close();
- return true;
- }
- }
-
- static class ReadXmlAttrsOp extends Op {
- Context mContext;
- XmlResourceParser mParser;
- AttributeSet mAttrs;
-
- ReadXmlAttrsOp() {
- super("ReadXmlAttrs", "Read attributes from an XML tag");
- }
-
- void onInit(Context context, boolean foreground) {
- mContext = context;
- mParser = mContext.getResources().getLayout(R.xml.simple);
- mAttrs = Xml.asAttributeSet(mParser);
-
- int eventType;
- try {
- // Find the first <item> tag.
- eventType = mParser.getEventType();
- String tagName;
- do {
- if (eventType == XmlPullParser.START_TAG) {
- tagName = mParser.getName();
- if (tagName.equals("item")) {
- break;
- }
- }
- eventType = mParser.next();
- } while (eventType != XmlPullParser.END_DOCUMENT);
- } catch (XmlPullParserException e) {
- throw new RuntimeException("I died", e);
- } catch (IOException e) {
- throw new RuntimeException("I died", e);
- }
- }
-
- void onTerm(Context context) {
- mParser.close();
- }
-
- boolean onRun() {
- TypedArray a = mContext.obtainStyledAttributes(mAttrs,
- com.android.internal.R.styleable.MenuItem);
- a.recycle();
- return true;
- }
- }
-
- static class ParseXmlResOp extends Op {
- Context mContext;
-
- ParseXmlResOp() {
- super("ParseXmlRes", "Parse compiled XML resource");
- }
-
- void onInit(Context context, boolean foreground) {
- mContext = context;
- }
-
- boolean onRun() {
- SimpleInflater inf = new SimpleInflater(mContext);
- inf.inflate(R.xml.simple);
- return true;
- }
- }
-
- static class ParseLargeXmlResOp extends Op {
- Context mContext;
-
- ParseLargeXmlResOp() {
- super("ParseLargeXmlRes", "Parse large XML resource");
- }
-
- void onInit(Context context, boolean foreground) {
- mContext = context;
- }
-
- boolean onRun() {
- SimpleInflater inf = new SimpleInflater(mContext);
- inf.inflate(R.xml.simple_large);
- return true;
- }
- }
-
- static class LayoutInflaterOp extends Op {
- Context mContext;
-
- LayoutInflaterOp() {
- super("LayoutInflater", "Inflate layout resource");
- }
-
- void onInit(Context context, boolean foreground) {
- mContext = context;
- }
-
- boolean onRun() {
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
- LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- inf.inflate(R.layout.small_layout, null);
- return true;
- }
- }
-
- static class LayoutInflaterLargeOp extends Op {
- Context mContext;
-
- LayoutInflaterLargeOp() {
- super("LayoutInflaterLarge", "Inflate large layout resource");
- }
-
- void onInit(Context context, boolean foreground) {
- mContext = context;
- }
-
- boolean onRun() {
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
- LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- inf.inflate(R.layout.large_layout, null);
- return true;
- }
- }
-
- static class LayoutInflaterViewOp extends Op {
- Context mContext;
-
- LayoutInflaterViewOp() {
- super("LayoutInflaterView", "Inflate layout with 50 View objects");
- }
-
- void onInit(Context context, boolean foreground) {
- mContext = context;
- }
-
- boolean onRun() {
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
- LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- inf.inflate(R.layout.view_layout, null);
- return true;
- }
- }
-
- static class LayoutInflaterButtonOp extends Op {
- Context mContext;
-
- LayoutInflaterButtonOp() {
- super("LayoutInflaterButton", "Inflate layout with 50 Button objects");
- }
-
- void onInit(Context context, boolean foreground) {
- mContext = context;
- }
-
- boolean onRun() {
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
- LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- inf.inflate(R.layout.button_layout, null);
- return true;
- }
- }
-
- static class LayoutInflaterImageButtonOp extends Op {
- Context mContext;
-
- LayoutInflaterImageButtonOp() {
- super("LayoutInflaterImageButton", "Inflate layout with 50 ImageButton objects");
- }
-
- void onInit(Context context, boolean foreground) {
- mContext = context;
- }
-
- boolean onRun() {
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
- LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- inf.inflate(R.layout.image_button_layout, null);
- return true;
- }
- }
-
- static class CreateBitmapOp extends Op {
- Context mContext;
-
- CreateBitmapOp() {
- super("CreateBitmap", "Create a Bitmap");
- }
-
- void onInit(Context context, boolean foreground) {
- mContext = context;
- }
-
- boolean onRun() {
- BitmapFactory.Options opts = new BitmapFactory.Options();
- opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
- Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888);
- return true;
- }
- }
-
- static class CreateRecycleBitmapOp extends Op {
- Context mContext;
-
- CreateRecycleBitmapOp() {
- super("CreateRecycleBitmap", "Create and recycle a Bitmap");
- }
-
- void onInit(Context context, boolean foreground) {
- mContext = context;
- }
-
- boolean onRun() {
- BitmapFactory.Options opts = new BitmapFactory.Options();
- opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
- Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888);
- bm.recycle();
- return true;
- }
- }
-
- static class LoadSmallBitmapOp extends Op {
- Context mContext;
-
- LoadSmallBitmapOp() {
- super("LoadSmallBitmap", "Load small raw bitmap");
- }
-
- void onInit(Context context, boolean foreground) {
- mContext = context;
- }
-
- boolean onRun() {
- BitmapFactory.Options opts = new BitmapFactory.Options();
- opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
- Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
- R.drawable.stat_sample, opts);
- return true;
- }
- }
-
- static class LoadRecycleSmallBitmapOp extends Op {
- Context mContext;
-
- LoadRecycleSmallBitmapOp() {
- super("LoadRecycleSmallBitmap", "Load and recycle small raw bitmap");
- }
-
- void onInit(Context context, boolean foreground) {
- mContext = context;
- }
-
- boolean onRun() {
- BitmapFactory.Options opts = new BitmapFactory.Options();
- opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
- Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
- R.drawable.stat_sample, opts);
- bm.recycle();
- return true;
- }
- }
-
- static class LoadLargeBitmapOp extends Op {
- Context mContext;
-
- LoadLargeBitmapOp() {
- super("LoadLargeBitmap", "Load large raw bitmap");
- }
-
- void onInit(Context context, boolean foreground) {
- mContext = context;
- }
-
- boolean onRun() {
- BitmapFactory.Options opts = new BitmapFactory.Options();
- opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
- Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
- R.drawable.wallpaper_goldengate, opts);
- return true;
- }
- }
-
- static class LoadRecycleLargeBitmapOp extends Op {
- Context mContext;
-
- LoadRecycleLargeBitmapOp() {
- super("LoadRecycleLargeBitmap", "Load and recycle large raw bitmap");
- }
-
- void onInit(Context context, boolean foreground) {
- mContext = context;
- }
-
- boolean onRun() {
- BitmapFactory.Options opts = new BitmapFactory.Options();
- opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
- Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
- R.drawable.wallpaper_goldengate, opts);
- bm.recycle();
- return true;
- }
- }
-
- static class LoadSmallScaledBitmapOp extends Op {
- Context mContext;
-
- LoadSmallScaledBitmapOp() {
- super("LoadSmallScaledBitmap", "Load small raw bitmap that is scaled for density");
- }
-
- void onInit(Context context, boolean foreground) {
- mContext = context;
- }
-
- boolean onRun() {
- BitmapFactory.Options opts = new BitmapFactory.Options();
- opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
- Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
- R.drawable.stat_sample_scale, opts);
- return true;
- }
- }
-
- static class LoadLargeScaledBitmapOp extends Op {
- Context mContext;
-
- LoadLargeScaledBitmapOp() {
- super("LoadLargeScaledBitmap", "Load large raw bitmap that is scaled for density");
- }
-
- void onInit(Context context, boolean foreground) {
- mContext = context;
- }
-
- boolean onRun() {
- BitmapFactory.Options opts = new BitmapFactory.Options();
- opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
- Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
- R.drawable.wallpaper_goldengate_scale, opts);
- return true;
- }
- }
-
- static class CreateFileOp extends Op {
- File mFile;
-
- CreateFileOp() {
- super("CreateFile", "Create and delete a file");
- }
-
- void onInit(Context context, boolean foreground) {
- mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
- mFile.delete();
- }
-
- boolean onRun() {
- try {
- mFile.createNewFile();
- } catch (IOException e) {
- Log.w(TAG, "Failure creating " + mFile, e);
- }
- mFile.delete();
- return true;
- }
- }
-
- static class CreateWriteFileOp extends Op {
- File mFile;
-
- CreateWriteFileOp() {
- super("CreateWriteFile", "Create, write, and delete a file");
- }
-
- void onInit(Context context, boolean foreground) {
- mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
- mFile.delete();
- }
-
- boolean onRun() {
- try {
- FileOutputStream fos = new FileOutputStream(mFile);
- fos.write(1);
- fos.close();
- } catch (IOException e) {
- Log.w(TAG, "Failure creating " + mFile, e);
- }
- mFile.delete();
- return true;
- }
- }
-
- static class CreateWriteSyncFileOp extends Op {
- File mFile;
-
- CreateWriteSyncFileOp() {
- super("CreateWriteSyncFile", "Create, write, sync, and delete a file");
- }
-
- void onInit(Context context, boolean foreground) {
- mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
- mFile.delete();
- }
-
- boolean onRun() {
- try {
- FileOutputStream fos = new FileOutputStream(mFile);
- fos.write(1);
- fos.flush();
- FileUtils.sync(fos);
- fos.close();
- } catch (IOException e) {
- Log.w(TAG, "Failure creating " + mFile, e);
- }
- mFile.delete();
- return true;
- }
- }
-
- static class WriteFileOp extends Op {
- File mFile;
- RandomAccessFile mRAF;
- byte[] mBuffer;
-
- WriteFileOp() {
- super("WriteFile", "Truncate and write a 64k file");
- }
-
- void onInit(Context context, boolean foreground) {
- mBuffer = new byte[1024*64];
- for (int i=0; i<mBuffer.length; i++) {
- mBuffer[i] = (byte)i;
- }
- mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
- mFile.delete();
- try {
- mRAF = new RandomAccessFile(mFile, "rw");
- } catch (FileNotFoundException e) {
- Log.w(TAG, "Failure creating " + mFile, e);
- }
- }
-
- boolean onRun() {
- try {
- mRAF.seek(0);
- mRAF.setLength(0);
- mRAF.write(mBuffer);
- } catch (IOException e) {
- Log.w(TAG, "Failure writing " + mFile, e);
- }
- return true;
- }
-
- void onTerm(Context context) {
- try {
- mRAF.close();
- } catch (IOException e) {
- Log.w(TAG, "Failure closing " + mFile, e);
- }
- mFile.delete();
- }
- }
-
- static class ReadFileOp extends Op {
- File mFile;
- RandomAccessFile mRAF;
- byte[] mBuffer;
-
- ReadFileOp() {
- super("ReadFile", "Seek and read a 64k file");
- }
-
- void onInit(Context context, boolean foreground) {
- mBuffer = new byte[1024*64];
- for (int i=0; i<mBuffer.length; i++) {
- mBuffer[i] = (byte)i;
- }
- mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
- mFile.delete();
- try {
- mRAF = new RandomAccessFile(mFile, "rw");
- mRAF.seek(0);
- mRAF.setLength(0);
- mRAF.write(mBuffer);
- } catch (IOException e) {
- Log.w(TAG, "Failure creating " + mFile, e);
- }
- }
-
- boolean onRun() {
- try {
- mRAF.seek(0);
- mRAF.read(mBuffer);
- } catch (IOException e) {
- Log.w(TAG, "Failure reading " + mFile, e);
- }
- return true;
- }
-
- void onTerm(Context context) {
- try {
- mRAF.close();
- } catch (IOException e) {
- Log.w(TAG, "Failure closing " + mFile, e);
- }
- mFile.delete();
- }
- }
}
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/LocalTestService.java b/tests/FrameworkPerf/src/com/android/frameworkperf/LocalTestService.java
new file mode 100644
index 0000000..09c6be8
--- /dev/null
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/LocalTestService.java
@@ -0,0 +1,6 @@
+package com.android.frameworkperf;
+
+public class LocalTestService extends TestService {
+ void terminate() {
+ }
+}
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/RunResult.java b/tests/FrameworkPerf/src/com/android/frameworkperf/RunResult.java
new file mode 100644
index 0000000..d14e434
--- /dev/null
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/RunResult.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 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.frameworkperf;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class RunResult implements Parcelable {
+ final String name;
+ final String fgLongName;
+ final String bgLongName;
+ final long fgTime;
+ final long fgOps;
+ final long bgTime;
+ final long bgOps;
+
+ RunResult(TestService.TestRunner op) {
+ name = op.getName();
+ fgLongName = op.getForegroundLongName();
+ bgLongName = op.getBackgroundLongName();
+ fgTime = op.getForegroundTime();
+ fgOps = op.getForegroundOps();
+ bgTime = op.getBackgroundTime();
+ bgOps = op.getBackgroundOps();
+ }
+
+ RunResult(Parcel source) {
+ name = source.readString();
+ fgLongName = source.readString();
+ bgLongName = source.readString();
+ fgTime = source.readLong();
+ fgOps = source.readLong();
+ bgTime = source.readLong();
+ bgOps = source.readLong();
+ }
+
+ float getFgMsPerOp() {
+ return fgOps != 0 ? (fgTime / (float)fgOps) : 0;
+ }
+
+ float getBgMsPerOp() {
+ return bgOps != 0 ? (bgTime / (float)bgOps) : 0;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(name);
+ dest.writeString(fgLongName);
+ dest.writeString(bgLongName);
+ dest.writeLong(fgTime);
+ dest.writeLong(fgOps);
+ dest.writeLong(bgTime);
+ dest.writeLong(bgOps);
+ }
+
+ public static final Parcelable.Creator<RunResult> CREATOR
+ = new Parcelable.Creator<RunResult>() {
+ public RunResult createFromParcel(Parcel in) {
+ return new RunResult(in);
+ }
+
+ public RunResult[] newArray(int size) {
+ return new RunResult[size];
+ }
+ };
+}
\ No newline at end of file
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/TestArgs.java b/tests/FrameworkPerf/src/com/android/frameworkperf/TestArgs.java
new file mode 100644
index 0000000..f2f7c56
--- /dev/null
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/TestArgs.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 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.frameworkperf;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class TestArgs implements Parcelable {
+ long maxTime;
+ int combOp = -1;
+ int fgOp = -1;
+ int bgOp = -1;
+
+ public TestArgs() {
+ }
+
+ public TestArgs(Parcel source) {
+ maxTime = source.readLong();
+ combOp = source.readInt();
+ fgOp = source.readInt();
+ bgOp = source.readInt();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeLong(maxTime);
+ dest.writeInt(combOp);
+ dest.writeInt(fgOp);
+ dest.writeInt(bgOp);
+ }
+
+ public static final Parcelable.Creator<TestArgs> CREATOR
+ = new Parcelable.Creator<TestArgs>() {
+ public TestArgs createFromParcel(Parcel in) {
+ return new TestArgs(in);
+ }
+
+ public TestArgs[] newArray(int size) {
+ return new TestArgs[size];
+ }
+ };
+}
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java b/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java
new file mode 100644
index 0000000..3d939bd
--- /dev/null
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java
@@ -0,0 +1,1054 @@
+/*
+ * Copyright (C) 2011 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.frameworkperf;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.os.FileUtils;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.Xml;
+import android.view.LayoutInflater;
+
+public class TestService extends Service {
+ static final String TAG = "Perf";
+
+ final static Op[] mOpPairs = new Op[] {
+ new MethodCallOp(), new NoOp(),
+ new MethodCallOp(), new CpuOp(),
+ new MethodCallOp(), new SchedulerOp(),
+ new MethodCallOp(), new GcOp(),
+ new MethodCallOp(), new CreateFileOp(),
+ new MethodCallOp(), new CreateWriteFileOp(),
+ new MethodCallOp(), new CreateWriteSyncFileOp(),
+ new MethodCallOp(), new WriteFileOp(),
+ new MethodCallOp(), new ReadFileOp(),
+ new SchedulerOp(), new SchedulerOp(),
+ new GcOp(), new NoOp(),
+ new IpcOp(), new NoOp(),
+ new IpcOp(), new CpuOp(),
+ new IpcOp(), new SchedulerOp(),
+ new IpcOp(), new GcOp(),
+ new IpcOp(), new CreateFileOp(),
+ new IpcOp(), new CreateWriteFileOp(),
+ new IpcOp(), new CreateWriteSyncFileOp(),
+ new IpcOp(), new WriteFileOp(),
+ new IpcOp(), new ReadFileOp(),
+ new CreateFileOp(), new NoOp(),
+ new CreateWriteFileOp(), new NoOp(),
+ new CreateWriteSyncFileOp(), new NoOp(),
+ new WriteFileOp(), new NoOp(),
+ new ReadFileOp(), new NoOp(),
+ new WriteFileOp(), new CreateWriteFileOp(),
+ new ReadFileOp(), new CreateWriteFileOp(),
+ new WriteFileOp(), new CreateWriteSyncFileOp(),
+ new ReadFileOp(), new CreateWriteSyncFileOp(),
+ new WriteFileOp(), new WriteFileOp(),
+ new WriteFileOp(), new ReadFileOp(),
+ new ReadFileOp(), new WriteFileOp(),
+ new ReadFileOp(), new ReadFileOp(),
+ new OpenXmlResOp(), new NoOp(),
+ new ReadXmlAttrsOp(), new NoOp(),
+ new ParseXmlResOp(), new NoOp(),
+ new ParseLargeXmlResOp(), new NoOp(),
+ new LayoutInflaterOp(), new NoOp(),
+ new LayoutInflaterLargeOp(), new NoOp(),
+ new LayoutInflaterViewOp(), new NoOp(),
+ new LayoutInflaterButtonOp(), new NoOp(),
+ new LayoutInflaterImageButtonOp(), new NoOp(),
+ new CreateBitmapOp(), new NoOp(),
+ new CreateRecycleBitmapOp(), new NoOp(),
+ new LoadSmallBitmapOp(), new NoOp(),
+ new LoadRecycleSmallBitmapOp(), new NoOp(),
+ new LoadLargeBitmapOp(), new NoOp(),
+ new LoadRecycleLargeBitmapOp(), new NoOp(),
+ new LoadSmallScaledBitmapOp(), new NoOp(),
+ new LoadLargeScaledBitmapOp(), new NoOp(),
+ };
+
+ final static Op[] mAvailOps = new Op[] {
+ null,
+ new NoOp(),
+ new CpuOp(),
+ new SchedulerOp(),
+ new MethodCallOp(),
+ new IpcOp(),
+ new CreateFileOp(),
+ new CreateWriteFileOp(),
+ new CreateWriteSyncFileOp(),
+ new WriteFileOp(),
+ new ReadFileOp(),
+ new OpenXmlResOp(),
+ new ReadXmlAttrsOp(),
+ new ParseXmlResOp(),
+ new ParseLargeXmlResOp(),
+ new LayoutInflaterOp(),
+ new LayoutInflaterLargeOp(),
+ new LayoutInflaterViewOp(),
+ new LayoutInflaterButtonOp(),
+ new LayoutInflaterImageButtonOp(),
+ new CreateBitmapOp(),
+ new CreateRecycleBitmapOp(),
+ new LoadSmallBitmapOp(),
+ new LoadRecycleSmallBitmapOp(),
+ new LoadLargeBitmapOp(),
+ new LoadRecycleLargeBitmapOp(),
+ new LoadSmallScaledBitmapOp(),
+ new LoadLargeScaledBitmapOp(),
+ };
+
+ static final int CMD_START_TEST = 1;
+ static final int CMD_TERMINATE = 2;
+
+ static final int MSG_REALLY_START = 1000;
+ static final int MSG_REALLY_TERMINATE = 1001;
+
+ static final int RES_TEST_FINISHED = 1;
+ static final int RES_TERMINATED = 2;
+
+ final Handler mHandler = new Handler() {
+ @Override public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case CMD_START_TEST: {
+ // Give a little time for things to settle down.
+ Message newMsg = Message.obtain(null, MSG_REALLY_START);
+ newMsg.obj = msg.obj;
+ newMsg.replyTo = msg.replyTo;
+ sendMessageDelayed(newMsg, 500);
+ } break;
+ case MSG_REALLY_START: {
+ Bundle bundle = (Bundle)msg.obj;
+ bundle.setClassLoader(getClassLoader());
+ final TestArgs args = (TestArgs)bundle.getParcelable("args");
+ final Messenger replyTo = msg.replyTo;
+ mRunner.run(this, args, new Runnable() {
+ @Override public void run() {
+ if (replyTo != null) {
+ Message msg = Message.obtain(null, RES_TEST_FINISHED);
+ Bundle bundle = new Bundle();
+ bundle.putParcelable("res", new RunResult(mRunner));
+ msg.obj = bundle;
+ try {
+ replyTo.send(msg);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ });
+ } break;
+ case CMD_TERMINATE: {
+ // Give a little time for things to settle down.
+ Message newMsg = Message.obtain(null, MSG_REALLY_TERMINATE);
+ newMsg.obj = msg.obj;
+ newMsg.replyTo = msg.replyTo;
+ sendMessageDelayed(newMsg, 50);
+ } break;
+ case MSG_REALLY_TERMINATE: {
+ if (msg.replyTo != null) {
+ Message reply = Message.obtain(null, RES_TERMINATED);
+ try {
+ msg.replyTo.send(reply);
+ } catch (RemoteException e) {
+ }
+ }
+ terminate();
+ } break;
+ }
+ }
+ };
+
+ final TestRunner mRunner = new TestRunner();
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return (new Messenger(mHandler)).getBinder();
+ }
+
+ void terminate() {
+ Runtime.getRuntime().exit(0);
+ }
+
+ enum BackgroundMode {
+ NOTHING,
+ CPU,
+ SCHEDULER
+ };
+
+ public class TestRunner {
+ Handler mHandler;
+ long mMaxRunTime;
+ Op mForegroundOp;
+ Op mBackgroundOp;
+ Runnable mDoneCallback;
+
+ RunnerThread mBackgroundThread;
+ RunnerThread mForegroundThread;
+ long mStartTime;
+
+ boolean mBackgroundRunning;
+ boolean mForegroundRunning;
+
+ long mBackgroundEndTime;
+ long mBackgroundOps;
+ long mForegroundEndTime;
+ long mForegroundOps;
+
+ public TestRunner() {
+ }
+
+ public String getForegroundName() {
+ return mForegroundOp.getName();
+ }
+
+ public String getBackgroundName() {
+ return mBackgroundOp.getName();
+ }
+
+ public String getName() {
+ String fgName = mForegroundOp.getName();
+ String bgName = mBackgroundOp.getName();
+ StringBuilder res = new StringBuilder();
+ if (fgName != null) {
+ res.append(fgName);
+ res.append("Fg");
+ }
+ if (bgName != null) {
+ res.append(bgName);
+ res.append("Bg");
+ }
+ return res.toString();
+ }
+
+ public String getForegroundLongName() {
+ return mForegroundOp.getLongName();
+ }
+
+ public String getBackgroundLongName() {
+ return mBackgroundOp.getLongName();
+ }
+
+ public void run(Handler handler, TestArgs args, Runnable doneCallback) {
+ mHandler = handler;
+ mMaxRunTime = args.maxTime;
+ if (args.combOp >= 0) {
+ mForegroundOp = mOpPairs[args.combOp];
+ mBackgroundOp = mOpPairs[args.combOp+1];
+ } else {
+ mForegroundOp = mAvailOps[args.fgOp];
+ mBackgroundOp = mAvailOps[args.bgOp];
+ }
+ mDoneCallback = doneCallback;
+ mBackgroundThread = new RunnerThread("background", new Runnable() {
+ @Override public void run() {
+ boolean running;
+ int ops = 0;
+ do {
+ running = mBackgroundOp.onRun();
+ ops++;
+ } while (evalRepeat(running, true) && running);
+ mBackgroundEndTime = SystemClock.uptimeMillis();
+ mBackgroundOps = ops * mBackgroundOp.getOpsPerRun();
+ threadFinished(false);
+ }
+ }, Process.THREAD_PRIORITY_BACKGROUND);
+ mForegroundThread = new RunnerThread("background", new Runnable() {
+ @Override public void run() {
+ boolean running;
+ int ops = 0;
+ do {
+ running = mForegroundOp.onRun();
+ ops++;
+ } while (evalRepeat(true, running) && running);
+ mForegroundEndTime = SystemClock.uptimeMillis();
+ mForegroundOps = ops * mForegroundOp.getOpsPerRun();
+ threadFinished(true);
+ }
+ }, Process.THREAD_PRIORITY_FOREGROUND);
+
+ mForegroundOp.onInit(TestService.this, true);
+ mBackgroundOp.onInit(TestService.this, false);
+
+ synchronized (this) {
+ mStartTime = SystemClock.uptimeMillis();
+ mBackgroundRunning = true;
+ mForegroundRunning = true;
+ }
+
+ mBackgroundThread.start();
+ mForegroundThread.start();
+ }
+
+ public long getForegroundTime() {
+ return mForegroundEndTime-mStartTime;
+ }
+
+ public long getForegroundOps() {
+ return mForegroundOps;
+ }
+
+ public long getBackgroundTime() {
+ return mBackgroundEndTime-mStartTime;
+ }
+
+ public long getBackgroundOps() {
+ return mBackgroundOps;
+ }
+
+ private boolean evalRepeat(boolean bgRunning, boolean fgRunning) {
+ synchronized (this) {
+ if (!bgRunning) {
+ mBackgroundRunning = false;
+ }
+ if (!fgRunning) {
+ mForegroundRunning = false;
+ }
+ if (!mBackgroundRunning && !mForegroundRunning) {
+ return false;
+ }
+ long now = SystemClock.uptimeMillis();
+ if (now > (mStartTime+mMaxRunTime)) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ private void threadFinished(boolean foreground) {
+ synchronized (this) {
+ if (foreground) {
+ mForegroundRunning = false;
+ } else {
+ mBackgroundRunning = false;
+ }
+ if (!mBackgroundRunning && !mForegroundRunning) {
+ mHandler.post(new Runnable() {
+ @Override public void run() {
+ mForegroundOp.onTerm(TestService.this);
+ mBackgroundOp.onTerm(TestService.this);
+ if (mDoneCallback != null) {
+ mDoneCallback.run();
+ }
+ }
+ });
+ }
+ }
+ }
+ }
+
+ class RunnerThread extends Thread {
+ private final Runnable mOp;
+ private final int mPriority;
+
+ RunnerThread(String name, Runnable op, int priority) {
+ super(name);
+ mOp = op;
+ mPriority = priority;
+ }
+
+ public void run() {
+ Process.setThreadPriority(mPriority);
+ mOp.run();
+ }
+ }
+
+ static public abstract class Op {
+ final String mName;
+ final String mLongName;
+
+ public Op(String name, String longName) {
+ mName = name;
+ mLongName = longName;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public String getLongName() {
+ return mLongName;
+ }
+
+ void onInit(Context context, boolean foreground) {
+ }
+
+ abstract boolean onRun();
+
+ void onTerm(Context context) {
+ }
+
+ int getOpsPerRun() {
+ return 1;
+ }
+ }
+
+ static class NoOp extends Op {
+ NoOp() {
+ super(null, "Nothing");
+ }
+
+ boolean onRun() {
+ return false;
+ }
+
+ int getOpsPerRun() {
+ return 0;
+ }
+ }
+
+ static class CpuOp extends Op {
+ CpuOp() {
+ super("CPU", "Consume CPU");
+ }
+
+ boolean onRun() {
+ return true;
+ }
+ }
+
+ static class SchedulerOp extends Op {
+ SchedulerOp() {
+ super("Sched", "Change scheduler group");
+ }
+
+ boolean onRun() {
+ Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
+ Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+ return true;
+ }
+ }
+
+ static class GcOp extends Op {
+ GcOp() {
+ super("Gc", "Run garbage collector");
+ }
+
+ boolean onRun() {
+ byte[] stuff = new byte[1024*1024];
+ return true;
+ }
+ }
+
+ static class MethodCallOp extends Op {
+ MethodCallOp() {
+ super("MethodCall", "Method call");
+ }
+
+ boolean onRun() {
+ final int N = getOpsPerRun();
+ for (int i=0; i<N; i++) {
+ someFunc(i);
+ }
+ return true;
+ }
+
+ int someFunc(int foo) {
+ return 0;
+ }
+
+ int getOpsPerRun() {
+ return 500;
+ }
+ }
+
+ static class IpcOp extends Op {
+ PackageManager mPm;
+ String mProcessName;
+
+ IpcOp() {
+ super("Ipc", "IPC to system process");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mPm = context.getPackageManager();
+ mProcessName = context.getApplicationInfo().processName;
+ }
+
+ boolean onRun() {
+ final int N = getOpsPerRun();
+ for (int i=0; i<N; i++) {
+ mPm.queryContentProviders(mProcessName, Process.myUid(), 0);
+ }
+ return true;
+ }
+
+ int getOpsPerRun() {
+ return 100;
+ }
+ }
+
+ static class OpenXmlResOp extends Op {
+ Context mContext;
+
+ OpenXmlResOp() {
+ super("OpenXmlRes", "Open (and close) an XML resource");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ XmlResourceParser parser = mContext.getResources().getLayout(R.xml.simple);
+ parser.close();
+ return true;
+ }
+ }
+
+ static class ReadXmlAttrsOp extends Op {
+ Context mContext;
+ XmlResourceParser mParser;
+ AttributeSet mAttrs;
+
+ ReadXmlAttrsOp() {
+ super("ReadXmlAttrs", "Read attributes from an XML tag");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mContext = context;
+ mParser = mContext.getResources().getLayout(R.xml.simple);
+ mAttrs = Xml.asAttributeSet(mParser);
+
+ int eventType;
+ try {
+ // Find the first <item> tag.
+ eventType = mParser.getEventType();
+ String tagName;
+ do {
+ if (eventType == XmlPullParser.START_TAG) {
+ tagName = mParser.getName();
+ if (tagName.equals("item")) {
+ break;
+ }
+ }
+ eventType = mParser.next();
+ } while (eventType != XmlPullParser.END_DOCUMENT);
+ } catch (XmlPullParserException e) {
+ throw new RuntimeException("I died", e);
+ } catch (IOException e) {
+ throw new RuntimeException("I died", e);
+ }
+ }
+
+ void onTerm(Context context) {
+ mParser.close();
+ }
+
+ boolean onRun() {
+ TypedArray a = mContext.obtainStyledAttributes(mAttrs,
+ com.android.internal.R.styleable.MenuItem);
+ a.recycle();
+ return true;
+ }
+ }
+
+ static class ParseXmlResOp extends Op {
+ Context mContext;
+
+ ParseXmlResOp() {
+ super("ParseXmlRes", "Parse compiled XML resource");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ SimpleInflater inf = new SimpleInflater(mContext);
+ inf.inflate(R.xml.simple);
+ return true;
+ }
+ }
+
+ static class ParseLargeXmlResOp extends Op {
+ Context mContext;
+
+ ParseLargeXmlResOp() {
+ super("ParseLargeXmlRes", "Parse large XML resource");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ SimpleInflater inf = new SimpleInflater(mContext);
+ inf.inflate(R.xml.simple_large);
+ return true;
+ }
+ }
+
+ static class LayoutInflaterOp extends Op {
+ Context mContext;
+
+ LayoutInflaterOp() {
+ super("LayoutInflater", "Inflate layout resource");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ inf.inflate(R.layout.small_layout, null);
+ return true;
+ }
+ }
+
+ static class LayoutInflaterLargeOp extends Op {
+ Context mContext;
+
+ LayoutInflaterLargeOp() {
+ super("LayoutInflaterLarge", "Inflate large layout resource");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ inf.inflate(R.layout.large_layout, null);
+ return true;
+ }
+ }
+
+ static class LayoutInflaterViewOp extends Op {
+ Context mContext;
+
+ LayoutInflaterViewOp() {
+ super("LayoutInflaterView", "Inflate layout with 50 View objects");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ inf.inflate(R.layout.view_layout, null);
+ return true;
+ }
+ }
+
+ static class LayoutInflaterButtonOp extends Op {
+ Context mContext;
+
+ LayoutInflaterButtonOp() {
+ super("LayoutInflaterButton", "Inflate layout with 50 Button objects");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ inf.inflate(R.layout.button_layout, null);
+ return true;
+ }
+ }
+
+ static class LayoutInflaterImageButtonOp extends Op {
+ Context mContext;
+
+ LayoutInflaterImageButtonOp() {
+ super("LayoutInflaterImageButton", "Inflate layout with 50 ImageButton objects");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ inf.inflate(R.layout.image_button_layout, null);
+ return true;
+ }
+ }
+
+ static class CreateBitmapOp extends Op {
+ Context mContext;
+
+ CreateBitmapOp() {
+ super("CreateBitmap", "Create a Bitmap");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ BitmapFactory.Options opts = new BitmapFactory.Options();
+ opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+ Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888);
+ return true;
+ }
+ }
+
+ static class CreateRecycleBitmapOp extends Op {
+ Context mContext;
+
+ CreateRecycleBitmapOp() {
+ super("CreateRecycleBitmap", "Create and recycle a Bitmap");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ BitmapFactory.Options opts = new BitmapFactory.Options();
+ opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+ Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888);
+ bm.recycle();
+ return true;
+ }
+ }
+
+ static class LoadSmallBitmapOp extends Op {
+ Context mContext;
+
+ LoadSmallBitmapOp() {
+ super("LoadSmallBitmap", "Load small raw bitmap");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ BitmapFactory.Options opts = new BitmapFactory.Options();
+ opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+ Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
+ R.drawable.stat_sample, opts);
+ return true;
+ }
+ }
+
+ static class LoadRecycleSmallBitmapOp extends Op {
+ Context mContext;
+
+ LoadRecycleSmallBitmapOp() {
+ super("LoadRecycleSmallBitmap", "Load and recycle small raw bitmap");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ BitmapFactory.Options opts = new BitmapFactory.Options();
+ opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+ Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
+ R.drawable.stat_sample, opts);
+ bm.recycle();
+ return true;
+ }
+ }
+
+ static class LoadLargeBitmapOp extends Op {
+ Context mContext;
+
+ LoadLargeBitmapOp() {
+ super("LoadLargeBitmap", "Load large raw bitmap");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ BitmapFactory.Options opts = new BitmapFactory.Options();
+ opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+ Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
+ R.drawable.wallpaper_goldengate, opts);
+ return true;
+ }
+ }
+
+ static class LoadRecycleLargeBitmapOp extends Op {
+ Context mContext;
+
+ LoadRecycleLargeBitmapOp() {
+ super("LoadRecycleLargeBitmap", "Load and recycle large raw bitmap");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ BitmapFactory.Options opts = new BitmapFactory.Options();
+ opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+ Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
+ R.drawable.wallpaper_goldengate, opts);
+ bm.recycle();
+ return true;
+ }
+ }
+
+ static class LoadSmallScaledBitmapOp extends Op {
+ Context mContext;
+
+ LoadSmallScaledBitmapOp() {
+ super("LoadSmallScaledBitmap", "Load small raw bitmap that is scaled for density");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ BitmapFactory.Options opts = new BitmapFactory.Options();
+ opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+ Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
+ R.drawable.stat_sample_scale, opts);
+ return true;
+ }
+ }
+
+ static class LoadLargeScaledBitmapOp extends Op {
+ Context mContext;
+
+ LoadLargeScaledBitmapOp() {
+ super("LoadLargeScaledBitmap", "Load large raw bitmap that is scaled for density");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ BitmapFactory.Options opts = new BitmapFactory.Options();
+ opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+ Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
+ R.drawable.wallpaper_goldengate_scale, opts);
+ return true;
+ }
+ }
+
+ static class CreateFileOp extends Op {
+ File mFile;
+
+ CreateFileOp() {
+ super("CreateFile", "Create and delete a file");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
+ mFile.delete();
+ }
+
+ boolean onRun() {
+ try {
+ mFile.createNewFile();
+ } catch (IOException e) {
+ Log.w(TAG, "Failure creating " + mFile, e);
+ }
+ mFile.delete();
+ return true;
+ }
+ }
+
+ static class CreateWriteFileOp extends Op {
+ File mFile;
+
+ CreateWriteFileOp() {
+ super("CreateWriteFile", "Create, write, and delete a file");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
+ mFile.delete();
+ }
+
+ boolean onRun() {
+ try {
+ FileOutputStream fos = new FileOutputStream(mFile);
+ fos.write(1);
+ fos.close();
+ } catch (IOException e) {
+ Log.w(TAG, "Failure creating " + mFile, e);
+ }
+ mFile.delete();
+ return true;
+ }
+ }
+
+ static class CreateWriteSyncFileOp extends Op {
+ File mFile;
+
+ CreateWriteSyncFileOp() {
+ super("CreateWriteSyncFile", "Create, write, sync, and delete a file");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
+ mFile.delete();
+ }
+
+ boolean onRun() {
+ try {
+ FileOutputStream fos = new FileOutputStream(mFile);
+ fos.write(1);
+ fos.flush();
+ FileUtils.sync(fos);
+ fos.close();
+ } catch (IOException e) {
+ Log.w(TAG, "Failure creating " + mFile, e);
+ }
+ mFile.delete();
+ return true;
+ }
+ }
+
+ static class WriteFileOp extends Op {
+ File mFile;
+ RandomAccessFile mRAF;
+ byte[] mBuffer;
+
+ WriteFileOp() {
+ super("WriteFile", "Truncate and write a 64k file");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mBuffer = new byte[1024*64];
+ for (int i=0; i<mBuffer.length; i++) {
+ mBuffer[i] = (byte)i;
+ }
+ mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
+ mFile.delete();
+ try {
+ mRAF = new RandomAccessFile(mFile, "rw");
+ } catch (FileNotFoundException e) {
+ Log.w(TAG, "Failure creating " + mFile, e);
+ }
+ }
+
+ boolean onRun() {
+ try {
+ mRAF.seek(0);
+ mRAF.setLength(0);
+ mRAF.write(mBuffer);
+ } catch (IOException e) {
+ Log.w(TAG, "Failure writing " + mFile, e);
+ }
+ return true;
+ }
+
+ void onTerm(Context context) {
+ try {
+ mRAF.close();
+ } catch (IOException e) {
+ Log.w(TAG, "Failure closing " + mFile, e);
+ }
+ mFile.delete();
+ }
+ }
+
+ static class ReadFileOp extends Op {
+ File mFile;
+ RandomAccessFile mRAF;
+ byte[] mBuffer;
+
+ ReadFileOp() {
+ super("ReadFile", "Seek and read a 64k file");
+ }
+
+ void onInit(Context context, boolean foreground) {
+ mBuffer = new byte[1024*64];
+ for (int i=0; i<mBuffer.length; i++) {
+ mBuffer[i] = (byte)i;
+ }
+ mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
+ mFile.delete();
+ try {
+ mRAF = new RandomAccessFile(mFile, "rw");
+ mRAF.seek(0);
+ mRAF.setLength(0);
+ mRAF.write(mBuffer);
+ } catch (IOException e) {
+ Log.w(TAG, "Failure creating " + mFile, e);
+ }
+ }
+
+ boolean onRun() {
+ try {
+ mRAF.seek(0);
+ mRAF.read(mBuffer);
+ } catch (IOException e) {
+ Log.w(TAG, "Failure reading " + mFile, e);
+ }
+ return true;
+ }
+
+ void onTerm(Context context) {
+ try {
+ mRAF.close();
+ } catch (IOException e) {
+ Log.w(TAG, "Failure closing " + mFile, e);
+ }
+ mFile.delete();
+ }
+ }
+}