diff options
399 files changed, 4096 insertions, 2070 deletions
diff --git a/api/current.txt b/api/current.txt index 4e41c29943a9..d83659f64922 100644 --- a/api/current.txt +++ b/api/current.txt @@ -3235,6 +3235,7 @@ package android.app { 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 @@ package android.app { 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 @@ package android.app { 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 @@ package android.appwidget { 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 @@ package android.bluetooth { 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 @@ package android.bluetooth { 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 @@ package android.bluetooth { 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 { @@ -8792,6 +8797,7 @@ package android.graphics { method public long getTimestamp(); method public void getTransformMatrix(float[]); method public void release(); + method public void setDefaultBufferSize(int, int); method public void setOnFrameAvailableListener(android.graphics.SurfaceTexture.OnFrameAvailableListener); method public void updateTexImage(); } @@ -16606,6 +16612,10 @@ package android.provider { field public static final java.lang.String PHOTO_FILE_ID = "data14"; } + public static final class ContactsContract.Contacts.StreamItems implements android.provider.ContactsContract.StreamItemsColumns { + field public static final java.lang.String CONTENT_DIRECTORY = "stream_items"; + } + protected static abstract interface ContactsContract.ContactsColumns { field public static final java.lang.String DISPLAY_NAME = "display_name"; field public static final java.lang.String HAS_PHONE_NUMBER = "has_phone_number"; @@ -16863,6 +16873,10 @@ package android.provider { field public static final java.lang.String DATA_ID = "data_id"; } + public static final class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns { + field public static final java.lang.String CONTENT_DIRECTORY = "stream_items"; + } + protected static abstract interface ContactsContract.RawContactsColumns { field public static final java.lang.String AGGREGATION_MODE = "aggregation_mode"; field public static final java.lang.String CONTACT_ID = "contact_id"; @@ -16926,6 +16940,56 @@ package android.provider { field public static final android.net.Uri PROFILE_CONTENT_URI; } + public static final class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns { + field public static final java.lang.String PHOTO = "photo"; + } + + protected static abstract interface ContactsContract.StreamItemPhotosColumns { + field public static final java.lang.String PHOTO_FILE_ID = "photo_file_id"; + field public static final java.lang.String PHOTO_URI = "photo_uri"; + field public static final java.lang.String SORT_INDEX = "sort_index"; + field public static final java.lang.String STREAM_ITEM_ID = "stream_item_id"; + field public static final java.lang.String SYNC1 = "stream_item_photo_sync1"; + field public static final java.lang.String SYNC2 = "stream_item_photo_sync2"; + field public static final java.lang.String SYNC3 = "stream_item_photo_sync3"; + field public static final java.lang.String SYNC4 = "stream_item_photo_sync4"; + } + + public static final class ContactsContract.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns { + field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item"; + field public static final android.net.Uri CONTENT_LIMIT_URI; + field public static final android.net.Uri CONTENT_PHOTO_URI; + field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item"; + field public static final android.net.Uri CONTENT_URI; + field public static final java.lang.String MAX_ITEMS = "max_items"; + } + + public static final class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns { + field public static final java.lang.String CONTENT_DIRECTORY = "photo"; + field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo"; + field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo"; + } + + protected static abstract interface ContactsContract.StreamItemsColumns { + field public static final java.lang.String ACCOUNT_NAME = "account_name"; + field public static final java.lang.String ACCOUNT_TYPE = "account_type"; + field public static final java.lang.String COMMENTS = "comments"; + field public static final java.lang.String CONTACT_ID = "contact_id"; + field public static final java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup"; + field public static final java.lang.String DATA_SET = "data_set"; + field public static final java.lang.String RAW_CONTACT_ID = "raw_contact_id"; + field public static final java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id"; + field public static final java.lang.String RES_ICON = "icon"; + field public static final java.lang.String RES_LABEL = "label"; + field public static final java.lang.String RES_PACKAGE = "res_package"; + field public static final java.lang.String SYNC1 = "stream_item_sync1"; + field public static final java.lang.String SYNC2 = "stream_item_sync2"; + field public static final java.lang.String SYNC3 = "stream_item_sync3"; + field public static final java.lang.String SYNC4 = "stream_item_sync4"; + field public static final java.lang.String TEXT = "text"; + field public static final java.lang.String TIMESTAMP = "timestamp"; + } + protected static abstract interface ContactsContract.SyncColumns implements android.provider.ContactsContract.BaseSyncColumns { field public static final java.lang.String ACCOUNT_NAME = "account_name"; field public static final java.lang.String ACCOUNT_TYPE = "account_type"; @@ -17363,6 +17427,7 @@ package android.provider { 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/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index 4f722893d453..7c03a2ff2020 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -109,6 +109,10 @@ public class Am { runStartService(); } else if (op.equals("force-stop")) { runForceStop(); + } else if (op.equals("kill")) { + runKill(); + } else if (op.equals("kill-all")) { + runKillAll(); } else if (op.equals("instrument")) { runInstrument(); } else if (op.equals("broadcast")) { @@ -484,6 +488,14 @@ public class Am { mAm.forceStopPackage(nextArgRequired()); } + private void runKill() throws Exception { + mAm.killBackgroundProcesses(nextArgRequired()); + } + + private void runKillAll() throws Exception { + mAm.killAllBackgroundProcesses(); + } + private void sendBroadcast() throws Exception { Intent intent = makeIntent(); IntentReceiver receiver = new IntentReceiver(); @@ -1179,6 +1191,8 @@ public class Am { " [--R COUNT] [-S] <INTENT>\n" + " am startservice <INTENT>\n" + " am force-stop <PACKAGE>\n" + + " am kill <PACKAGE>\n" + + " am kill-all\n" + " am broadcast <INTENT>\n" + " am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]\n" + " [--no-window-animation] <COMPONENT>\n" + @@ -1202,6 +1216,12 @@ public class Am { "\n" + "am force-stop: force stop everything associated with <PACKAGE>.\n" + "\n" + + "am kill: Kill all processes associated with <PACKAGE>. Only kills.\n" + + " processes that are safe to kill -- that is, will not impact the user\n" + + " experience.\n" + + "\n" + + "am kill-all: Kill all background processes.\n" + + "\n" + "am broadcast: send a broadcast Intent.\n" + "\n" + "am instrument: start an Instrumentation. Typically this target <COMPONENT>\n" + diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp index 2378345821c2..bd430d182d53 100644 --- a/cmds/stagefright/stream.cpp +++ b/cmds/stagefright/stream.cpp @@ -360,7 +360,7 @@ int main(int argc, char **argv) { 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/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index b4471f096ad5..7994d7cd3bfb 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -1092,6 +1092,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeNoException(); return true; } + + case KILL_ALL_BACKGROUND_PROCESSES_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + killAllBackgroundProcesses(); + reply.writeNoException(); + return true; + } case FORCE_STOP_PACKAGE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); @@ -2906,7 +2913,7 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); reply.recycle(); } - + public void killBackgroundProcesses(String packageName) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); @@ -2917,7 +2924,17 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); reply.recycle(); } - + + public void killAllBackgroundProcesses() throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + mRemote.transact(KILL_ALL_BACKGROUND_PROCESSES_TRANSACTION, data, reply, 0); + reply.readException(); + data.recycle(); + reply.recycle(); + } + public void forceStopPackage(String packageName) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 00fe953f70e3..a4714cab3542 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -3832,11 +3832,16 @@ public final class ActivityThread { * Initialize the default http proxy in this process for the reasons we set the time zone. */ IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); - IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); - try { - ProxyProperties proxyProperties = service.getProxy(); - Proxy.setHttpProxySystemProperty(proxyProperties); - } catch (RemoteException e) {} + if (b != null) { + // In pre-boot mode (doing initial launch to collect password), not + // all system is up. This includes the connectivity service, so don't + // crash if we can't get it. + IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); + try { + ProxyProperties proxyProperties = service.getProxy(); + Proxy.setHttpProxySystemProperty(proxyProperties); + } catch (RemoteException e) {} + } if (data.instrumentationName != null) { ContextImpl appContext = new ContextImpl(); diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index 9b01b7ffaf44..473a2d17ca39 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -458,6 +458,9 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene // 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 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene } /** - * 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 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene 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 c4ba778cfb73..a8c9cbab2095 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -382,6 +382,7 @@ final class FragmentManagerImpl extends FragmentManager { 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 @@ final class FragmentManagerImpl extends FragmentManager { boolean mStateSaved; boolean mDestroyed; String mNoTransactionsBecause; + boolean mHavePendingDeferredStart; // Temporary vars for state save and restore. Bundle mStateBundle = null; @@ -711,6 +713,11 @@ final class FragmentManagerImpl extends FragmentManager { 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 @@ final class FragmentManagerImpl extends FragmentManager { 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 @@ final class FragmentManagerImpl extends FragmentManager { synchronized (this) { if (mPendingActions == null || mPendingActions.size() == 0) { - return didSomething; + break; } numActions = mPendingActions.size(); @@ -1363,8 +1378,23 @@ final class FragmentManagerImpl extends FragmentManager { 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 @@ final class FragmentManagerImpl extends FragmentManager { 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/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 26813bf117df..5222d375a439 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -234,6 +234,7 @@ public interface IActivityManager extends IInterface { public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) throws RemoteException; public void killBackgroundProcesses(final String packageName) throws RemoteException; + public void killAllBackgroundProcesses() throws RemoteException; public void forceStopPackage(final String packageName) throws RemoteException; // Note: probably don't want to allow applications access to these. @@ -605,4 +606,5 @@ public interface IActivityManager extends IInterface { int GET_PROCESS_PSS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+136; int SHOW_BOOT_MESSAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+137; int DISMISS_KEYGUARD_ON_NEXT_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+138; + int KILL_ALL_BACKGROUND_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+139; } diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java index 761c7eb0863c..61a9dce98d57 100644 --- a/core/java/android/appwidget/AppWidgetHostView.java +++ b/core/java/android/appwidget/AppWidgetHostView.java @@ -26,6 +26,7 @@ import android.graphics.Bitmap; 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.AdapterView; 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 @@ public class AppWidgetHostView extends FrameLayout { } /** - * 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 @@ public class AppWidgetHostView extends FrameLayout { // 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 4cb822047918..03065218ee92 100644 --- a/core/java/android/bluetooth/BluetoothDevice.java +++ b/core/java/android/bluetooth/BluetoothDevice.java @@ -247,13 +247,12 @@ public final class BluetoothDevice implements Parcelable { * 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 @@ public final class BluetoothDevice implements Parcelable { * 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 @@ public final class BluetoothDevice implements Parcelable { 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 @@ public final class BluetoothDevice implements Parcelable { } /** - * 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. + * + * <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 + * @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/NetworkStats.java b/core/java/android/net/NetworkStats.java index 5c6ef1a9eac8..36056529c3a6 100644 --- a/core/java/android/net/NetworkStats.java +++ b/core/java/android/net/NetworkStats.java @@ -165,6 +165,17 @@ public class NetworkStats implements Parcelable { dest.writeLongArray(operations); } + @Override + public NetworkStats clone() { + final NetworkStats clone = new NetworkStats(elapsedRealtime, size); + NetworkStats.Entry entry = null; + for (int i = 0; i < size; i++) { + entry = getValues(i, entry); + clone.addValues(entry); + } + return clone; + } + // @VisibleForTesting public NetworkStats addIfaceValues( String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) { @@ -455,7 +466,7 @@ public class NetworkStats implements Parcelable { public NetworkStats subtract(NetworkStats value) throws NonMonotonicException { final long deltaRealtime = this.elapsedRealtime - value.elapsedRealtime; if (deltaRealtime < 0) { - throw new IllegalArgumentException("found non-monotonic realtime"); + throw new NonMonotonicException(this, value); } // result will have our rows, and elapsed time between snapshots @@ -575,7 +586,8 @@ public class NetworkStats implements Parcelable { pw.print("NetworkStats: elapsedRealtime="); pw.println(elapsedRealtime); for (int i = 0; i < size; i++) { pw.print(prefix); - pw.print(" iface="); pw.print(iface[i]); + pw.print(" ["); pw.print(i); pw.print("]"); + pw.print(" iface="); pw.print(iface[i]); pw.print(" uid="); pw.print(uid[i]); pw.print(" set="); pw.print(setToString(set[i])); pw.print(" tag="); pw.print(tagToString(tag[i])); @@ -638,6 +650,10 @@ public class NetworkStats implements Parcelable { public final int leftIndex; public final int rightIndex; + public NonMonotonicException(NetworkStats left, NetworkStats right) { + this(left, -1, right, -1); + } + public NonMonotonicException( NetworkStats left, int leftIndex, NetworkStats right, int rightIndex) { this.left = checkNotNull(left, "missing left"); diff --git a/core/java/android/net/wimax/WimaxManagerConstants.java b/core/java/android/net/wimax/WimaxManagerConstants.java new file mode 100644 index 000000000000..b4aaf5bffe00 --- /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/ContactsContract.java b/core/java/android/provider/ContactsContract.java index ff28596a207f..821b6df5fd15 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -1673,7 +1673,6 @@ public final class ContactsContract { * Querying for social stream data requires android.permission.READ_SOCIAL_STREAM * permission. * </p> - * @hide */ public static final class StreamItems implements StreamItemsColumns { /** @@ -2736,7 +2735,6 @@ public final class ContactsContract { * inserting or updating social stream items requires android.permission.WRITE_SOCIAL_STREAM * permission. * </p> - * @hide */ public static final class StreamItems implements BaseColumns, StreamItemsColumns { /** @@ -3149,7 +3147,6 @@ public final class ContactsContract { * </pre> * </dd> * </dl> - * @hide */ public static final class StreamItems implements BaseColumns, StreamItemsColumns { /** @@ -3247,7 +3244,6 @@ public final class ContactsContract { * Columns in the StreamItems table. * * @see ContactsContract.StreamItems - * @hide */ protected interface StreamItemsColumns { /** @@ -3538,7 +3534,6 @@ public final class ContactsContract { * <pre> * </dd> * </dl> - * @hide */ public static final class StreamItemPhotos implements BaseColumns, StreamItemPhotosColumns { /** @@ -3566,7 +3561,6 @@ public final class ContactsContract { * Columns in the StreamItemPhotos table. * * @see ContactsContract.StreamItemPhotos - * @hide */ protected interface StreamItemPhotosColumns { /** diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index a0652f7c20d0..769776ecee92 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -1183,6 +1183,10 @@ public final class Settings { 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 final class Settings { */ 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 @@ public final class Settings { "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 @@ public final class Settings { 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 0e6d07d8dd18..8eb9da13d3fd 100755 --- a/core/java/android/provider/Telephony.java +++ b/core/java/android/provider/Telephony.java @@ -1838,5 +1838,15 @@ public final class Telephony { 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 954a6feafe58..fdc25708f2d1 100755 --- a/core/java/android/speech/tts/TextToSpeech.java +++ b/core/java/android/speech/tts/TextToSpeech.java @@ -1089,6 +1089,7 @@ public class TextToSpeech { // 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 245271df5967..83b6d4c24f21 100644 --- a/core/java/android/speech/tts/TextToSpeechService.java +++ b/core/java/android/speech/tts/TextToSpeechService.java @@ -792,8 +792,13 @@ public abstract class TextToSpeechService extends Service { 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 2cc928f966fe..388920c38d12 100644 --- a/core/java/android/webkit/BrowserFrame.java +++ b/core/java/android/webkit/BrowserFrame.java @@ -813,8 +813,6 @@ class BrowserFrame extends Handler { boolean synchronous, String username, String password) { - PerfChecker checker = new PerfChecker(); - if (mSettings.getCacheMode() != WebSettings.LOAD_DEFAULT) { cacheMode = mSettings.getCacheMode(); } @@ -872,11 +870,6 @@ class BrowserFrame extends Handler { || 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 5b78586aedb4..b49843571174 100644 --- a/core/java/android/webkit/JWebCoreJavaBridge.java +++ b/core/java/android/webkit/JWebCoreJavaBridge.java @@ -87,11 +87,9 @@ final class JWebCoreJavaBridge extends Handler { * 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 04af73877cce..37e8bc090837 100644 --- a/core/java/android/webkit/LoadListener.java +++ b/core/java/android/webkit/LoadListener.java @@ -1136,7 +1136,6 @@ class LoadListener extends Handler implements EventHandler { // 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 @@ class LoadListener extends Handler implements EventHandler { } else { c.release(); } - checker.responseAlert("res nativeAddData"); } } @@ -1173,13 +1171,11 @@ class LoadListener extends Handler implements EventHandler { 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 8c5f86eb4afd..000000000000 --- 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/WebTextView.java b/core/java/android/webkit/WebTextView.java index 5ee1b8a66067..8aafc3d078fe 100644 --- a/core/java/android/webkit/WebTextView.java +++ b/core/java/android/webkit/WebTextView.java @@ -16,14 +16,9 @@ package android.webkit; -import com.android.internal.widget.EditableInputConnection; - import android.content.Context; -import android.graphics.Canvas; import android.graphics.Color; -import android.graphics.ColorFilter; import android.graphics.Paint; -import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; @@ -60,12 +55,12 @@ import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.TextView; +import junit.framework.Assert; + import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; -import junit.framework.Assert; - /** * WebTextView is a specialized version of EditText used by WebView * to overlay html textfields (and textareas) to use our standard @@ -926,18 +921,23 @@ import junit.framework.Assert; */ /* package */ void setRect(int x, int y, int width, int height) { LayoutParams lp = (LayoutParams) getLayoutParams(); + boolean needsUpdate = false; if (null == lp) { lp = new LayoutParams(width, height, x, y); } else { - lp.x = x; - lp.y = y; - lp.width = width; - lp.height = height; + if ((lp.x != x) || (lp.y != y) || (lp.width != width) + || (lp.height != height)) { + needsUpdate = true; + lp.x = x; + lp.y = y; + lp.width = width; + lp.height = height; + } } if (getParent() == null) { // Insert the view so that it's drawn first (at index 0) mWebView.addView(this, 0, lp); - } else { + } else if (needsUpdate) { setLayoutParams(lp); } // Set up a measure spec so a layout can always be recreated. diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 58b63fe53d03..55f345fb95e7 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -683,7 +683,6 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout // 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout mScrollingLayerRect.top = y; } abortAnimation(); - mPrivateHandler.removeMessages(RESUME_WEBCORE_PRIORITY); nativeSetIsScrolling(false); if (!mBlockWebkitViewMessages) { WebViewCore.resumePriority(); @@ -4119,20 +4118,6 @@ public class WebView extends AbsoluteLayout } 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout // 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout // 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 @@ public class WebView extends AbsoluteLayout // 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout mLastTouchTime = eventTime; if (!mScroller.isFinished()) { abortAnimation(); - mPrivateHandler.removeMessages(RESUME_WEBCORE_PRIORITY); } mSnapScrollMode = SNAP_NONE; mVelocityTracker = VelocityTracker.obtain(); @@ -8491,10 +8458,6 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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/NumberPicker.java b/core/java/android/widget/NumberPicker.java index 5ab99dcfa184..1a1b8d04365f 100644 --- a/core/java/android/widget/NumberPicker.java +++ b/core/java/android/widget/NumberPicker.java @@ -741,9 +741,16 @@ public class NumberPicker extends LinearLayout { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - final int newWidthMeasureSpec = makeMeasureSpec(widthMeasureSpec, mMinWidth, mMaxWidth); - final int newHeightMeasureSpec = makeMeasureSpec(heightMeasureSpec, mMinHeight, mMaxHeight); + // Try greedily to fit the max width and height. + final int newWidthMeasureSpec = makeMeasureSpec(widthMeasureSpec, mMaxWidth); + final int newHeightMeasureSpec = makeMeasureSpec(heightMeasureSpec, mMaxHeight); super.onMeasure(newWidthMeasureSpec, newHeightMeasureSpec); + // Flag if we are measured with width or height less than the respective min. + final int desiredWidth = Math.max(mMinWidth, getMeasuredWidth()); + final int desiredHeight = Math.max(mMinHeight, getMeasuredHeight()); + final int widthSize = resolveSizeAndState(desiredWidth, newWidthMeasureSpec, 0); + final int heightSize = resolveSizeAndState(desiredHeight, newHeightMeasureSpec, 0); + setMeasuredDimension(widthSize, heightSize); } @Override @@ -1357,23 +1364,19 @@ public class NumberPicker extends LinearLayout { * Makes a measure spec that tries greedily to use the max value. * * @param measureSpec The measure spec. - * @param maxValue The max value for the size. + * @param maxSize The max value for the size. * @return A measure spec greedily imposing the max size. */ - private int makeMeasureSpec(int measureSpec, int minValue, int maxValue) { + private int makeMeasureSpec(int measureSpec, int maxSize) { final int size = MeasureSpec.getSize(measureSpec); - if (size < minValue) { - throw new IllegalArgumentException("Available space is less than min size: " - + size + " < " + minValue); - } final int mode = MeasureSpec.getMode(measureSpec); switch (mode) { case MeasureSpec.EXACTLY: return measureSpec; case MeasureSpec.AT_MOST: - return MeasureSpec.makeMeasureSpec(Math.min(size, maxValue), MeasureSpec.EXACTLY); + return MeasureSpec.makeMeasureSpec(Math.min(size, maxSize), MeasureSpec.EXACTLY); case MeasureSpec.UNSPECIFIED: - return MeasureSpec.makeMeasureSpec(maxValue, MeasureSpec.EXACTLY); + return MeasureSpec.makeMeasureSpec(maxSize, MeasureSpec.EXACTLY); default: throw new IllegalArgumentException("Unknown measure mode: " + mode); } diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java index e84ae9720b1e..f524ef0f1d0f 100644 --- a/core/java/android/widget/SearchView.java +++ b/core/java/android/widget/SearchView.java @@ -728,7 +728,8 @@ public class SearchView extends LinearLayout implements CollapsibleActionView { private void updateSubmitButton(boolean hasText) { int visibility = GONE; - if (isSubmitAreaEnabled() && hasFocus() && (hasText || !mVoiceButtonEnabled)) { + if (mSubmitButtonEnabled && isSubmitAreaEnabled() && hasFocus() + && (hasText || !mVoiceButtonEnabled)) { visibility = VISIBLE; } mSubmitButton.setVisibility(visibility); @@ -1082,9 +1083,7 @@ public class SearchView extends LinearLayout implements CollapsibleActionView { CharSequence text = mQueryTextView.getText(); mUserQuery = text; boolean hasText = !TextUtils.isEmpty(text); - if (isSubmitButtonEnabled()) { - updateSubmitButton(hasText); - } + updateSubmitButton(hasText); updateVoiceButton(!hasText); updateCloseButton(); updateSubmitArea(); diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java index e929e7d55b56..87c3e9bc8b25 100644 --- a/core/java/android/widget/SpellChecker.java +++ b/core/java/android/widget/SpellChecker.java @@ -82,6 +82,8 @@ public class SpellChecker implements SpellCheckerSessionListener { } private void setLocale(Locale locale) { + closeSession(); + final TextServicesManager textServicesManager = (TextServicesManager) mTextView.getContext().getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE); if (!textServicesManager.isSpellCheckerEnabled()) { @@ -104,12 +106,6 @@ public class SpellChecker implements SpellCheckerSessionListener { // Change SpellParsers' wordIterator locale mWordIterator = new WordIterator(locale); - // Stop all SpellParsers - final int length = mSpellParsers.length; - for (int i = 0; i < length; i++) { - mSpellParsers[i].finish(); - } - // Remove existing misspelled SuggestionSpans mTextView.removeMisspelledSpans((Editable) mTextView.getText()); diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java index 27d44bf9efe8..ec3790ec2710 100644 --- a/core/java/android/widget/Spinner.java +++ b/core/java/android/widget/Spinner.java @@ -68,6 +68,7 @@ public class Spinner extends AbsSpinner implements OnClickListener { int mDropDownWidth; private int mGravity; + private boolean mDisableChildrenWhenDisabled; private Rect mTempRect = new Rect(); @@ -186,6 +187,9 @@ public class Spinner extends AbsSpinner implements OnClickListener { 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 @@ public class Spinner extends AbsSpinner implements OnClickListener { } } + @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 @@ public class Spinner extends AbsSpinner implements OnClickListener { 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 a8680d441d71..5833afd8ffe7 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -9059,51 +9059,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener /** * 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } 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 d5450e4ab9bf..17b8acfd839f 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -439,17 +439,6 @@ public class LockPatternUtils { } /** - * 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 @@ public class LockPatternUtils { 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 @@ public class LockPatternUtils { } 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 @@ public class LockPatternUtils { } 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 433a3a6d9f7c..230df39f0840 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/btn_default_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_dark.9.png Binary files differindex f57126bc56e1..13ab8f7dabb2 100644 --- a/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_light.9.png Binary files differindex f57126bc56e1..13ab8f7dabb2 100644 --- a/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_light.9.png +++ b/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_default_disabled_holo.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_holo.9.png Binary files differindex c5adc38aa99f..1d76bb5aa80b 100644 --- a/core/res/res/drawable-hdpi/btn_default_disabled_holo.9.png +++ b/core/res/res/drawable-hdpi/btn_default_disabled_holo.9.png diff --git a/core/res/res/drawable-hdpi/btn_default_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_holo_dark.9.png Binary files differindex 05cb4e455e3b..8ebd761cc1e1 100644 --- a/core/res/res/drawable-hdpi/btn_default_disabled_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/btn_default_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_default_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_holo_light.9.png Binary files differindex 05cb4e455e3b..8ebd761cc1e1 100644 --- a/core/res/res/drawable-hdpi/btn_default_disabled_holo_light.9.png +++ b/core/res/res/drawable-hdpi/btn_default_disabled_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_default_focused_holo.9.png b/core/res/res/drawable-hdpi/btn_default_focused_holo.9.png Binary files differindex efcfa26d7594..b405d81c3e85 100644 --- a/core/res/res/drawable-hdpi/btn_default_focused_holo.9.png +++ b/core/res/res/drawable-hdpi/btn_default_focused_holo.9.png diff --git a/core/res/res/drawable-hdpi/btn_default_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_focused_holo_dark.9.png Binary files differindex 3b9d73469839..fee599ae9940 100644 --- a/core/res/res/drawable-hdpi/btn_default_focused_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/btn_default_focused_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_default_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_focused_holo_light.9.png Binary files differindex 3b9d73469839..fee599ae9940 100644 --- a/core/res/res/drawable-hdpi/btn_default_focused_holo_light.9.png +++ b/core/res/res/drawable-hdpi/btn_default_focused_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_default_normal_holo.9.png b/core/res/res/drawable-hdpi/btn_default_normal_holo.9.png Binary files differindex 490b6f545aa9..dddfc26c37dd 100644 --- a/core/res/res/drawable-hdpi/btn_default_normal_holo.9.png +++ b/core/res/res/drawable-hdpi/btn_default_normal_holo.9.png diff --git a/core/res/res/drawable-hdpi/btn_default_normal_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_normal_holo_dark.9.png Binary files differindex b28518349ab7..ab40fa7ab944 100644 --- a/core/res/res/drawable-hdpi/btn_default_normal_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/btn_default_normal_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_default_normal_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_normal_holo_light.9.png Binary files differindex b28518349ab7..807792183fd5 100644 --- a/core/res/res/drawable-hdpi/btn_default_normal_holo_light.9.png +++ b/core/res/res/drawable-hdpi/btn_default_normal_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_default_pressed_holo.9.png b/core/res/res/drawable-hdpi/btn_default_pressed_holo.9.png Binary files differindex 57f20268b570..0d8f8ba49c28 100644 --- a/core/res/res/drawable-hdpi/btn_default_pressed_holo.9.png +++ b/core/res/res/drawable-hdpi/btn_default_pressed_holo.9.png diff --git a/core/res/res/drawable-hdpi/btn_default_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_pressed_holo_dark.9.png Binary files differindex 13d154fa2090..baf7018a443e 100644 --- a/core/res/res/drawable-hdpi/btn_default_pressed_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/btn_default_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_default_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_pressed_holo_light.9.png Binary files differindex 13d154fa2090..baf7018a443e 100644 --- a/core/res/res/drawable-hdpi/btn_default_pressed_holo_light.9.png +++ b/core/res/res/drawable-hdpi/btn_default_pressed_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_dark.9.png Binary files differindex 15b9fb94de2d..7a24c9b6d61b 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_light.9.png Binary files differindex 4d83d6502273..7a24c9b6d61b 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_light.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_dark.9.png Binary files differindex e06aef018761..93c6d1bdec36 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_light.9.png Binary files differindex d81d34635769..93c6d1bdec36 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_light.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_dark.9.png Binary files differindex 9f027b7c22d4..120f963a396a 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_light.9.png Binary files differindex a7582d63b3ee..120f963a396a 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_light.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_dark.9.png Binary files differindex 21be9f446cb1..6b106fb6a9cf 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_light.9.png Binary files differindex 791b318fc3d7..6b106fb6a9cf 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_light.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_dark.9.png Binary files differindex 8cf35b286dfd..a1b7003040e0 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_light.9.png Binary files differindex e475b496f503..a1b7003040e0 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_light.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_dark.9.png Binary files differindex 7996db4d8d25..7176a6b3e6a4 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_light.9.png Binary files differindex 7996db4d8d25..7176a6b3e6a4 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_light.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_dark.9.png Binary files differindex 906a22996983..7fba6a5dbc16 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_light.9.png Binary files differindex 906a22996983..7fba6a5dbc16 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_light.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_dark.9.png Binary files differindex 56bd3253cb67..8bbfe9f0a664 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_light.9.png Binary files differindex 56bd3253cb67..8bbfe9f0a664 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_light.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_dark.9.png Binary files differindex 61b2efcb7904..28f0ee62749c 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_light.9.png Binary files differindex 61b2efcb7904..28f0ee62749c 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_light.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_dark.9.png Binary files differindex d2e4ca8dfc9a..c4c41a3183cd 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_light.9.png Binary files differindex d2e4ca8dfc9a..c4c41a3183cd 100644 --- a/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_light.9.png +++ b/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/ic_media_next.png b/core/res/res/drawable-hdpi/ic_media_next.png Binary files differindex f5ba824c1943..6e27b8161e4a 100644 --- a/core/res/res/drawable-hdpi/ic_media_next.png +++ b/core/res/res/drawable-hdpi/ic_media_next.png diff --git a/core/res/res/drawable-hdpi/ic_media_pause.png b/core/res/res/drawable-hdpi/ic_media_pause.png Binary files differindex 671148e8f809..1d465a41e4b0 100644 --- a/core/res/res/drawable-hdpi/ic_media_pause.png +++ b/core/res/res/drawable-hdpi/ic_media_pause.png diff --git a/core/res/res/drawable-hdpi/ic_media_play.png b/core/res/res/drawable-hdpi/ic_media_play.png Binary files differindex c2e366a7dd7e..2746d17fb1fe 100644 --- a/core/res/res/drawable-hdpi/ic_media_play.png +++ b/core/res/res/drawable-hdpi/ic_media_play.png diff --git a/core/res/res/drawable-hdpi/ic_media_previous.png b/core/res/res/drawable-hdpi/ic_media_previous.png Binary files differindex 40ecb00f469f..85b376690418 100644 --- a/core/res/res/drawable-hdpi/ic_media_previous.png +++ b/core/res/res/drawable-hdpi/ic_media_previous.png diff --git a/core/res/res/drawable-hdpi/ic_media_stop.png b/core/res/res/drawable-hdpi/ic_media_stop.png Binary files differindex ec0c1eaabb80..a0ff13695d9b 100644 --- a/core/res/res/drawable-hdpi/ic_media_stop.png +++ b/core/res/res/drawable-hdpi/ic_media_stop.png diff --git a/core/res/res/drawable-hdpi/list_focused_holo.9.png b/core/res/res/drawable-hdpi/list_focused_holo.9.png Binary files differindex 516f5c7399c8..555270842a73 100644 --- a/core/res/res/drawable-hdpi/list_focused_holo.9.png +++ b/core/res/res/drawable-hdpi/list_focused_holo.9.png diff --git a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.png Binary files differindex 9ff4cce66b88..5717beebcf23 100644 --- a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.png +++ b/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.png diff --git a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.png Binary files differindex a556e00f25ec..e874330d3868 100644 --- a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.png +++ b/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.png diff --git a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.png Binary files differindex 935351104198..96a6c8a2dd91 100644 --- a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.png +++ b/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.png diff --git a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.png Binary files differindex 935351104198..96a6c8a2dd91 100644 --- a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.png +++ b/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.png diff --git a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.png Binary files differindex 2ca591f5a3cf..4631d85cf15e 100644 --- a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.png +++ b/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.png diff --git a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.png Binary files differindex 1275a2f29a82..39c7af4145ff 100644 --- a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.png +++ b/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.png diff --git a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.png Binary files differindex df374c4e4ce5..b06017e0f8b6 100644 --- a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.png +++ b/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.png diff --git a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.png Binary files differindex d6b9c679317f..a1000f8951f7 100644 --- a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.png +++ b/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.png diff --git a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.png Binary files differindex 69474e33414b..b3d6706a408c 100644 --- a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.png +++ b/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.png diff --git a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.png Binary files differindex 69474e33414b..b3d6706a408c 100644 --- a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.png +++ b/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.png diff --git a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.png Binary files differindex a2fc32a4652f..9ee35c7db9d8 100644 --- a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.png +++ b/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.png diff --git a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.png Binary files differindex c4b58b73ea8e..4da4fa76f996 100644 --- a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.png +++ b/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.png diff --git a/core/res/res/drawable-hdpi/presence_away.png b/core/res/res/drawable-hdpi/presence_away.png Binary files differindex 455fec188618..c39d3a87ce78 100644 --- a/core/res/res/drawable-hdpi/presence_away.png +++ b/core/res/res/drawable-hdpi/presence_away.png 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 Binary files differnew file mode 100644 index 000000000000..cbd8c5cccaae --- /dev/null +++ b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_dark.9.png 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 Binary files differnew file mode 100644 index 000000000000..f7f4ba34a1a8 --- /dev/null +++ b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_light.9.png diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_dark.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_dark.9.png Binary files differindex db236355c3ec..a82e7ac05014 100644 --- a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_dark.9.png +++ b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_dark.9.png diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_light.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_light.9.png Binary files differindex 269a4569e247..db4ce8003e4e 100644 --- a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_light.9.png +++ b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_light.9.png diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_dark.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_dark.9.png Binary files differindex d997b361faa7..0c689ff9f717 100644 --- a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_dark.9.png +++ b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_dark.9.png diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light.9.png Binary files differindex 8ed5eb7a4821..f3999204c19c 100644 --- a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light.9.png +++ b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light.9.png diff --git a/core/res/res/drawable-hdpi/spinner_ab_default_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_default_holo_dark.9.png Binary files differindex b306f22ccd26..eb28ff9a5516 100644 --- a/core/res/res/drawable-hdpi/spinner_ab_default_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/spinner_ab_default_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/spinner_ab_default_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_default_holo_light.9.png Binary files differindex 21cf17e4fd1d..d281adb553af 100644 --- a/core/res/res/drawable-hdpi/spinner_ab_default_holo_light.9.png +++ b/core/res/res/drawable-hdpi/spinner_ab_default_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_dark.9.png Binary files differindex b9833f3f94d7..b2985860907a 100644 --- a/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_light.9.png Binary files differindex f68b6624b557..4215396dd4e5 100644 --- a/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_light.9.png +++ b/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/spinner_ab_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_focused_holo_dark.9.png Binary files differindex a76f4ab6706c..a280eabf59b5 100644 --- a/core/res/res/drawable-hdpi/spinner_ab_focused_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/spinner_ab_focused_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/spinner_ab_focused_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_focused_holo_light.9.png Binary files differindex ecfe9ccbfdce..f8d619b4d47a 100644 --- a/core/res/res/drawable-hdpi/spinner_ab_focused_holo_light.9.png +++ b/core/res/res/drawable-hdpi/spinner_ab_focused_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_dark.9.png Binary files differindex 51a5226b644e..955a2f34061a 100644 --- a/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_light.9.png Binary files differindex a24da9104e03..6c22e223acd3 100644 --- a/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_light.9.png +++ b/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/spinner_default_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_default_holo_dark.9.png Binary files differindex 09fc9c32c647..34a88dfa8f87 100644 --- a/core/res/res/drawable-hdpi/spinner_default_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/spinner_default_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/spinner_default_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_default_holo_light.9.png Binary files differindex bb257b910990..b03842dfa265 100644 --- a/core/res/res/drawable-hdpi/spinner_default_holo_light.9.png +++ b/core/res/res/drawable-hdpi/spinner_default_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/spinner_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_disabled_holo_dark.9.png Binary files differindex df49a4d0bb50..2d306d984149 100644 --- a/core/res/res/drawable-hdpi/spinner_disabled_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/spinner_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/spinner_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_disabled_holo_light.9.png Binary files differindex a6cb9922a528..720c4175c605 100644 --- a/core/res/res/drawable-hdpi/spinner_disabled_holo_light.9.png +++ b/core/res/res/drawable-hdpi/spinner_disabled_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/spinner_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_focused_holo_dark.9.png Binary files differindex 09f8cefe023a..b038fba6150a 100644 --- a/core/res/res/drawable-hdpi/spinner_focused_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/spinner_focused_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/spinner_focused_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_focused_holo_light.9.png Binary files differindex 58c67a01e841..ccffda98dbcd 100644 --- a/core/res/res/drawable-hdpi/spinner_focused_holo_light.9.png +++ b/core/res/res/drawable-hdpi/spinner_focused_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/spinner_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_pressed_holo_dark.9.png Binary files differindex a4723383b31f..f638d5e7965e 100644 --- a/core/res/res/drawable-hdpi/spinner_pressed_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/spinner_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/spinner_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_pressed_holo_light.9.png Binary files differindex ed9f6f621d00..0aedd25de2cc 100644 --- a/core/res/res/drawable-hdpi/spinner_pressed_holo_light.9.png +++ b/core/res/res/drawable-hdpi/spinner_pressed_holo_light.9.png 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 Binary files differnew file mode 100644 index 000000000000..c2e4b783c31e --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png 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 Binary files differnew file mode 100644 index 000000000000..51b839fd5572 --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png diff --git a/core/res/res/drawable-hdpi/switch_bg_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_bg_disabled_holo_dark.9.png Binary files differindex e88681261aa3..f2196fd3fe32 100644 --- a/core/res/res/drawable-hdpi/switch_bg_disabled_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/switch_bg_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/switch_bg_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/switch_bg_disabled_holo_light.9.png Binary files differindex 3e92cf0ede3a..f111d823f217 100644 --- a/core/res/res/drawable-hdpi/switch_bg_disabled_holo_light.9.png +++ b/core/res/res/drawable-hdpi/switch_bg_disabled_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/switch_bg_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_bg_focused_holo_dark.9.png Binary files differindex 962cefb380fb..4e2ae0f36d4e 100644 --- a/core/res/res/drawable-hdpi/switch_bg_focused_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/switch_bg_focused_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/switch_bg_focused_holo_light.9.png b/core/res/res/drawable-hdpi/switch_bg_focused_holo_light.9.png Binary files differindex e05b345f0e2c..479e5042c394 100644 --- a/core/res/res/drawable-hdpi/switch_bg_focused_holo_light.9.png +++ b/core/res/res/drawable-hdpi/switch_bg_focused_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/switch_thumb_activated_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_thumb_activated_holo_dark.9.png Binary files differindex 0bce7679a709..2fc475b37b76 100644 --- a/core/res/res/drawable-hdpi/switch_thumb_activated_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/switch_thumb_activated_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/switch_thumb_activated_holo_light.9.png b/core/res/res/drawable-hdpi/switch_thumb_activated_holo_light.9.png Binary files differindex 3b9c048cbd28..5adecf100027 100644 --- a/core/res/res/drawable-hdpi/switch_thumb_activated_holo_light.9.png +++ b/core/res/res/drawable-hdpi/switch_thumb_activated_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_dark.9.png Binary files differindex a4bd07454f4c..457fa847ce9e 100644 --- a/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_light.9.png Binary files differindex 587bf4e5c836..c3cfc2999332 100644 --- a/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_light.9.png +++ b/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/switch_thumb_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_thumb_holo_dark.9.png Binary files differindex a86be03cad88..d0e18061fba9 100644 --- a/core/res/res/drawable-hdpi/switch_thumb_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/switch_thumb_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/switch_thumb_holo_light.9.png b/core/res/res/drawable-hdpi/switch_thumb_holo_light.9.png Binary files differindex e3b0729e34fc..c30506db3623 100644 --- a/core/res/res/drawable-hdpi/switch_thumb_holo_light.9.png +++ b/core/res/res/drawable-hdpi/switch_thumb_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_dark.9.png Binary files differindex 4b56420a0a0a..9106687c4eeb 100644 --- a/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_light.9.png Binary files differindex 741674d5218c..2bdda5624441 100644 --- a/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_light.9.png +++ b/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/sym_keyboard_num0_no_plus.png b/core/res/res/drawable-hdpi/sym_keyboard_num0_no_plus.png Binary files differindex 2aad23c99349..0e5f1e2979d6 100644 --- a/core/res/res/drawable-hdpi/sym_keyboard_num0_no_plus.png +++ b/core/res/res/drawable-hdpi/sym_keyboard_num0_no_plus.png diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_dark.9.png Binary files differindex 74ed9b5acaa6..38d00db5ced4 100644 --- a/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_light.9.png Binary files differindex 74ed9b5acaa6..38d00db5ced4 100644 --- a/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_light.9.png +++ b/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_holo.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_holo.9.png Binary files differindex abf64938f4e1..85c2c4f8ed6e 100644 --- a/core/res/res/drawable-mdpi/btn_default_disabled_holo.9.png +++ b/core/res/res/drawable-mdpi/btn_default_disabled_holo.9.png diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_holo_dark.9.png Binary files differindex 3b5d85017408..4a6351a45d64 100644 --- a/core/res/res/drawable-mdpi/btn_default_disabled_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/btn_default_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_holo_light.9.png Binary files differindex 3b5d85017408..4a6351a45d64 100644 --- a/core/res/res/drawable-mdpi/btn_default_disabled_holo_light.9.png +++ b/core/res/res/drawable-mdpi/btn_default_disabled_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_default_focused_holo.9.png b/core/res/res/drawable-mdpi/btn_default_focused_holo.9.png Binary files differindex 71b052b58798..89d7a0e66d53 100644 --- a/core/res/res/drawable-mdpi/btn_default_focused_holo.9.png +++ b/core/res/res/drawable-mdpi/btn_default_focused_holo.9.png diff --git a/core/res/res/drawable-mdpi/btn_default_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_focused_holo_dark.9.png Binary files differindex 215002bc1b45..39950f6cad1d 100644 --- a/core/res/res/drawable-mdpi/btn_default_focused_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/btn_default_focused_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_default_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_focused_holo_light.9.png Binary files differindex 215002bc1b45..39950f6cad1d 100644 --- a/core/res/res/drawable-mdpi/btn_default_focused_holo_light.9.png +++ b/core/res/res/drawable-mdpi/btn_default_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_default_normal_holo.9.png b/core/res/res/drawable-mdpi/btn_default_normal_holo.9.png Binary files differindex 87c62ff0cbd2..0895d57e89ec 100644 --- a/core/res/res/drawable-mdpi/btn_default_normal_holo.9.png +++ b/core/res/res/drawable-mdpi/btn_default_normal_holo.9.png diff --git a/core/res/res/drawable-mdpi/btn_default_normal_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_normal_holo_dark.9.png Binary files differindex dd8ee9d6beaf..54c635490834 100644 --- a/core/res/res/drawable-mdpi/btn_default_normal_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/btn_default_normal_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_default_normal_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_normal_holo_light.9.png Binary files differindex dd8ee9d6beaf..50070ed45910 100644 --- a/core/res/res/drawable-mdpi/btn_default_normal_holo_light.9.png +++ b/core/res/res/drawable-mdpi/btn_default_normal_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_default_pressed_holo.9.png b/core/res/res/drawable-mdpi/btn_default_pressed_holo.9.png Binary files differindex 51821fa6f065..6a1b6a139abb 100644 --- a/core/res/res/drawable-mdpi/btn_default_pressed_holo.9.png +++ b/core/res/res/drawable-mdpi/btn_default_pressed_holo.9.png diff --git a/core/res/res/drawable-mdpi/btn_default_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_pressed_holo_dark.9.png Binary files differindex 2ca4c3b0d8bc..13a1fdd31167 100644 --- a/core/res/res/drawable-mdpi/btn_default_pressed_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/btn_default_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_default_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_pressed_holo_light.9.png Binary files differindex 2ca4c3b0d8bc..13a1fdd31167 100644 --- a/core/res/res/drawable-mdpi/btn_default_pressed_holo_light.9.png +++ b/core/res/res/drawable-mdpi/btn_default_pressed_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_dark.9.png Binary files differindex 0fa2859ec326..88da06e1d7de 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_light.9.png Binary files differindex bdc03304cdb2..88da06e1d7de 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_light.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_dark.9.png Binary files differindex 35aca07cf020..ae2c2c4bfc4b 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_light.9.png Binary files differindex 3a07479ab446..ae2c2c4bfc4b 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_light.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_dark.9.png Binary files differindex 575558486b60..db0f9ab68882 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_light.9.png Binary files differindex b0af68f595b0..db0f9ab68882 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_light.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_dark.9.png Binary files differindex 7c725b27c11b..7abaf3ed0ad9 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_light.9.png Binary files differindex 93696aaeeb40..7abaf3ed0ad9 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_light.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_dark.9.png Binary files differindex 6dc4f1ed61be..354fd0e2c48f 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_light.9.png Binary files differindex 3a7e25c4a6ac..354fd0e2c48f 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_light.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_dark.9.png Binary files differindex 5ddcc423c50e..d311c8077ad6 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_light.9.png Binary files differindex 5ddcc423c50e..d311c8077ad6 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_light.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_dark.9.png Binary files differindex 6f19f4919f0e..d0fd585c6027 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_light.9.png Binary files differindex 6f19f4919f0e..d0fd585c6027 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_light.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_dark.9.png Binary files differindex 1087fe31a834..e27b3ded920e 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_light.9.png Binary files differindex 1087fe31a834..e27b3ded920e 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_light.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_dark.9.png Binary files differindex 7db7486e384e..cbed62f41d98 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_light.9.png Binary files differindex 7db7486e384e..cbed62f41d98 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_light.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_dark.9.png Binary files differindex 842d967f41db..16fa3320f7cc 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_light.9.png Binary files differindex 842d967f41db..16fa3320f7cc 100644 --- a/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_light.9.png +++ b/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/ic_media_next.png b/core/res/res/drawable-mdpi/ic_media_next.png Binary files differindex acef506ba7ad..fcd73d90e762 100644 --- a/core/res/res/drawable-mdpi/ic_media_next.png +++ b/core/res/res/drawable-mdpi/ic_media_next.png diff --git a/core/res/res/drawable-mdpi/ic_media_pause.png b/core/res/res/drawable-mdpi/ic_media_pause.png Binary files differindex 548ba0219311..3e6b2a17b562 100644 --- a/core/res/res/drawable-mdpi/ic_media_pause.png +++ b/core/res/res/drawable-mdpi/ic_media_pause.png diff --git a/core/res/res/drawable-mdpi/ic_media_play.png b/core/res/res/drawable-mdpi/ic_media_play.png Binary files differindex 0fe680647e94..7966bbc5161a 100644 --- a/core/res/res/drawable-mdpi/ic_media_play.png +++ b/core/res/res/drawable-mdpi/ic_media_play.png diff --git a/core/res/res/drawable-mdpi/ic_media_previous.png b/core/res/res/drawable-mdpi/ic_media_previous.png Binary files differindex 940d6a46fa09..b653d05b9f4a 100644 --- a/core/res/res/drawable-mdpi/ic_media_previous.png +++ b/core/res/res/drawable-mdpi/ic_media_previous.png diff --git a/core/res/res/drawable-mdpi/ic_media_stop.png b/core/res/res/drawable-mdpi/ic_media_stop.png Binary files differindex 24bcb709205d..8ea7efee53d6 100644 --- a/core/res/res/drawable-mdpi/ic_media_stop.png +++ b/core/res/res/drawable-mdpi/ic_media_stop.png diff --git a/core/res/res/drawable-mdpi/list_focused_holo.9.png b/core/res/res/drawable-mdpi/list_focused_holo.9.png Binary files differindex 7c0599e3a6fc..00f05d8c97e7 100644 --- a/core/res/res/drawable-mdpi/list_focused_holo.9.png +++ b/core/res/res/drawable-mdpi/list_focused_holo.9.png diff --git a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.png Binary files differindex 7d9637a9440b..50f6e98accd9 100644 --- a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.png +++ b/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.png diff --git a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.png Binary files differindex f7409e47336c..67434f6277c5 100644 --- a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.png +++ b/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.png diff --git a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.png Binary files differindex 081ea4ed303f..eb16f8dde140 100644 --- a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.png +++ b/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.png diff --git a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.png Binary files differindex 081ea4ed303f..eb16f8dde140 100644 --- a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.png +++ b/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.png diff --git a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.png Binary files differindex 739a8d7c8896..58a3b64322ac 100644 --- a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.png +++ b/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.png diff --git a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.png Binary files differindex bd440f2840d8..382943b08ac7 100644 --- a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.png +++ b/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.png diff --git a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.png Binary files differindex 0318c5f9e196..bc5e3faef985 100644 --- a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.png +++ b/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.png diff --git a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.png Binary files differindex 0318c5f9e196..bc5e3faef985 100644 --- a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.png +++ b/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.png 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 Binary files differnew file mode 100644 index 000000000000..d12a19660fd7 --- /dev/null +++ b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_dark.9.png 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 Binary files differnew file mode 100644 index 000000000000..27c7977dc66b --- /dev/null +++ b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_light.9.png diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_dark.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_dark.9.png Binary files differindex 84d4c11809e4..99c42c5740c3 100644 --- a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_dark.9.png +++ b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_dark.9.png diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_light.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_light.9.png Binary files differindex d922ef114596..886b044b2566 100644 --- a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_light.9.png +++ b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_light.9.png diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_dark.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_dark.9.png Binary files differindex 8c37c8d7356a..eee058fcfeb4 100644 --- a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_dark.9.png +++ b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_dark.9.png diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light.9.png Binary files differindex e442c28405b2..1ac24be7fa54 100644 --- a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light.9.png +++ b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light.9.png diff --git a/core/res/res/drawable-mdpi/spinner_ab_default_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_default_holo_dark.9.png Binary files differindex 9c99bdabff4c..29aff4d43f71 100644 --- a/core/res/res/drawable-mdpi/spinner_ab_default_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/spinner_ab_default_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/spinner_ab_default_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_default_holo_light.9.png Binary files differindex 81b205a59660..4055f70539b6 100644 --- a/core/res/res/drawable-mdpi/spinner_ab_default_holo_light.9.png +++ b/core/res/res/drawable-mdpi/spinner_ab_default_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_dark.9.png Binary files differindex 3ad668770537..ea4ee042eaf5 100644 --- a/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_light.9.png Binary files differindex fab4c6762af0..f74c02b9e18c 100644 --- a/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_light.9.png +++ b/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/spinner_ab_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_focused_holo_dark.9.png Binary files differindex f3ef4823cd9a..09a2992ccaef 100644 --- a/core/res/res/drawable-mdpi/spinner_ab_focused_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/spinner_ab_focused_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/spinner_ab_focused_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_focused_holo_light.9.png Binary files differindex d6772780282b..6536ee63329b 100644 --- a/core/res/res/drawable-mdpi/spinner_ab_focused_holo_light.9.png +++ b/core/res/res/drawable-mdpi/spinner_ab_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_dark.9.png Binary files differindex 6255e2eb9c61..202b5b72ee8e 100644 --- a/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_light.9.png Binary files differindex 1085248704ab..6de0ba8841d2 100644 --- a/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_light.9.png +++ b/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/spinner_default_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_default_holo_dark.9.png Binary files differindex f88dcbad908d..48af19222ecc 100644 --- a/core/res/res/drawable-mdpi/spinner_default_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/spinner_default_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/spinner_default_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_default_holo_light.9.png Binary files differindex c75eecee6e3d..b3180cbb69ee 100644 --- a/core/res/res/drawable-mdpi/spinner_default_holo_light.9.png +++ b/core/res/res/drawable-mdpi/spinner_default_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/spinner_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_disabled_holo_dark.9.png Binary files differindex eb23155e7d0f..22eddd8ae0b2 100644 --- a/core/res/res/drawable-mdpi/spinner_disabled_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/spinner_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/spinner_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_disabled_holo_light.9.png Binary files differindex 4318af5e74ed..dad0ec9a263d 100644 --- a/core/res/res/drawable-mdpi/spinner_disabled_holo_light.9.png +++ b/core/res/res/drawable-mdpi/spinner_disabled_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/spinner_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_focused_holo_dark.9.png Binary files differindex dc8f01eca73d..2cdd273bc8d0 100644 --- a/core/res/res/drawable-mdpi/spinner_focused_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/spinner_focused_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/spinner_focused_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_focused_holo_light.9.png Binary files differindex 7d3af8794019..f605db895942 100644 --- a/core/res/res/drawable-mdpi/spinner_focused_holo_light.9.png +++ b/core/res/res/drawable-mdpi/spinner_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/spinner_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_pressed_holo_dark.9.png Binary files differindex 2f00be8e7163..a69992483058 100644 --- a/core/res/res/drawable-mdpi/spinner_pressed_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/spinner_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/spinner_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_pressed_holo_light.9.png Binary files differindex 9c48cedeb967..f3c12d792803 100644 --- a/core/res/res/drawable-mdpi/spinner_pressed_holo_light.9.png +++ b/core/res/res/drawable-mdpi/spinner_pressed_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/switch_bg_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_bg_disabled_holo_dark.9.png Binary files differindex a161b03a05b3..76ccb8e96aa0 100644 --- a/core/res/res/drawable-mdpi/switch_bg_disabled_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/switch_bg_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/switch_bg_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/switch_bg_disabled_holo_light.9.png Binary files differindex c637dd1e55e9..1e56c3253d42 100644 --- a/core/res/res/drawable-mdpi/switch_bg_disabled_holo_light.9.png +++ b/core/res/res/drawable-mdpi/switch_bg_disabled_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/switch_bg_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_bg_focused_holo_dark.9.png Binary files differindex 680d1a06a672..914e4337af81 100644 --- a/core/res/res/drawable-mdpi/switch_bg_focused_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/switch_bg_focused_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/switch_bg_focused_holo_light.9.png b/core/res/res/drawable-mdpi/switch_bg_focused_holo_light.9.png Binary files differindex 70da7b343682..89b02735fef0 100644 --- a/core/res/res/drawable-mdpi/switch_bg_focused_holo_light.9.png +++ b/core/res/res/drawable-mdpi/switch_bg_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/switch_thumb_activated_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_thumb_activated_holo_dark.9.png Binary files differindex 3d786c01a66a..0787d1647f55 100644 --- a/core/res/res/drawable-mdpi/switch_thumb_activated_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/switch_thumb_activated_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/switch_thumb_activated_holo_light.9.png b/core/res/res/drawable-mdpi/switch_thumb_activated_holo_light.9.png Binary files differindex 2bad2b8f2df8..0157e68ba1ae 100644 --- a/core/res/res/drawable-mdpi/switch_thumb_activated_holo_light.9.png +++ b/core/res/res/drawable-mdpi/switch_thumb_activated_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_dark.9.png Binary files differindex f6ed0bf0af0d..51b14d0a5749 100644 --- a/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_light.9.png Binary files differindex a430b7782f13..d68568af5af5 100644 --- a/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_light.9.png +++ b/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/switch_thumb_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_thumb_holo_dark.9.png Binary files differindex 6312c599e380..6bf153afaad0 100644 --- a/core/res/res/drawable-mdpi/switch_thumb_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/switch_thumb_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/switch_thumb_holo_light.9.png b/core/res/res/drawable-mdpi/switch_thumb_holo_light.9.png Binary files differindex 208672267053..0d98983e6112 100644 --- a/core/res/res/drawable-mdpi/switch_thumb_holo_light.9.png +++ b/core/res/res/drawable-mdpi/switch_thumb_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_dark.9.png Binary files differindex e44b1d819b14..3cee7b813f1b 100644 --- a/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_light.9.png Binary files differindex ee7e37b06d26..43a7c4cf69d3 100644 --- a/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_light.9.png +++ b/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/sym_keyboard_num0_no_plus.png b/core/res/res/drawable-mdpi/sym_keyboard_num0_no_plus.png Binary files differindex 91332b17ecf3..d23114daebd7 100644 --- a/core/res/res/drawable-mdpi/sym_keyboard_num0_no_plus.png +++ b/core/res/res/drawable-mdpi/sym_keyboard_num0_no_plus.png diff --git a/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_dark.9.png Binary files differindex b534256eef94..b7707c6f3371 100644 --- a/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_light.9.png Binary files differindex b534256eef94..b7707c6f3371 100644 --- a/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/btn_default_disabled_holo.9.png b/core/res/res/drawable-xhdpi/btn_default_disabled_holo.9.png Binary files differindex aca0a23a86e1..2ed63865a844 100644 --- a/core/res/res/drawable-xhdpi/btn_default_disabled_holo.9.png +++ b/core/res/res/drawable-xhdpi/btn_default_disabled_holo.9.png diff --git a/core/res/res/drawable-xhdpi/btn_default_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_default_disabled_holo_dark.9.png Binary files differindex 137d726e26d2..ffee5e2d03ea 100644 --- a/core/res/res/drawable-xhdpi/btn_default_disabled_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/btn_default_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/btn_default_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_default_disabled_holo_light.9.png Binary files differindex 137d726e26d2..ffee5e2d03ea 100644 --- a/core/res/res/drawable-xhdpi/btn_default_disabled_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/btn_default_disabled_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/btn_default_focused_holo.9.png b/core/res/res/drawable-xhdpi/btn_default_focused_holo.9.png Binary files differindex 7dc088af5eda..702ebc65af14 100644 --- a/core/res/res/drawable-xhdpi/btn_default_focused_holo.9.png +++ b/core/res/res/drawable-xhdpi/btn_default_focused_holo.9.png diff --git a/core/res/res/drawable-xhdpi/btn_default_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_default_focused_holo_dark.9.png Binary files differindex c5bc3ecac07a..30bfa30ac3b7 100644 --- a/core/res/res/drawable-xhdpi/btn_default_focused_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/btn_default_focused_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/btn_default_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_default_focused_holo_light.9.png Binary files differindex c5bc3ecac07a..30bfa30ac3b7 100644 --- a/core/res/res/drawable-xhdpi/btn_default_focused_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/btn_default_focused_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/btn_default_normal_holo.9.png b/core/res/res/drawable-xhdpi/btn_default_normal_holo.9.png Binary files differindex a97c1d324cdb..89ce2df5bc3a 100644 --- a/core/res/res/drawable-xhdpi/btn_default_normal_holo.9.png +++ b/core/res/res/drawable-xhdpi/btn_default_normal_holo.9.png diff --git a/core/res/res/drawable-xhdpi/btn_default_normal_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_default_normal_holo_dark.9.png Binary files differindex ed7e0f419a43..745d53e7a9eb 100644 --- a/core/res/res/drawable-xhdpi/btn_default_normal_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/btn_default_normal_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/btn_default_normal_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_default_normal_holo_light.9.png Binary files differindex ed7e0f419a43..c509934f5ada 100644 --- a/core/res/res/drawable-xhdpi/btn_default_normal_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/btn_default_normal_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/btn_default_pressed_holo.9.png b/core/res/res/drawable-xhdpi/btn_default_pressed_holo.9.png Binary files differindex 25d139a71f3c..b1eab7977039 100644 --- a/core/res/res/drawable-xhdpi/btn_default_pressed_holo.9.png +++ b/core/res/res/drawable-xhdpi/btn_default_pressed_holo.9.png diff --git a/core/res/res/drawable-xhdpi/btn_default_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_default_pressed_holo_dark.9.png Binary files differindex 61f5f6f1f219..417152b4f63e 100644 --- a/core/res/res/drawable-xhdpi/btn_default_pressed_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/btn_default_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/btn_default_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_default_pressed_holo_light.9.png Binary files differindex 61f5f6f1f219..417152b4f63e 100644 --- a/core/res/res/drawable-xhdpi/btn_default_pressed_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/btn_default_pressed_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_dark.9.png Binary files differindex 18aeac6bb3c4..c271216c3223 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_light.9.png Binary files differindex 471b6ea8a803..c271216c3223 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_dark.9.png Binary files differindex 393f96726eca..a2d3ecd7efb0 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_light.9.png Binary files differindex 87193af9d2d2..a2d3ecd7efb0 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_dark.9.png Binary files differindex 0ad8f3588dd8..80cbb053bcee 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_light.9.png Binary files differindex fc21be150ef7..80cbb053bcee 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_dark.9.png Binary files differindex 5ff338d65b12..db2cfc564f3f 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_light.9.png Binary files differindex 13214732683e..db2cfc564f3f 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_dark.9.png Binary files differindex 9c914b0e440b..5086f4609432 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_light.9.png Binary files differindex fe28238fd656..5086f4609432 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_dark.9.png Binary files differindex 455fdb45e4e9..0f5851b6880f 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_light.9.png Binary files differindex 455fdb45e4e9..0f5851b6880f 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_dark.9.png Binary files differindex ee8329df7630..74c853f2e53f 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_light.9.png Binary files differindex ee8329df7630..74c853f2e53f 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_dark.9.png Binary files differindex ccfb2d00a000..7bd7af5b6b85 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_light.9.png Binary files differindex ccfb2d00a000..7bd7af5b6b85 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_dark.9.png Binary files differindex ad1f4f0045bd..71dad92384a8 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_light.9.png Binary files differindex ad1f4f0045bd..71dad92384a8 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_dark.9.png Binary files differindex 97304afe10b7..1f62eff00d4a 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_light.9.png Binary files differindex 97304afe10b7..1f62eff00d4a 100644 --- a/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/ic_media_next.png b/core/res/res/drawable-xhdpi/ic_media_next.png Binary files differindex 726fee7af47b..4def965cec24 100644 --- a/core/res/res/drawable-xhdpi/ic_media_next.png +++ b/core/res/res/drawable-xhdpi/ic_media_next.png diff --git a/core/res/res/drawable-xhdpi/ic_media_pause.png b/core/res/res/drawable-xhdpi/ic_media_pause.png Binary files differindex 8614bff431bb..6bd3d482e111 100644 --- a/core/res/res/drawable-xhdpi/ic_media_pause.png +++ b/core/res/res/drawable-xhdpi/ic_media_pause.png diff --git a/core/res/res/drawable-xhdpi/ic_media_play.png b/core/res/res/drawable-xhdpi/ic_media_play.png Binary files differindex d93e8241970d..ccfef180562c 100644 --- a/core/res/res/drawable-xhdpi/ic_media_play.png +++ b/core/res/res/drawable-xhdpi/ic_media_play.png diff --git a/core/res/res/drawable-xhdpi/ic_media_previous.png b/core/res/res/drawable-xhdpi/ic_media_previous.png Binary files differindex 59f994d0fe53..c4472ae2d9cb 100644 --- a/core/res/res/drawable-xhdpi/ic_media_previous.png +++ b/core/res/res/drawable-xhdpi/ic_media_previous.png diff --git a/core/res/res/drawable-xhdpi/ic_media_stop.png b/core/res/res/drawable-xhdpi/ic_media_stop.png Binary files differindex 00159aaf5e38..89f36950bfb9 100644 --- a/core/res/res/drawable-xhdpi/ic_media_stop.png +++ b/core/res/res/drawable-xhdpi/ic_media_stop.png diff --git a/core/res/res/drawable-xhdpi/list_focused_holo.9.png b/core/res/res/drawable-xhdpi/list_focused_holo.9.png Binary files differindex 690cb1eb61f6..b545f8e57871 100644 --- a/core/res/res/drawable-xhdpi/list_focused_holo.9.png +++ b/core/res/res/drawable-xhdpi/list_focused_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..692783468ccc --- /dev/null +++ b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_dark.9.png 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 Binary files differnew file mode 100644 index 000000000000..4bce5278ab13 --- /dev/null +++ b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_light.9.png diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_dark.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_dark.9.png Binary files differindex 9cf9173bc6fe..99dbfcca6da0 100644 --- a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_dark.9.png +++ b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_dark.9.png diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light.9.png Binary files differindex c8d8a17e78a6..2d3e5c8784d8 100644 --- a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light.9.png +++ b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light.9.png diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_dark.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_dark.9.png Binary files differindex e3793f783abe..75c5996bbc81 100644 --- a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_dark.9.png +++ b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_dark.9.png diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light.9.png Binary files differindex c0be34f0f52d..a2d6ca13fdf1 100644 --- a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light.9.png +++ b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_ab_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_default_holo_dark.9.png Binary files differindex 5e7551dce8a9..d8929fcd1864 100644 --- a/core/res/res/drawable-xhdpi/spinner_ab_default_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/spinner_ab_default_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_ab_default_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_default_holo_light.9.png Binary files differindex f4586f8e9ea0..9174c4e4bc98 100644 --- a/core/res/res/drawable-xhdpi/spinner_ab_default_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/spinner_ab_default_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_dark.9.png Binary files differindex 86d369da732f..3015d307088f 100644 --- a/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_light.9.png Binary files differindex 1c4983b8b854..126637d1194f 100644 --- a/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_dark.9.png Binary files differindex edf2573841eb..d45c7a864d9b 100644 --- a/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_light.9.png Binary files differindex 3a165793312b..29036b907a23 100644 --- a/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_dark.9.png Binary files differindex 5253673642fb..2cb34d7f6040 100644 --- a/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_light.9.png Binary files differindex cfb4a9cb4c16..82f752fdc283 100644 --- a/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_default_holo_dark.9.png Binary files differindex fab743d10099..e94ce80c9305 100644 --- a/core/res/res/drawable-xhdpi/spinner_default_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/spinner_default_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_default_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_default_holo_light.9.png Binary files differindex 9987f7401c51..f006541bb915 100644 --- a/core/res/res/drawable-xhdpi/spinner_default_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/spinner_default_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_disabled_holo_dark.9.png Binary files differindex 6dcd2d46f5d6..7bfab99ae0d6 100644 --- a/core/res/res/drawable-xhdpi/spinner_disabled_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/spinner_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_disabled_holo_light.9.png Binary files differindex bfddedbfc5d6..1edcc81e4b6b 100644 --- a/core/res/res/drawable-xhdpi/spinner_disabled_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/spinner_disabled_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_focused_holo_dark.9.png Binary files differindex eb1e1b7c5897..ff7b959a050a 100644 --- a/core/res/res/drawable-xhdpi/spinner_focused_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/spinner_focused_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_focused_holo_light.9.png Binary files differindex 00c440cb8c27..156b5ab377cb 100644 --- a/core/res/res/drawable-xhdpi/spinner_focused_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/spinner_focused_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_pressed_holo_dark.9.png Binary files differindex 28d170f4d4cc..d0ce6e4cf05b 100644 --- a/core/res/res/drawable-xhdpi/spinner_pressed_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/spinner_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_pressed_holo_light.9.png Binary files differindex d61be5d74ffe..9e9617ee7f28 100644 --- a/core/res/res/drawable-xhdpi/spinner_pressed_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/spinner_pressed_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/switch_bg_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/switch_bg_disabled_holo_dark.9.png Binary files differindex 911acd74fb7d..b23070c17319 100644 --- a/core/res/res/drawable-xhdpi/switch_bg_disabled_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/switch_bg_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/switch_bg_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/switch_bg_disabled_holo_light.9.png Binary files differindex 8ba0f75bdb84..29f177a45421 100644 --- a/core/res/res/drawable-xhdpi/switch_bg_disabled_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/switch_bg_disabled_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/switch_bg_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/switch_bg_focused_holo_dark.9.png Binary files differindex e30e34d6e417..e85103da2b8e 100644 --- a/core/res/res/drawable-xhdpi/switch_bg_focused_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/switch_bg_focused_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/switch_bg_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/switch_bg_focused_holo_light.9.png Binary files differindex b1f5b2447832..75978bccaf8a 100644 --- a/core/res/res/drawable-xhdpi/switch_bg_focused_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/switch_bg_focused_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_dark.9.png b/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_dark.9.png Binary files differindex ea53b5f3f1b4..a0e6b20031c4 100644 --- a/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_light.9.png b/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_light.9.png Binary files differindex 8a4b61aa89ec..88235fea32c1 100644 --- a/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_dark.9.png Binary files differindex 6a280dc6cd14..04fb9a173cd6 100644 --- a/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_light.9.png Binary files differindex 34a93041ac0f..06a14f38394e 100644 --- a/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/switch_thumb_holo_dark.9.png b/core/res/res/drawable-xhdpi/switch_thumb_holo_dark.9.png Binary files differindex 757fdd4ff02e..af7d63163c1a 100644 --- a/core/res/res/drawable-xhdpi/switch_thumb_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/switch_thumb_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/switch_thumb_holo_light.9.png b/core/res/res/drawable-xhdpi/switch_thumb_holo_light.9.png Binary files differindex 8873ccca1cec..d6ab3eacc864 100644 --- a/core/res/res/drawable-xhdpi/switch_thumb_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/switch_thumb_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_dark.9.png Binary files differindex d22226ed6c75..5a8e807c93f2 100644 --- a/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_light.9.png Binary files differindex c94248c01b1a..392f3dce3311 100644 --- a/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/sym_keyboard_num0_no_plus.png b/core/res/res/drawable-xhdpi/sym_keyboard_num0_no_plus.png Binary files differindex c477cf125a2f..95b542d11d07 100644 --- a/core/res/res/drawable-xhdpi/sym_keyboard_num0_no_plus.png +++ b/core/res/res/drawable-xhdpi/sym_keyboard_num0_no_plus.png diff --git a/core/res/res/drawable/quickcontact_badge_overlay_dark.xml b/core/res/res/drawable/quickcontact_badge_overlay_dark.xml index 972488d576e4..6bd7403580da 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 bf95d52807a9..cf7f9168f5e7 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 000000000000..d8a575013c39 --- /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-sw600dp/keyguard_screen_password_landscape.xml b/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml index ee1ce5faf5db..b58f0812801f 100644 --- a/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml +++ b/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml @@ -50,20 +50,56 @@ android:layout_centerVertical="true" android:layout_marginRight="155dip"> - <!-- Password entry field --> - <EditText android:id="@+id/passwordEntry" - android:layout_height="wrap_content" + + <LinearLayout + android:orientation="horizontal" android:layout_width="match_parent" - android:singleLine="true" - android:textStyle="normal" - android:inputType="textPassword" - android:gravity="center" - android:textSize="24sp" - android:textAppearance="?android:attr/textAppearanceMedium" - android:background="@drawable/lockscreen_password_field_dark" - android:textColor="#ffffffff" - android:privateImeOptions="com.google.android.inputmethod.latin.forceAscii" - /> + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:background="@drawable/lockscreen_password_field_dark"> + + <EditText android:id="@+id/passwordEntry" + android:layout_height="wrap_content" + android:layout_width="0dip" + android:layout_weight="1" + android:gravity="center" + android:layout_gravity="center" + android:layout_marginLeft="@dimen/keyguard_lockscreen_pin_margin_left" + android:singleLine="true" + android:textStyle="normal" + android:inputType="textPassword" + android:textSize="24sp" + android:textAppearance="?android:attr/textAppearanceMedium" + android:background="@null" + android:textColor="#ffffffff" + android:imeOptions="flagNoFullscreen|actionDone" + android:privateImeOptions="com.google.android.inputmethod.latin.forceAscii" + /> + + <!-- This delete button is only visible for numeric PIN entry --> + <ImageButton android:id="@+id/pinDel" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@android:drawable/ic_input_delete" + android:clickable="true" + android:padding="8dip" + android:layout_gravity="center" + android:background="?android:attr/selectableItemBackground" + android:visibility="gone" + /> + + <ImageView android:id="@+id/switch_ime_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/ic_lockscreen_ime" + android:clickable="true" + android:padding="8dip" + android:layout_gravity="center" + android:background="?android:attr/selectableItemBackground" + android:visibility="gone" + /> + + </LinearLayout> <!-- Numeric keyboard --> <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard" @@ -71,7 +107,7 @@ android:layout_height="330dip" android:background="#40000000" android:layout_marginTop="5dip" - android:keyBackground="@drawable/btn_keyboard_key_fulltrans" + android:keyBackground="@drawable/btn_keyboard_key_ics" android:visibility="gone" /> </LinearLayout> diff --git a/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml b/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml index 254dd3e21501..cadb5f8b02fc 100644 --- a/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml +++ b/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml @@ -44,22 +44,56 @@ android:gravity="center"> <!-- Password entry field --> - <EditText android:id="@+id/passwordEntry" - android:layout_height="wrap_content" + <LinearLayout + android:orientation="horizontal" android:layout_width="330dip" - android:singleLine="true" - android:textStyle="normal" - android:inputType="textPassword" - android:gravity="center" + android:layout_height="wrap_content" android:layout_gravity="center" - android:textSize="24sp" android:layout_marginTop="120dip" android:layout_marginBottom="5dip" - android:textAppearance="?android:attr/textAppearanceMedium" - android:background="@drawable/lockscreen_password_field_dark" - android:textColor="#ffffffff" - android:privateImeOptions="com.google.android.inputmethod.latin.forceAscii" - /> + android:background="@drawable/lockscreen_password_field_dark"> + + <EditText android:id="@+id/passwordEntry" + android:layout_height="wrap_content" + android:layout_width="0dip" + android:layout_weight="1" + android:singleLine="true" + android:textStyle="normal" + android:inputType="textPassword" + android:gravity="center" + android:layout_gravity="center" + android:layout_marginLeft="@dimen/keyguard_lockscreen_pin_margin_left" + android:textSize="24sp" + android:textAppearance="?android:attr/textAppearanceMedium" + android:background="@null" + android:textColor="#ffffffff" + android:privateImeOptions="com.google.android.inputmethod.latin.forceAscii" + /> + + <!-- This delete button is only visible for numeric PIN entry --> + <ImageButton android:id="@+id/pinDel" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@android:drawable/ic_input_delete" + android:clickable="true" + android:padding="8dip" + android:layout_gravity="center" + android:background="?android:attr/selectableItemBackground" + android:visibility="gone" + /> + + <ImageView android:id="@+id/switch_ime_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/ic_lockscreen_ime" + android:clickable="true" + android:padding="8dip" + android:layout_gravity="center" + android:background="?android:attr/selectableItemBackground" + android:visibility="gone" + /> + + </LinearLayout> <View android:layout_width="match_parent" @@ -72,7 +106,7 @@ android:layout_width="330dip" android:layout_height="260dip" android:background="#40000000" - android:keyBackground="@drawable/btn_keyboard_key_fulltrans" + android:keyBackground="@drawable/btn_keyboard_key_ics" android:layout_marginBottom="80dip" /> diff --git a/core/res/res/layout/action_menu_layout.xml b/core/res/res/layout/action_menu_layout.xml index 5696d87de813..c401fec8840d 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/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml index 62f59f658480..ba0c22f10041 100644 --- a/core/res/res/layout/keyguard_screen_password_landscape.xml +++ b/core/res/res/layout/keyguard_screen_password_landscape.xml @@ -143,6 +143,8 @@ android:layout_width="0dip" android:layout_weight="1" android:gravity="center" + android:layout_marginLeft="@dimen/keyguard_lockscreen_pin_margin_left" + android:layout_gravity="center_vertical" android:singleLine="true" android:textStyle="normal" android:inputType="textPassword" diff --git a/core/res/res/layout/keyguard_screen_password_portrait.xml b/core/res/res/layout/keyguard_screen_password_portrait.xml index 597cfe77571f..f6933c3924de 100644 --- a/core/res/res/layout/keyguard_screen_password_portrait.xml +++ b/core/res/res/layout/keyguard_screen_password_portrait.xml @@ -109,6 +109,8 @@ android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_horizontal" + android:layout_gravity="center_vertical" + android:layout_marginLeft="@dimen/keyguard_lockscreen_pin_margin_left" android:singleLine="true" android:textStyle="normal" android:inputType="textPassword" diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 269e348b28ab..24802e2f9635 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -1169,8 +1169,7 @@ <string name="description_target_camera" msgid="969071997552486814">"Камера"</string> <string name="description_target_silent" msgid="893551287746522182">"Тих режим"</string> <string name="description_target_soundon" msgid="30052466675500172">"Включване на звука"</string> - <!-- no translation found for description_target_unlock_tablet (3833195335629795055) --> - <skip /> + <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Прокарайте пръст, за да отключите."</string> <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Включете слушалки, за да чуете клавишите за паролата на висок глас."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Точка."</string> <string name="action_bar_home_description" msgid="5293600496601490216">"Придвижване към „Начало“"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 788b285816ef..97ad227d183a 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -1169,8 +1169,7 @@ <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string> <string name="description_target_silent" msgid="893551287746522182">"Lydløs"</string> <string name="description_target_soundon" msgid="30052466675500172">"Lyd slået til"</string> - <!-- no translation found for description_target_unlock_tablet (3833195335629795055) --> - <skip /> + <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Glid hurtigt henover for at låse op."</string> <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Tilslut et headset for at få læst taster højt, når du indtaster en adgangskode."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punktum."</string> <string name="action_bar_home_description" msgid="5293600496601490216">"Naviger hjem"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 71c6da5f3e3b..b4a3c92715cf 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -282,7 +282,7 @@ <string name="permlab_signalPersistentProcesses" msgid="4255467255488653854">"Linux-Signale an Apps senden"</string> <string name="permdesc_signalPersistentProcesses" msgid="3565530463215015289">"Ermöglicht der App, das Senden des gelieferten Signals an alle anhaltenden Prozesse zu fordern"</string> <string name="permlab_persistentActivity" msgid="8659652042401085862">"Apps permanent ausführen"</string> - <string name="permdesc_persistentActivity" msgid="5037199778265006008">"Ermöglicht einer App, eigene Komponenten persistent zu machen, damit das System diese nicht für andere Anwendungen nutzen kann"</string> + <string name="permdesc_persistentActivity" msgid="5037199778265006008">"Ermöglicht einer App, eigene Komponenten permanent zu machen, damit das System diese nicht für andere Apps nutzen kann"</string> <string name="permlab_deletePackages" msgid="3343439331576348805">"Apps löschen"</string> <string name="permdesc_deletePackages" msgid="3634943677518723314">"Ermöglicht einer App, Android-Pakete zu löschen. Schädliche Anwendungen können so wichtige Anwendungen löschen."</string> <string name="permlab_clearAppUserData" msgid="2192134353540277878">"Daten anderer Apps löschen"</string> @@ -340,7 +340,7 @@ <string name="permlab_writeCalendar" msgid="8438874755193825647">"Ohne das Wissen der Eigentümer Kalendertermine hinzufügen oder ändern und E-Mails an Gäste senden"</string> <string name="permdesc_writeCalendar" msgid="5368129321997977226">"Ermöglicht einer App das Senden von Termineinladungen als Kalendereigentümer und das Hinzufügen, Entfernen und Ändern von Terminen, die Sie auf Ihrem Gerät bearbeiten können, einschließlich der Termine von Freunden oder Kollegen. Schädliche Apps mit dieser Berechtigung können Spam-E-Mails senden, die von Kalendereigentümern zu kommen scheinen, Termine ohne das Wissen der Eigentümer ändern oder falsche Termine hinzufügen."</string> <string name="permlab_accessMockLocation" msgid="8688334974036823330">"Simulierte Standortquellen für Testzwecke"</string> - <string name="permdesc_accessMockLocation" msgid="7648286063459727252">"Erstellt falsche Standortquellen für Testzwecke. Schädliche Anwendungen können so den von den echten Standortquellen wie GPS oder Netzwerkanbieter zurückgegebenen Standort und/oder Status überschreiben."</string> + <string name="permdesc_accessMockLocation" msgid="7648286063459727252">"Erstellt simulierte Standortquellen für Testzwecke. Schädliche Anwendungen können so den von den echten Standortquellen wie GPS oder Netzwerkanbieter zurückgegebenen Standort und/oder Status überschreiben."</string> <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"Auf zusätzliche Dienstanbieterbefehle für Standort zugreifen"</string> <string name="permdesc_accessLocationExtraCommands" msgid="1948144701382451721">"Zugriff auf zusätzliche Dienstanbieterbefehle für Standort. Schädliche Anwendungen könnten so die Funktionsweise von GPS oder anderen Standortquellen beeinträchtigen."</string> <string name="permlab_installLocationProvider" msgid="6578101199825193873">"Berechtigung zur Installation eines Standortanbieters"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index dfc0916e854e..5896467226c5 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -151,7 +151,7 @@ <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sound is OFF"</string> <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sound is ON"</string> <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Airplane mode"</string> - <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Aiplane mode is ON"</string> + <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Airplane mode is ON"</string> <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Airplane mode is OFF"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index f24e64cc333b..f7dd60bcb3db 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -1169,7 +1169,7 @@ <string name="description_target_camera" msgid="969071997552486814">"دوربین"</string> <string name="description_target_silent" msgid="893551287746522182">"ساکت"</string> <string name="description_target_soundon" msgid="30052466675500172">"صدا روشن"</string> - <string name="description_target_unlock_tablet" msgid="3833195335629795055">"برای بازگشایی قفل، انگشت خود را روی صفحه بلغزانید."</string> + <string name="description_target_unlock_tablet" msgid="3833195335629795055">"برای بازگشایی قفل، بلغزانید."</string> <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"برای شنیدن کلیدهای گذرواژه که با صدای بلند خوانده میشوند، از هدست استفاده کنید."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"نقطه."</string> <string name="action_bar_home_description" msgid="5293600496601490216">"رفتن به صفحه اصلی"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 3c90e0999efb..4985388eba68 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -1169,8 +1169,7 @@ <string name="description_target_camera" msgid="969071997552486814">"Fotoaparat"</string> <string name="description_target_silent" msgid="893551287746522182">"Bešumno"</string> <string name="description_target_soundon" msgid="30052466675500172">"Zvuk je uključen"</string> - <!-- no translation found for description_target_unlock_tablet (3833195335629795055) --> - <skip /> + <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Prijeđite prstima da biste otključali."</string> <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Priključite slušalice da biste čuli tipke zaporke izgovorene naglas."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Točka."</string> <string name="action_bar_home_description" msgid="5293600496601490216">"Kreni na početnu"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 2fd2cfc12929..0169ea2f92ea 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -632,7 +632,7 @@ <string name="relationTypeSister" msgid="1735983554479076481">"Irmã"</string> <string name="relationTypeSpouse" msgid="394136939428698117">"Cônjuge"</string> <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Personalizado"</string> - <string name="sipAddressTypeHome" msgid="6093598181069359295">"Página inicial"</string> + <string name="sipAddressTypeHome" msgid="6093598181069359295">"Residência"</string> <string name="sipAddressTypeWork" msgid="6920725730797099047">"Emprego"</string> <string name="sipAddressTypeOther" msgid="4408436162950119849">"Outro"</string> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Introduzir código PIN"</string> @@ -1014,7 +1014,7 @@ <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatar"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string> <string name="adb_active_notification_message" msgid="8470296818270110396">"Seleccione para desactivar depuração USB."</string> - <string name="select_input_method" msgid="6865512749462072765">"Seleccionar método de entrada"</string> + <string name="select_input_method" msgid="6865512749462072765">"Selecionar método de entrada"</string> <string name="configure_input_methods" msgid="6324843080254191535">"Configurar métodos de entrada"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 3670e536339c..6334bcd2d2c8 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -1169,8 +1169,7 @@ <string name="description_target_camera" msgid="969071997552486814">"Cameră foto"</string> <string name="description_target_silent" msgid="893551287746522182">"Silenţios"</string> <string name="description_target_soundon" msgid="30052466675500172">"Sunet activat"</string> - <!-- no translation found for description_target_unlock_tablet (3833195335629795055) --> - <skip /> + <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Glisaţi pentru a debloca."</string> <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Conectaţi un set căşti-microfon pentru a auzi tastele apăsate când introduceţi parola."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punct."</string> <string name="action_bar_home_description" msgid="5293600496601490216">"Navigaţi la ecranul de pornire"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 24269e7d89bb..d66c2d446323 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -1080,7 +1080,7 @@ <string name="submit" msgid="1602335572089911941">"Отправить"</string> <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Включен режим \"Штурман\""</string> <string name="car_mode_disable_notification_message" msgid="668663626721675614">"Чтобы выйти, нажмите здесь."</string> - <string name="tethered_notification_title" msgid="3146694234398202601">"USB-модем или точка доступа Wi-Fi активны"</string> + <string name="tethered_notification_title" msgid="3146694234398202601">"USB-модем/точка доступа Wi-Fi используется"</string> <string name="tethered_notification_message" msgid="3067108323903048927">"Нажмите для настройки"</string> <string name="back_button_label" msgid="2300470004503343439">"Назад"</string> <string name="next_button_label" msgid="1080555104677992408">"Далее"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 157a3fcaad17..da78c176d2db 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -1169,8 +1169,7 @@ <string name="description_target_camera" msgid="969071997552486814">"Камера"</string> <string name="description_target_silent" msgid="893551287746522182">"Нечујно"</string> <string name="description_target_soundon" msgid="30052466675500172">"Укључи звук"</string> - <!-- no translation found for description_target_unlock_tablet (3833195335629795055) --> - <skip /> + <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Превуците да бисте откључали."</string> <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Укључите слушалице да бисте чули наглас изговорене тастере за лозинку."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Тачка."</string> <string name="action_bar_home_description" msgid="5293600496601490216">"Кретање до Почетне"</string> diff --git a/core/res/res/values-sw600dp/dimens.xml b/core/res/res/values-sw600dp/dimens.xml index 551c1d844157..5b488c08e0ea 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 a40e24c0b147..d0ab8b116d06 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 index 48e8f1eb70eb..8b07e347184b 100755..100644 --- 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/dimens.xml b/core/res/res/values/dimens.xml index fa1864866bdf..82ef68aef302 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -169,6 +169,9 @@ <!-- Size of top margin on Clock font to edge on unlock LockScreen --> <dimen name="keyguard_lockscreen_status_line_clockfont_bottom_margin">12dip</dimen> + <!-- Padding on left margin of PIN text entry field to center it when del button is showing --> + <dimen name="keyguard_lockscreen_pin_margin_left">40dip</dimen> + <!-- Minimum popup width for selecting an activity in ActivityChooserDialog/ActivityChooserView. --> <dimen name="activity_chooser_popup_min_width">200dip</dimen> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 97d5afe8cfdf..4d97ad20f4a5 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 index a4dfa1d0e2aa..9b8be854e325 100755 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1368,6 +1368,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 8d95d86e5e9a..73e1a7c0303e 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -1798,6 +1798,7 @@ please see styles_device_defaults.xml. <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 @@ please see styles_device_defaults.xml. </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 @@ please see styles_device_defaults.xml. </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 @@ please see styles_device_defaults.xml. </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/core/res/res/xml-xlarge/password_kbd_numeric.xml b/core/res/res/xml-xlarge/password_kbd_numeric.xml index 3745672a5808..b2704f609e0e 100755 --- a/core/res/res/xml-xlarge/password_kbd_numeric.xml +++ b/core/res/res/xml-xlarge/password_kbd_numeric.xml @@ -49,12 +49,10 @@ </Row> <Row android:rowEdgeFlags="bottom"> + <Key android:codes="48" android:keyIcon="@drawable/sym_keyboard_num0_no_plus" + android:keyWidth="66.66%p" android:keyEdgeFlags="left"/> <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok" - android:keyEdgeFlags="left"/> - <Key android:codes="48" android:keyIcon="@drawable/sym_keyboard_num0_no_plus"/> - <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete" - android:iconPreview="@drawable/sym_keyboard_feedback_delete" - android:isRepeatable="true" android:keyEdgeFlags="right"/> + android:keyEdgeFlags="right"/> </Row> </Keyboard> diff --git a/core/tests/coretests/src/android/net/NetworkStatsTest.java b/core/tests/coretests/src/android/net/NetworkStatsTest.java index b37eb466e1ca..098464f9f013 100644 --- a/core/tests/coretests/src/android/net/NetworkStatsTest.java +++ b/core/tests/coretests/src/android/net/NetworkStatsTest.java @@ -294,6 +294,22 @@ public class NetworkStatsTest extends TestCase { assertValues(after, 1, TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 128L, 8L, 0L, 0L, 0L); } + public void testClone() throws Exception { + final NetworkStats original = new NetworkStats(TEST_START, 5) + .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L) + .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L); + + // make clone and mutate original + final NetworkStats clone = original.clone(); + original.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L); + + assertEquals(3, original.size()); + assertEquals(2, clone.size()); + + assertEquals(128L + 512L + 128L, original.getTotalBytes()); + assertEquals(128L + 512L, clone.getTotalBytes()); + } + private static void assertValues(NetworkStats stats, int index, String iface, int uid, int set, int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { final NetworkStats.Entry entry = stats.getValues(index, null); diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java index f3b62ec10e51..29fab11603a4 100644 --- a/graphics/java/android/graphics/SurfaceTexture.java +++ b/graphics/java/android/graphics/SurfaceTexture.java @@ -130,10 +130,17 @@ public class SurfaceTexture { } /** - * Set the size of buffers returned by requestBuffers when a width and height - * of zero is requested. + * Set the default size of the image buffers. The image producer may override the buffer size, + * in which case the producer-set buffer size will be used, not the default size set by this + * method. Both video and camera based image producers do override the size. This method may + * be used to set the image size when producing images with {@link android.graphics.Canvas} (via + * {@link android.view.Surface#lockCanvas}), or OpenGL ES (via an EGLSurface). * - * @hide Pending approval by API council. + * The new default buffer size will take effect the next time the image producer requests a + * buffer to fill. For {@link android.graphics.Canvas} this will be the next time {@link + * android.view.Surface#lockCanvas} is called. For OpenGL ES, the EGLSurface should be + * destroyed (via eglDestroySurface), made not-current (via eglMakeCurrent), and then recreated + * (via eglCreateWindowSurface) to ensure that the new default size has taken effect. */ public void setDefaultBufferSize(int width, int height) { nativeSetDefaultBufferSize(width, height); diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h index 0e2cdf79ad19..e9059031fbfa 100644 --- a/include/media/IMediaPlayer.h +++ b/include/media/IMediaPlayer.h @@ -40,7 +40,6 @@ public: 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 4328d3cc6d74..80f43a342a55 100644 --- a/include/media/MediaPlayerInterface.h +++ b/include/media/MediaPlayerInterface.h @@ -117,9 +117,6 @@ public: 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 08835fb6c6b9..e6a0cc569b46 100644 --- a/include/media/mediaplayer.h +++ b/include/media/mediaplayer.h @@ -170,7 +170,6 @@ public: 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 a862d003ce50..590b4ae223d5 100755 --- a/media/java/android/media/videoeditor/MediaImageItem.java +++ b/media/java/android/media/videoeditor/MediaImageItem.java @@ -154,7 +154,7 @@ public class MediaImageItem extends MediaItem { final Bitmap imageBitmap; - if (mHeight > maxResolution.second) { + if (mWidth > maxResolution.first || mHeight > maxResolution.second) { /** * We need to scale the image */ @@ -971,14 +971,13 @@ public class MediaImageItem extends MediaItem { /** * 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 @@ public class MediaImageItem extends MediaItem { 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 50a41ca153ee..9c1e6b727b38 100644 --- a/media/libmedia/IMediaPlayer.cpp +++ b/media/libmedia/IMediaPlayer.cpp @@ -35,7 +35,6 @@ enum { SET_DATA_SOURCE_URL, SET_DATA_SOURCE_FD, SET_DATA_SOURCE_STREAM, - SET_VIDEO_SURFACE, PREPARE_ASYNC, START, STOP, @@ -112,16 +111,6 @@ public: 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 @@ status_t BnMediaPlayer::onTransact( 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 f72300beca1f..c2e1ddfaf43b 100644 --- a/media/libmedia/mediaplayer.cpp +++ b/media/libmedia/mediaplayer.cpp @@ -219,14 +219,6 @@ status_t MediaPlayer::getMetadata(bool update_only, bool apply_filter, Parcel *m 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 b6553586c9fa..e8d0f0c14075 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -788,14 +788,6 @@ status_t MediaPlayerService::Client::setDataSource( 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 62214bab2250..04d9e28e1199 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -248,7 +248,6 @@ private: // 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 b35696f1204c..34693898700c 100644 --- a/media/libmediaplayerservice/MidiFile.h +++ b/media/libmediaplayerservice/MidiFile.h @@ -35,7 +35,6 @@ public: 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 cd4b1efffcbc..598d573c13d6 100644 --- a/media/libmediaplayerservice/StagefrightPlayer.cpp +++ b/media/libmediaplayerservice/StagefrightPlayer.cpp @@ -69,12 +69,6 @@ status_t StagefrightPlayer::setDataSource(const sp<IStreamSource> &source) { 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 cbc6d4996da1..e89e18ab2b63 100644 --- a/media/libmediaplayerservice/StagefrightPlayer.h +++ b/media/libmediaplayerservice/StagefrightPlayer.h @@ -40,7 +40,6 @@ public: 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 802a11b0eff3..91ffa7dc43fe 100644 --- a/media/libmediaplayerservice/TestPlayerStub.h +++ b/media/libmediaplayerservice/TestPlayerStub.h @@ -75,9 +75,6 @@ class TestPlayerStub : public MediaPlayerInterface { // 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 70208f8a6136..2a5c0a6c53c6 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -99,12 +99,6 @@ void NuPlayer::setDataSource( 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 f90759dd3e94..f23deea60765 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -42,7 +42,6 @@ struct NuPlayer : public AHandler { 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 452ba994abd6..5aa99bfa1ead 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp @@ -89,12 +89,6 @@ status_t NuPlayerDriver::setDataSource(const sp<IStreamSource> &source) { 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 aaa3de0f0d9c..4a0026ca90ad 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h @@ -37,7 +37,6 @@ struct NuPlayerDriver : public MediaPlayerInterface { 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/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index bf19040fbeb3..640e9fac9c07 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -381,7 +381,7 @@ void NuPlayer::Renderer::onDrainVideoQueue() { LOGV("rendering video at media time %.2f secs", mediaTimeUs / 1E6); } - entry->mNotifyConsumed->setInt32("render", true); + entry->mNotifyConsumed->setInt32("render", !tooLate); entry->mNotifyConsumed->post(); mVideoQueue.erase(mVideoQueue.begin()); entry = NULL; diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index f37e75baa758..7d9d7ed9aa6a 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -1139,18 +1139,9 @@ bool AwesomePlayer::isPlaying() const { 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 1ba79e57edb3..e4de20adae60 100644 --- a/media/libstagefright/CameraSourceTimeLapse.cpp +++ b/media/libstagefright/CameraSourceTimeLapse.cpp @@ -257,6 +257,12 @@ bool CameraSourceTimeLapse::skipFrameAndModifyTimeStamp(int64_t *timestampUs) { 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 7d6bcad4df01..c13d6cba98d7 100644 --- a/media/libstagefright/include/AwesomePlayer.h +++ b/media/libstagefright/include/AwesomePlayer.h @@ -81,7 +81,6 @@ struct AwesomePlayer { 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 @@ private: 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 ed3051bf44a2..a6fdeea5684b 100644 --- a/media/tests/players/invoke_mock_media_player.cpp +++ b/media/tests/players/invoke_mock_media_player.cpp @@ -68,7 +68,6 @@ class Player: public MediaPlayerBase } 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/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h index a08932a3dd64..8e8e26c0a849 100644 --- a/opengl/include/EGL/eglext.h +++ b/opengl/include/EGL/eglext.h @@ -256,6 +256,21 @@ typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC)(void); typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC)(void); #endif + +/* EGL_ANDROID_blob_cache + */ +#ifndef EGL_ANDROID_blob_cache +#define EGL_ANDROID_blob_cache 1 +typedef khronos_ssize_t EGLsizei; +typedef void (*EGLSetBlobFunc) (const void* key, EGLsizei keySize, const void* value, EGLsizei valueSize); +typedef EGLsizei (*EGLGetBlobFunc) (const void* key, EGLsizei keySize, void* value, EGLsizei valueSize); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncs(EGLDisplay dpy, EGLSetBlobFunc set, EGLGetBlobFunc get); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSPROC) (EGLDisplay dpy, + EGLSetBlobFunc set, EGLGetBlobFunc get); +#endif + #ifdef __cplusplus } #endif diff --git a/opengl/libs/EGL/egl_cache.cpp b/opengl/libs/EGL/egl_cache.cpp index 1e64302f26a9..aa40d5888ce5 100644 --- a/opengl/libs/EGL/egl_cache.cpp +++ b/opengl/libs/EGL/egl_cache.cpp @@ -19,6 +19,21 @@ #include "egl_impl.h" #include "egldefs.h" +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +// Cache size limits. +static const size_t maxKeySize = 1024; +static const size_t maxValueSize = 4096; +static const size_t maxTotalSize = 64 * 1024; + +// Cache file header +static const char* cacheFileMagic = "EGL$"; +static const size_t cacheFileHeaderSize = 8; + // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- @@ -26,37 +41,37 @@ namespace android { #define BC_EXT_STR "EGL_ANDROID_blob_cache" // -// EGL_ANDROID_blob_cache types and functions +// Callback functions passed to EGL. // -typedef khronos_ssize_t EGLsizei; - -typedef void (*EGLSetBlobFunc) (const void* key, EGLsizei keySize, - const void* value, EGLsizei valueSize); - -typedef EGLsizei (*EGLGetBlobFunc) (const void* key, EGLsizei keySize, - void* value, EGLsizei valueSize); +static void setBlob(const void* key, EGLsizei keySize, const void* value, + EGLsizei valueSize) { + egl_cache_t::get()->setBlob(key, keySize, value, valueSize); +} -typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSPROC) (EGLDisplay dpy, - EGLSetBlobFunc set, EGLGetBlobFunc get); +static EGLsizei getBlob(const void* key, EGLsizei keySize, void* value, + EGLsizei valueSize) { + return egl_cache_t::get()->getBlob(key, keySize, value, valueSize); +} // // egl_cache_t definition // -static void setBlob(const void* key, EGLsizei keySize, const void* value, - EGLsizei valueSize) { +egl_cache_t::egl_cache_t() : + mInitialized(false), + mBlobCache(NULL) { } -static EGLsizei getBlob(const void* key, EGLsizei keySize, void* value, - EGLsizei valueSize) { - return 0; +egl_cache_t::~egl_cache_t() { } +egl_cache_t egl_cache_t::sCache; + egl_cache_t* egl_cache_t::get() { - static egl_cache_t theCache; - return &theCache; + return &sCache; } void egl_cache_t::initialize(egl_display_t *display) { + Mutex::Autolock lock(mMutex); for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) { egl_connection_t* const cnx = &gEGLImpl[i]; if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) { @@ -79,7 +94,8 @@ void egl_cache_t::initialize(egl_display_t *display) { continue; } - eglSetBlobCacheFuncs(display->disp[i].dpy, setBlob, getBlob); + eglSetBlobCacheFuncs(display->disp[i].dpy, android::setBlob, + android::getBlob); EGLint err = cnx->egl.eglGetError(); if (err != EGL_SUCCESS) { LOGE("eglSetBlobCacheFuncs resulted in an error: %#x", @@ -88,6 +104,210 @@ void egl_cache_t::initialize(egl_display_t *display) { } } } + mInitialized = true; +} + +void egl_cache_t::terminate() { + Mutex::Autolock lock(mMutex); + if (mBlobCache != NULL) { + saveBlobCacheLocked(); + mBlobCache = NULL; + } + mInitialized = false; +} + +void egl_cache_t::setBlob(const void* key, EGLsizei keySize, const void* value, + EGLsizei valueSize) { + Mutex::Autolock lock(mMutex); + + if (keySize < 0 || valueSize < 0) { + LOGW("EGL_ANDROID_blob_cache set: negative sizes are not allowed"); + return; + } + + if (mInitialized) { + sp<BlobCache> bc = getBlobCacheLocked(); + bc->set(key, keySize, value, valueSize); + } +} + +EGLsizei egl_cache_t::getBlob(const void* key, EGLsizei keySize, void* value, + EGLsizei valueSize) { + Mutex::Autolock lock(mMutex); + + if (keySize < 0 || valueSize < 0) { + LOGW("EGL_ANDROID_blob_cache set: negative sizes are not allowed"); + return 0; + } + + if (mInitialized) { + sp<BlobCache> bc = getBlobCacheLocked(); + return bc->get(key, keySize, value, valueSize); + } + return 0; +} + +void egl_cache_t::setCacheFilename(const char* filename) { + Mutex::Autolock lock(mMutex); + mFilename = filename; +} + +sp<BlobCache> egl_cache_t::getBlobCacheLocked() { + if (mBlobCache == NULL) { + mBlobCache = new BlobCache(maxKeySize, maxValueSize, maxTotalSize); + loadBlobCacheLocked(); + } + return mBlobCache; +} + +static uint32_t crc32c(const uint8_t* buf, size_t len) { + const uint32_t polyBits = 0x82F63B78; + uint32_t r = 0; + for (size_t i = 0; i < len; i++) { + r ^= buf[i]; + for (int j = 0; j < 8; j++) { + if (r & 1) { + r = (r >> 1) ^ polyBits; + } else { + r >>= 1; + } + } + } + return r; +} + +void egl_cache_t::saveBlobCacheLocked() { + if (mFilename.length() > 0) { + size_t cacheSize = mBlobCache->getFlattenedSize(); + size_t headerSize = cacheFileHeaderSize; + const char* fname = mFilename.string(); + + // Try to create the file with no permissions so we can write it + // without anyone trying to read it. + int fd = open(fname, O_CREAT | O_EXCL | O_RDWR, 0); + if (fd == -1) { + if (errno == EEXIST) { + // The file exists, delete it and try again. + if (unlink(fname) == -1) { + // No point in retrying if the unlink failed. + LOGE("error unlinking cache file %s: %s (%d)", fname, + strerror(errno), errno); + return; + } + // Retry now that we've unlinked the file. + fd = open(fname, O_CREAT | O_EXCL | O_RDWR, 0); + } + if (fd == -1) { + LOGE("error creating cache file %s: %s (%d)", fname, + strerror(errno), errno); + return; + } + } + + size_t fileSize = headerSize + cacheSize; + if (ftruncate(fd, fileSize) == -1) { + LOGE("error setting cache file size: %s (%d)", strerror(errno), + errno); + close(fd); + unlink(fname); + return; + } + + uint8_t* buf = reinterpret_cast<uint8_t*>(mmap(NULL, fileSize, + PROT_WRITE, MAP_SHARED, fd, 0)); + if (buf == MAP_FAILED) { + LOGE("error mmaping cache file: %s (%d)", strerror(errno), + errno); + close(fd); + unlink(fname); + return; + } + + status_t err = mBlobCache->flatten(buf + headerSize, cacheSize, NULL, + 0); + if (err != OK) { + LOGE("error writing cache contents: %s (%d)", strerror(-err), + -err); + munmap(buf, fileSize); + close(fd); + unlink(fname); + return; + } + + // Write the file magic and CRC + memcpy(buf, cacheFileMagic, 4); + uint32_t* crc = reinterpret_cast<uint32_t*>(buf + 4); + *crc = crc32c(buf + headerSize, cacheSize); + + munmap(buf, fileSize); + fchmod(fd, S_IRUSR); + close(fd); + } +} + +void egl_cache_t::loadBlobCacheLocked() { + if (mFilename.length() > 0) { + size_t headerSize = cacheFileHeaderSize; + + int fd = open(mFilename.string(), O_RDONLY, 0); + if (fd == -1) { + if (errno != ENOENT) { + LOGE("error opening cache file %s: %s (%d)", mFilename.string(), + strerror(errno), errno); + } + return; + } + + struct stat statBuf; + if (fstat(fd, &statBuf) == -1) { + LOGE("error stat'ing cache file: %s (%d)", strerror(errno), errno); + close(fd); + return; + } + + // Sanity check the size before trying to mmap it. + size_t fileSize = statBuf.st_size; + if (fileSize > maxTotalSize * 2) { + LOGE("cache file is too large: %#llx", statBuf.st_size); + close(fd); + return; + } + + uint8_t* buf = reinterpret_cast<uint8_t*>(mmap(NULL, fileSize, + PROT_READ, MAP_PRIVATE, fd, 0)); + if (buf == MAP_FAILED) { + LOGE("error mmaping cache file: %s (%d)", strerror(errno), + errno); + close(fd); + return; + } + + // Check the file magic and CRC + size_t cacheSize = fileSize - headerSize; + if (memcmp(buf, cacheFileMagic, 4) != 0) { + LOGE("cache file has bad mojo"); + close(fd); + return; + } + uint32_t* crc = reinterpret_cast<uint32_t*>(buf + 4); + if (crc32c(buf + headerSize, cacheSize) != *crc) { + LOGE("cache file failed CRC check"); + close(fd); + return; + } + + status_t err = mBlobCache->unflatten(buf + headerSize, cacheSize, NULL, 0); + if (err != OK) { + LOGE("error reading cache contents: %s (%d)", strerror(-err), + -err); + munmap(buf, fileSize); + close(fd); + return; + } + + munmap(buf, fileSize); + close(fd); + } } // ---------------------------------------------------------------------------- diff --git a/opengl/libs/EGL/egl_cache.h b/opengl/libs/EGL/egl_cache.h index 1fcfaccd8509..05d5873181e5 100644 --- a/opengl/libs/EGL/egl_cache.h +++ b/opengl/libs/EGL/egl_cache.h @@ -14,20 +14,110 @@ ** limitations under the License. */ +#ifndef ANDROID_EGL_CACHE_H +#define ANDROID_EGL_CACHE_H + +#include <EGL/egl.h> +#include <EGL/eglext.h> + +#include <utils/BlobCache.h> +#include <utils/String8.h> +#include <utils/StrongPointer.h> + // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- class egl_display_t; -class egl_cache_t { +class EGLAPI egl_cache_t { public: + // get returns a pointer to the singleton egl_cache_t object. This + // singleton object will never be destroyed. static egl_cache_t* get(); + // initialize puts the egl_cache_t into an initialized state, such that it + // is able to insert and retrieve entries from the cache. This should be + // called when EGL is initialized. When not in the initialized state the + // getBlob and setBlob methods will return without performing any cache + // operations. void initialize(egl_display_t* display); + + // terminate puts the egl_cache_t back into the uninitialized state. When + // in this state the getBlob and setBlob methods will return without + // performing any cache operations. + void terminate(); + + // setBlob attempts to insert a new key/value blob pair into the cache. + // This will be called by the hardware vendor's EGL implementation via the + // EGL_ANDROID_blob_cache extension. + void setBlob(const void* key, EGLsizei keySize, const void* value, + EGLsizei valueSize); + + // getBlob attempts to retrieve the value blob associated with a given key + // blob from cache. This will be called by the hardware vendor's EGL + // implementation via the EGL_ANDROID_blob_cache extension. + EGLsizei getBlob(const void* key, EGLsizei keySize, void* value, + EGLsizei valueSize); + + // setCacheFilename sets the name of the file that should be used to store + // cache contents from one program invocation to another. + void setCacheFilename(const char* filename); + +private: + // Creation and (the lack of) destruction is handled internally. + egl_cache_t(); + ~egl_cache_t(); + + // Copying is disallowed. + egl_cache_t(const egl_cache_t&); // not implemented + void operator=(const egl_cache_t&); // not implemented + + // getBlobCacheLocked returns the BlobCache object being used to store the + // key/value blob pairs. If the BlobCache object has not yet been created, + // this will do so, loading the serialized cache contents from disk if + // possible. + sp<BlobCache> getBlobCacheLocked(); + + // saveBlobCache attempts to save the current contents of mBlobCache to + // disk. + void saveBlobCacheLocked(); + + // loadBlobCache attempts to load the saved cache contents from disk into + // mBlobCache. + void loadBlobCacheLocked(); + + // mInitialized indicates whether the egl_cache_t is in the initialized + // state. It is initialized to false at construction time, and gets set to + // true when initialize is called. It is set back to false when terminate + // is called. When in this state, the cache behaves as normal. When not, + // the getBlob and setBlob methods will return without performing any cache + // operations. + bool mInitialized; + + // mBlobCache is the cache in which the key/value blob pairs are stored. It + // is initially NULL, and will be initialized by getBlobCacheLocked the + // first time it's needed. + sp<BlobCache> mBlobCache; + + // mFilename is the name of the file for storing cache contents in between + // program invocations. It is initialized to an empty string at + // construction time, and can be set with the setCacheFilename method. An + // empty string indicates that the cache should not be saved to or restored + // from disk. + String8 mFilename; + + // mMutex is the mutex used to prevent concurrent access to the member + // variables. It must be locked whenever the member variables are accessed. + mutable Mutex mMutex; + + // sCache is the singleton egl_cache_t object. + static egl_cache_t sCache; }; // ---------------------------------------------------------------------------- }; // namespace android // ---------------------------------------------------------------------------- + +#endif // ANDROID_EGL_CACHE_H diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp index 0f92864635c8..558ca77ff994 100644 --- a/opengl/libs/EGL/egl_display.cpp +++ b/opengl/libs/EGL/egl_display.cpp @@ -44,6 +44,7 @@ egl_display_t::egl_display_t() : egl_display_t::~egl_display_t() { magic = 0; + egl_cache_t::get()->terminate(); } egl_display_t* egl_display_t::get(EGLDisplay dpy) { diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h index 113595f17907..1c1092cd428d 100644 --- a/opengl/libs/EGL/egl_display.h +++ b/opengl/libs/EGL/egl_display.h @@ -59,7 +59,7 @@ struct egl_config_t { // ---------------------------------------------------------------------------- -class egl_display_t { +class EGLAPI egl_display_t { // marked as EGLAPI for testing purposes static egl_display_t sDisplay[NUM_DISPLAYS]; EGLDisplay getDisplay(EGLNativeDisplayType display); @@ -141,4 +141,3 @@ EGLBoolean validate_display_surface(EGLDisplay dpy, EGLSurface surface); // ---------------------------------------------------------------------------- #endif // ANDROID_EGL_DISPLAY_H - diff --git a/opengl/tests/EGLTest/Android.mk b/opengl/tests/EGLTest/Android.mk index 92d7eb12ac9d..14104d171ee0 100644 --- a/opengl/tests/EGLTest/Android.mk +++ b/opengl/tests/EGLTest/Android.mk @@ -7,6 +7,7 @@ LOCAL_MODULE := EGL_test LOCAL_MODULE_TAGS := tests LOCAL_SRC_FILES := \ + egl_cache_test.cpp \ EGL_test.cpp \ LOCAL_SHARED_LIBRARIES := \ @@ -21,9 +22,12 @@ LOCAL_STATIC_LIBRARIES := \ LOCAL_C_INCLUDES := \ bionic \ + bionic/libc/private \ bionic/libstdc++/include \ external/gtest/include \ external/stlport/stlport \ + frameworks/base/opengl/libs \ + frameworks/base/opengl/libs/EGL \ include $(BUILD_EXECUTABLE) diff --git a/opengl/tests/EGLTest/egl_cache_test.cpp b/opengl/tests/EGLTest/egl_cache_test.cpp new file mode 100644 index 000000000000..c7d9e3e201dc --- /dev/null +++ b/opengl/tests/EGLTest/egl_cache_test.cpp @@ -0,0 +1,110 @@ +/* + * 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. + */ + +#define LOG_TAG "EGL_test" +//#define LOG_NDEBUG 0 + +#include <gtest/gtest.h> + +#include <utils/Log.h> + +#include "egl_cache.h" +#include "egl_display.h" + +namespace android { + +class EGLCacheTest : public ::testing::Test { +protected: + virtual void SetUp() { + mCache = egl_cache_t::get(); + } + + virtual void TearDown() { + mCache->setCacheFilename(""); + mCache->terminate(); + } + + egl_cache_t* mCache; +}; + +TEST_F(EGLCacheTest, UninitializedCacheAlwaysMisses) { + char buf[4] = { 0xee, 0xee, 0xee, 0xee }; + mCache->setBlob("abcd", 4, "efgh", 4); + ASSERT_EQ(0, mCache->getBlob("abcd", 4, buf, 4)); + ASSERT_EQ(0xee, buf[0]); + ASSERT_EQ(0xee, buf[1]); + ASSERT_EQ(0xee, buf[2]); + ASSERT_EQ(0xee, buf[3]); +} + +TEST_F(EGLCacheTest, InitializedCacheAlwaysHits) { + char buf[4] = { 0xee, 0xee, 0xee, 0xee }; + mCache->initialize(egl_display_t::get(EGL_DEFAULT_DISPLAY)); + mCache->setBlob("abcd", 4, "efgh", 4); + ASSERT_EQ(4, mCache->getBlob("abcd", 4, buf, 4)); + ASSERT_EQ('e', buf[0]); + ASSERT_EQ('f', buf[1]); + ASSERT_EQ('g', buf[2]); + ASSERT_EQ('h', buf[3]); +} + +TEST_F(EGLCacheTest, TerminatedCacheAlwaysMisses) { + char buf[4] = { 0xee, 0xee, 0xee, 0xee }; + mCache->initialize(egl_display_t::get(EGL_DEFAULT_DISPLAY)); + mCache->setBlob("abcd", 4, "efgh", 4); + mCache->terminate(); + ASSERT_EQ(0, mCache->getBlob("abcd", 4, buf, 4)); + ASSERT_EQ(0xee, buf[0]); + ASSERT_EQ(0xee, buf[1]); + ASSERT_EQ(0xee, buf[2]); + ASSERT_EQ(0xee, buf[3]); +} + +class EGLCacheSerializationTest : public EGLCacheTest { + +protected: + + virtual void SetUp() { + EGLCacheTest::SetUp(); + + char* tn = tempnam("/sdcard", "EGL_test-cache-"); + mFilename = tn; + free(tn); + } + + virtual void TearDown() { + unlink(mFilename.string()); + EGLCacheTest::TearDown(); + } + + String8 mFilename; +}; + +TEST_F(EGLCacheSerializationTest, ReinitializedCacheContainsValues) { + char buf[4] = { 0xee, 0xee, 0xee, 0xee }; + mCache->setCacheFilename(mFilename); + mCache->initialize(egl_display_t::get(EGL_DEFAULT_DISPLAY)); + mCache->setBlob("abcd", 4, "efgh", 4); + mCache->terminate(); + mCache->initialize(egl_display_t::get(EGL_DEFAULT_DISPLAY)); + ASSERT_EQ(4, mCache->getBlob("abcd", 4, buf, 4)); + ASSERT_EQ('e', buf[0]); + ASSERT_EQ('f', buf[1]); + ASSERT_EQ('g', buf[2]); + ASSERT_EQ('h', buf[3]); +} + +} diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml index 3920257a7c43..0891525829ef 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 5495d0840477..44194f033f48 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 @@ public class DatabaseHelper extends SQLiteOpenHelper { 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/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 64c54d9e9cd9..eefb9fe69687 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -46,6 +46,16 @@ </intent-filter> </receiver> + <!-- handle dock insertion, launch screensaver instead --> + <activity android:name=".DreamsDockLauncher" + android:label="@string/dreams_dock_launcher"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.DESK_DOCK" /> + </intent-filter> + </activity> + <activity android:name=".usb.UsbStorageActivity" android:excludeFromRecents="true"> </activity> diff --git a/packages/SystemUI/res/drawable-hdpi/screenshot_panel.9.png b/packages/SystemUI/res/drawable-hdpi/screenshot_panel.9.png Binary files differindex 9447e01d8af5..2509321566ad 100644 --- a/packages/SystemUI/res/drawable-hdpi/screenshot_panel.9.png +++ b/packages/SystemUI/res/drawable-hdpi/screenshot_panel.9.png 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 Binary files differnew file mode 100644 index 000000000000..f24d8016fca9 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0.png 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 Binary files differnew file mode 100644 index 000000000000..66eb5db188d2 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0_fully.png 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 Binary files differnew file mode 100644 index 000000000000..edff74a46275 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1.png 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 Binary files differnew file mode 100644 index 000000000000..1cdd4eb5fbf0 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1_fully.png 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 Binary files differnew file mode 100644 index 000000000000..95fdaf9e6f21 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2.png 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 Binary files differnew file mode 100644 index 000000000000..8678e39f8d6a --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2_fully.png 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 Binary files differnew file mode 100644 index 000000000000..1d2d2901acf3 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3.png 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 Binary files differnew file mode 100644 index 000000000000..c2e4b783c31e --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png 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 Binary files differnew file mode 100644 index 000000000000..51b839fd5572 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png 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 Binary files differnew file mode 100644 index 000000000000..b20c5c78ef4c --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_idle.png diff --git a/packages/SystemUI/res/drawable-mdpi/screenshot_panel.9.png b/packages/SystemUI/res/drawable-mdpi/screenshot_panel.9.png Binary files differindex 7f1aea1da7f3..be1cd31c50ba 100644 --- a/packages/SystemUI/res/drawable-mdpi/screenshot_panel.9.png +++ b/packages/SystemUI/res/drawable-mdpi/screenshot_panel.9.png diff --git a/packages/SystemUI/res/drawable-xhdpi/screenshot_panel.9.png b/packages/SystemUI/res/drawable-xhdpi/screenshot_panel.9.png Binary files differindex e5cfc364cc23..c096c7a7a946 100644 --- a/packages/SystemUI/res/drawable-xhdpi/screenshot_panel.9.png +++ b/packages/SystemUI/res/drawable-xhdpi/screenshot_panel.9.png 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 fecef3dff2d2..46f4c39030b0 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 eb644b3630b3..93ac22ed0920 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-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 947ebb47958d..a8e7d0deb188 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -110,7 +110,7 @@ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string> <string name="accessibility_no_sim" msgid="8274017118472455155">"SIM-карта отсутствует."</string> - <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Общий Bluetooth-модем."</string> + <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth-модем"</string> <string name="accessibility_airplane_mode" msgid="834748999790763092">"Режим полета."</string> <!-- String.format failed for translation --> <!-- no translation found for accessibility_battery_level (7451474187113371965) --> diff --git a/packages/SystemUI/res/values/donottranslate.xml b/packages/SystemUI/res/values/donottranslate.xml index 93ec481258f5..089a54db5e86 100644 --- a/packages/SystemUI/res/values/donottranslate.xml +++ b/packages/SystemUI/res/values/donottranslate.xml @@ -18,8 +18,9 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- For formatting day of week and date in DateView. %1$s is DOW, %2$s is date. - In Roman locales we now show only the date, but DOW is available for other locales if - necessary. --> - <string name="status_bar_date_formatter">%2$s</string> + We show both (DOW on one line, then the date) but this can be overridden for locales as + necessary. + --> + <string name="status_bar_date_formatter">%1$s\n%2$s</string> </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 8108a90194a0..a0d7b13a012e 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> @@ -351,4 +356,7 @@ <!-- Content description of the clear button in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_clear_all">Clear all notifications.</string> + + <!-- Description of the desk dock action that invokes the Android Dreams screen saver feature --> + <string name="dreams_dock_launcher">Activate screen saver</string> </resources> diff --git a/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java b/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java new file mode 100644 index 000000000000..b8cdd73aa1d9 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java @@ -0,0 +1,39 @@ +package com.android.systemui; + +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.provider.Settings; +import android.util.Slog; + +public class DreamsDockLauncher extends Activity { + private static final String TAG = "DreamsDockLauncher"; + @Override + protected void onCreate (Bundle icicle) { + super.onCreate(icicle); + try { + String component = Settings.Secure.getString( + getContentResolver(), Settings.Secure.DREAM_COMPONENT); + if (component != null) { + ComponentName cn = ComponentName.unflattenFromString(component); + Intent zzz = new Intent(Intent.ACTION_MAIN) + .setComponent(cn) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS + | Intent.FLAG_ACTIVITY_NO_USER_ACTION + ); + startActivity(zzz); + } else { + Slog.e(TAG, "Couldn't start screen saver: none selected"); + } + } catch (android.content.ActivityNotFoundException exc) { + // no screensaver? give up + Slog.e(TAG, "Couldn't start screen saver: none installed"); + } + finish(); + } +} 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 c6a59d33eb0e..b0e6968c46fd 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 @@ public class PhoneStatusBar extends StatusBar { (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 13fb03e6c677..f45426bb260c 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 @@ public class AccessibilityContentDescriptions { 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 a3058166903f..f77e93f1ba84 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.NetworkInfo; 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 @@ public class NetworkController extends BroadcastReceiver { String mContentDescriptionPhoneSignal; String mContentDescriptionWifi; + String mContentDescriptionWimax; String mContentDescriptionCombinedSignal; String mContentDescriptionDataType; @@ -108,6 +110,14 @@ public class NetworkController extends BroadcastReceiver { 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 @@ public class NetworkController extends BroadcastReceiver { 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 @@ public class NetworkController extends BroadcastReceiver { int mLastDataDirectionIconId = -1; int mLastDataDirectionOverlayIconId = -1; int mLastWifiIconId = -1; + int mLastWimaxIconId = -1; int mLastCombinedSignalIconId = -1; int mLastDataTypeIconId = -1; String mLastLabel = ""; @@ -164,6 +176,7 @@ public class NetworkController extends BroadcastReceiver { // 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 @@ public class NetworkController extends BroadcastReceiver { 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 class NetworkController extends BroadcastReceiver { 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 @@ public class NetworkController extends BroadcastReceiver { } 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 @@ public class NetworkController extends BroadcastReceiver { } + // ===== 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 @@ public class NetworkController extends BroadcastReceiver { // We want to update all the icons, all at once, for any condition change updateDataNetType(); + updateWimaxIcons(); updateDataIcon(); updateTelephonySignalStrength(); updateWifiIcons(); @@ -945,6 +1019,21 @@ public class NetworkController extends BroadcastReceiver { } } + // 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 000000000000..86054895e8af --- /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/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java index 81e1901f398a..0f21bdb475a4 100644 --- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java +++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java @@ -360,8 +360,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler mHasOverlay = true; // Continue showing FaceLock area until dialer comes up or call is resumed - if (mLockPatternUtils.usingBiometricWeak() && - mLockPatternUtils.isBiometricWeakInstalled() && mFaceLockServiceRunning) { + if (usingFaceLock() && mFaceLockServiceRunning) { showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_EMERGENCY_DIALER_TIMEOUT); } @@ -582,8 +581,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler bindToFaceLock(); // Show FaceLock area, but only for a little bit so lockpattern will become visible if // FaceLock fails to start or crashes - if (mLockPatternUtils.usingBiometricWeak() && - mLockPatternUtils.isBiometricWeakInstalled()) { + if (usingFaceLock()) { showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_SERVICE_TIMEOUT); } } else { @@ -653,11 +651,10 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler ((KeyguardScreen) mUnlockScreen).onResume(); } - if (mLockPatternUtils.usingBiometricWeak() && - mLockPatternUtils.isBiometricWeakInstalled() && !mHasOverlay) { + if (usingFaceLock() && !mHasOverlay) { // Note that show() gets called before the screen turns off to set it up for next time // it is turned on. We don't want to set a timeout on the FaceLock area here because it - // may be gone by the time the screen is turned on again. We set the timout when the + // may be gone by the time the screen is turned on again. We set the timeout when the // screen turns on instead. showFaceLockArea(); } else { @@ -854,7 +851,9 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler if (mode == Mode.UnlockScreen) { final UnlockMode unlockMode = getUnlockMode(); if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) { + boolean restartFaceLock = stopFaceLockIfRunning(); recreateUnlockScreen(unlockMode); + if (restartFaceLock) activateFaceLockIfAble(); } } @@ -1147,28 +1146,33 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler // Everything below pertains to FaceLock - might want to separate this out - // Take care of FaceLock area when layout is created + // Indicates whether FaceLock is in use + private boolean usingFaceLock() { + return (mLockPatternUtils.usingBiometricWeak() && + mLockPatternUtils.isBiometricWeakInstalled()); + } + + // Takes care of FaceLock area when layout is created private void initializeFaceLockAreaView(View view) { - if (mLockPatternUtils.usingBiometricWeak() && - mLockPatternUtils.isBiometricWeakInstalled()) { + if (usingFaceLock()) { mFaceLockAreaView = view.findViewById(R.id.faceLockAreaView); if (mFaceLockAreaView == null) { Log.e(TAG, "Layout does not have faceLockAreaView and FaceLock is enabled"); - } else { - if (mBoundToFaceLockService) { - // If we are creating a layout when we are already bound to FaceLock, then we - // are undergoing an orientation change. Stop FaceLock and restart it in the - // new location. - if (DEBUG) Log.d(TAG, "Restarting FL - creating view while already bound"); - stopAndUnbindFromFaceLock(); - activateFaceLockIfAble(); - } } } else { mFaceLockAreaView = null; // Set to null if not using FaceLock } } + // Stops FaceLock if it is running and reports back whether it was running or not + private boolean stopFaceLockIfRunning() { + if (usingFaceLock() && mBoundToFaceLockService) { + stopAndUnbindFromFaceLock(); + return true; + } + return false; + } + // Handles covering or exposing FaceLock area on the client side when FaceLock starts or stops // This needs to be done in a handler because the call could be coming from a callback from the // FaceLock service that is in a thread that can't modify the UI @@ -1221,8 +1225,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler // Binds to FaceLock service. This call does not tell it to start, but it causes the service // to call the onServiceConnected callback, which then starts FaceLock. public void bindToFaceLock() { - if (mLockPatternUtils.usingBiometricWeak() && - mLockPatternUtils.isBiometricWeakInstalled()) { + if (usingFaceLock()) { if (!mBoundToFaceLockService) { if (DEBUG) Log.d(TAG, "before bind to FaceLock service"); mContext.bindService(new Intent(IFaceLockInterface.class.getName()), @@ -1238,8 +1241,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler // Tells FaceLock to stop and then unbinds from the FaceLock service public void stopAndUnbindFromFaceLock() { - if (mLockPatternUtils.usingBiometricWeak() && - mLockPatternUtils.isBiometricWeakInstalled()) { + if (usingFaceLock()) { stopFaceLock(); if (mBoundToFaceLockService) { @@ -1300,8 +1302,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler // Tells the FaceLock service to start displaying its UI and perform recognition public void startFaceLock(IBinder windowToken, int x, int y, int h, int w) { - if (mLockPatternUtils.usingBiometricWeak() && - mLockPatternUtils.isBiometricWeakInstalled()) { + if (usingFaceLock()) { synchronized (mFaceLockServiceRunningLock) { if (!mFaceLockServiceRunning) { if (DEBUG) Log.d(TAG, "Starting FaceLock"); @@ -1322,8 +1323,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler // Tells the FaceLock service to stop displaying its UI and stop recognition public void stopFaceLock() { - if (mLockPatternUtils.usingBiometricWeak() && - mLockPatternUtils.isBiometricWeakInstalled()) { + if (usingFaceLock()) { // Note that attempting to stop FaceLock when it's not running is not an issue. // FaceLock can return, which stops it and then we try to stop it when the // screen is turned off. That's why we check. diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java index 3469483330d6..24a2420428d3 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.view.ViewGroup; 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 @@ class LockScreen extends LinearLayout implements KeyguardScreen { 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/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java index 3ad716b7117d..06cd69ecbad8 100644 --- a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java +++ b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java @@ -35,15 +35,18 @@ import android.text.InputType; import android.text.TextWatcher; import android.text.method.DigitsKeyListener; import android.text.method.TextKeyListener; +import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; +import android.view.ViewGroup.LayoutParams; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; import android.widget.EditText; import android.widget.LinearLayout; +import android.widget.Space; import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; @@ -114,6 +117,7 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED, 0) != 0); + boolean imeOrDeleteButtonVisible = false; if (mIsAlpha) { // We always use the system IME for alpha keyboard, so hide lockscreen's soft keyboard mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA); @@ -129,6 +133,7 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen View pinDelete = findViewById(R.id.pinDel); if (pinDelete != null) { pinDelete.setVisibility(View.VISIBLE); + imeOrDeleteButtonVisible = true; pinDelete.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { @@ -181,6 +186,7 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen Context.INPUT_METHOD_SERVICE); if (mIsAlpha && switchImeButton != null && hasMultipleEnabledIMEsOrSubtypes(imm, false)) { switchImeButton.setVisibility(View.VISIBLE); + imeOrDeleteButtonVisible = true; switchImeButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { mCallback.pokeWakelock(); // Leave the screen on a bit longer @@ -188,6 +194,16 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen } }); } + + // If no icon is visible, reset the left margin on the password field so the text is + // still centered. + if (!imeOrDeleteButtonVisible) { + android.view.ViewGroup.LayoutParams params = mPasswordEntry.getLayoutParams(); + if (params instanceof MarginLayoutParams) { + ((MarginLayoutParams)params).leftMargin = 0; + mPasswordEntry.setLayoutParams(params); + } + } } /** diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 7d97246c1fa6..aa1c81c07b9e 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -493,7 +493,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { return true; } if ((mCarDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_CAR) || - (mDeskDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_DESK)) { + (mDeskDockEnablesAccelerometer && (mDockMode == Intent.EXTRA_DOCK_STATE_DESK + || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK + || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK))) { // enable accelerometer if we are docked in a dock that enables accelerometer // orientation management, return true; @@ -3137,7 +3139,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { // enable 180 degree rotation while docked. preferredRotation = mCarDockEnablesAccelerometer ? sensorRotation : mCarDockRotation; - } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK + } else if ((mDockMode == Intent.EXTRA_DOCK_STATE_DESK + || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK + || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK) && (mDeskDockEnablesAccelerometer || mDeskDockRotation >= 0)) { // Ignore sensor when in desk dock unless explicitly enabled. // This case can override the behavior of NOSENSOR, and can also diff --git a/preloaded-classes b/preloaded-classes index 31d49ce2851a..c29ba1560dba 100644 --- a/preloaded-classes +++ b/preloaded-classes @@ -18,7 +18,12 @@ android.accounts.IAccountManagerResponse 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$CreateServiceData 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.ApplicationLoaders 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.ContextImpl$StaticServiceFetcher 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.Instrumentation 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.emoji.EmojiFactory 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.LineHeightSpan 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$OnLongClickListener 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.EditorInfo$1 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.webkit.WebViewCore 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.CheckBox 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.SearchView 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 69560e5743c9..ff262f12ab61 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -2066,7 +2066,21 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track // 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. + // enforce this condition only once to enable draining the buffer in case the client + // app does not call stop() and relies on underrun to stop: + // hence the test on (track->mRetryCount >= kMaxTrackRetries) meaning the track was mixed + // during last round + uint32_t minFrames = 1; + if (!track->isStopped() && !track->isPausing() && + (track->mRetryCount >= kMaxTrackRetries)) { + 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 8c42f3133a0c..4af61129e211 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -26,8 +26,10 @@ import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; 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.Proxy; 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.Tethering; 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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/DockObserver.java b/services/java/com/android/server/DockObserver.java index dea900786874..64789d33692d 100644 --- a/services/java/com/android/server/DockObserver.java +++ b/services/java/com/android/server/DockObserver.java @@ -82,7 +82,9 @@ class DockObserver extends UEventObserver { // Don't force screen on when undocking from the desk dock. // The change in power state will do this anyway. // FIXME - we should be configurable. - if (mPreviousDockState != Intent.EXTRA_DOCK_STATE_DESK || + if ((mPreviousDockState != Intent.EXTRA_DOCK_STATE_DESK + && mPreviousDockState != Intent.EXTRA_DOCK_STATE_LE_DESK + && mPreviousDockState != Intent.EXTRA_DOCK_STATE_HE_DESK) || mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) { mPowerManager.userActivityWithForce(SystemClock.uptimeMillis(), false, true); diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java index 6887de32e112..da960aeae5e3 100644 --- a/services/java/com/android/server/NetworkManagementService.java +++ b/services/java/com/android/server/NetworkManagementService.java @@ -1136,12 +1136,14 @@ public class NetworkManagementService extends INetworkManagementService.Stub final StringBuilder command = new StringBuilder(); command.append("bandwidth removeiquota ").append(iface); + mActiveQuotaIfaces.remove(iface); + mActiveAlertIfaces.remove(iface); + try { // TODO: support quota shared across interfaces mConnector.doCommand(command.toString()); - mActiveQuotaIfaces.remove(iface); - mActiveAlertIfaces.remove(iface); } catch (NativeDaemonConnectorException e) { + // TODO: include current iptables state throw new IllegalStateException("Error communicating to native daemon", e); } } diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java index 1b0addfdae4e..6b23b33ae7bb 100644 --- a/services/java/com/android/server/PowerManagerService.java +++ b/services/java/com/android/server/PowerManagerService.java @@ -100,10 +100,13 @@ public class PowerManagerService extends IPowerManager.Stub private static final int LONG_KEYLIGHT_DELAY = 6000; // t+6 sec private static final int LONG_DIM_TIME = 7000; // t+N-5 sec - // How long to wait to debounce light sensor changes. + // How long to wait to debounce light sensor changes in milliseconds private static final int LIGHT_SENSOR_DELAY = 2000; - // For debouncing the proximity sensor. + // light sensor events rate in microseconds + private static final int LIGHT_SENSOR_RATE = 1000000; + + // For debouncing the proximity sensor in milliseconds private static final int PROXIMITY_SENSOR_DELAY = 1000; // trigger proximity if distance is less than 5 cm @@ -3049,7 +3052,7 @@ public class PowerManagerService extends IPowerManager.Stub try { if (enable) { mSensorManager.registerListener(mLightListener, mLightSensor, - SensorManager.SENSOR_DELAY_NORMAL); + LIGHT_SENSOR_RATE); } else { mSensorManager.unregisterListener(mLightListener); mHandler.removeCallbacks(mAutoBrightnessTask); diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java index 431cc39082de..280b32941571 100644 --- a/services/java/com/android/server/UiModeManagerService.java +++ b/services/java/com/android/server/UiModeManagerService.java @@ -123,6 +123,10 @@ class UiModeManagerService extends IUiModeManager.Stub { @Override public void onReceive(Context context, Intent intent) { if (getResultCode() != Activity.RESULT_OK) { + if (LOG) { + Slog.v(TAG, "Handling broadcast result for action " + intent.getAction() + + ": canceled: " + getResultCode()); + } return; } @@ -151,6 +155,12 @@ class UiModeManagerService extends IUiModeManager.Stub { category = Intent.CATEGORY_HOME; } } + + if (LOG) { + Slog.v(TAG, String.format( + "Handling broadcast result for action %s: enable=0x%08x disable=0x%08x category=%s", + intent.getAction(), enableFlags, disableFlags, category)); + } if (category != null) { // This is the new activity that will serve as home while @@ -424,11 +434,22 @@ class UiModeManagerService extends IUiModeManager.Stub { } } + final static boolean isDeskDockState(int state) { + switch (state) { + case Intent.EXTRA_DOCK_STATE_DESK: + case Intent.EXTRA_DOCK_STATE_LE_DESK: + case Intent.EXTRA_DOCK_STATE_HE_DESK: + return true; + default: + return false; + } + } + final void updateConfigurationLocked(boolean sendIt) { int uiMode = Configuration.UI_MODE_TYPE_NORMAL; if (mCarModeEnabled) { uiMode = Configuration.UI_MODE_TYPE_CAR; - } else if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) { + } else if (isDeskDockState(mDockState)) { uiMode = Configuration.UI_MODE_TYPE_DESK; } if (mCarModeEnabled) { @@ -477,7 +498,7 @@ class UiModeManagerService extends IUiModeManager.Stub { if (mLastBroadcastState == Intent.EXTRA_DOCK_STATE_CAR) { adjustStatusBarCarModeLocked(); oldAction = UiModeManager.ACTION_EXIT_CAR_MODE; - } else if (mLastBroadcastState == Intent.EXTRA_DOCK_STATE_DESK) { + } else if (isDeskDockState(mLastBroadcastState)) { oldAction = UiModeManager.ACTION_EXIT_DESK_MODE; } @@ -491,12 +512,12 @@ class UiModeManagerService extends IUiModeManager.Stub { mLastBroadcastState = Intent.EXTRA_DOCK_STATE_CAR; action = UiModeManager.ACTION_ENTER_CAR_MODE; } - } else if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) { - if (mLastBroadcastState != Intent.EXTRA_DOCK_STATE_DESK) { + } else if (isDeskDockState(mDockState)) { + if (!isDeskDockState(mLastBroadcastState)) { if (oldAction != null) { mContext.sendBroadcast(new Intent(oldAction)); } - mLastBroadcastState = Intent.EXTRA_DOCK_STATE_DESK; + mLastBroadcastState = mDockState; action = UiModeManager.ACTION_ENTER_DESK_MODE; } } else { @@ -505,6 +526,12 @@ class UiModeManagerService extends IUiModeManager.Stub { } if (action != null) { + if (LOG) { + Slog.v(TAG, String.format( + "updateLocked: preparing broadcast: action=%s enable=0x%08x disable=0x%08x", + action, enableFlags, disableFlags)); + } + // Send the ordered broadcast; the result receiver will receive after all // broadcasts have been sent. If any broadcast receiver changes the result // code from the initial value of RESULT_OK, then the result receiver will @@ -526,7 +553,7 @@ class UiModeManagerService extends IUiModeManager.Stub { if ((enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) { homeIntent = buildHomeIntent(Intent.CATEGORY_CAR_DOCK); } - } else if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) { + } else if (isDeskDockState(mDockState)) { if ((enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) { homeIntent = buildHomeIntent(Intent.CATEGORY_DESK_DOCK); } @@ -535,6 +562,12 @@ class UiModeManagerService extends IUiModeManager.Stub { homeIntent = buildHomeIntent(Intent.CATEGORY_HOME); } } + + if (LOG) { + Slog.v(TAG, "updateLocked: null action, mDockState=" + + mDockState +", firing homeIntent: " + homeIntent); + } + if (homeIntent != null) { try { mContext.startActivity(homeIntent); diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java index 01eade136f19..3c65255ca5bf 100644 --- a/services/java/com/android/server/WifiService.java +++ b/services/java/com/android/server/WifiService.java @@ -619,12 +619,7 @@ public class WifiService extends IWifiManager.Stub { */ public WifiConfiguration getWifiApConfiguration() { enforceAccessPermission(); - if (mWifiStateMachineChannel != null) { - return mWifiStateMachine.syncGetWifiApConfiguration(mWifiStateMachineChannel); - } else { - Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); - return null; - } + return mWifiStateMachine.syncGetWifiApConfiguration(); } /** diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 4fe8119ba19b..05d42ada146c 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -1220,6 +1220,8 @@ public final class ActivityManagerService extends ActivityManagerNative } Thread thread = new Thread() { @Override public void run() { + StringBuilder dropBuilder = new StringBuilder(1024); + StringBuilder logBuilder = new StringBuilder(1024); try { java.lang.Process proc = Runtime.getRuntime().exec(new String[] { "procrank", }); @@ -1233,16 +1235,29 @@ public final class ActivityManagerService extends ActivityManagerNative break; } if (line.length() > 0) { - Slog.i(TAG, line); + logBuilder.append(line); + logBuilder.append('\n'); } + dropBuilder.append(line); + dropBuilder.append('\n'); } converter.close(); } catch (IOException e) { } StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); - dumpApplicationMemoryUsage(null, pw, " ", new String[] { }, true); - Slog.i(TAG, sw.toString()); + StringWriter catSw = new StringWriter(); + PrintWriter catPw = new PrintWriter(catSw); + dumpApplicationMemoryUsage(null, pw, " ", new String[] { }, true, catPw); + String memUsage = sw.toString(); + dropBuilder.append('\n'); + dropBuilder.append(memUsage); + dropBuilder.append(catSw.toString()); + logBuilder.append(memUsage); + addErrorToDropBox("watchdog", null, "system_server", null, + null, "Low on memory -- no more background processes", + dropBuilder.toString(), null, null); + Slog.i(TAG, logBuilder.toString()); synchronized (ActivityManagerService.this) { long now = SystemClock.uptimeMillis(); if (mLastMemUsageReportTime < now) { @@ -1394,7 +1409,7 @@ public final class ActivityManagerService extends ActivityManagerNative return; } - mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false); + mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); } } @@ -3192,7 +3207,49 @@ public final class ActivityManagerService extends ActivityManagerNative return; } killPackageProcessesLocked(packageName, pkgUid, - ProcessList.SERVICE_ADJ, false, true, true, false); + ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); + } + } finally { + Binder.restoreCallingIdentity(callingId); + } + } + + public void killAllBackgroundProcesses() { + if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) + != PackageManager.PERMISSION_GRANTED) { + String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" + + Binder.getCallingPid() + + ", uid=" + Binder.getCallingUid() + + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; + Slog.w(TAG, msg); + throw new SecurityException(msg); + } + + long callingId = Binder.clearCallingIdentity(); + try { + synchronized(this) { + ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); + for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { + final int NA = apps.size(); + for (int ia=0; ia<NA; ia++) { + ProcessRecord app = apps.valueAt(ia); + if (app.persistent) { + // we don't kill persistent processes + continue; + } + if (app.removed) { + procs.add(app); + } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { + app.removed = true; + procs.add(app); + } + } + } + + int N = procs.size(); + for (int i=0; i<N; i++) { + removeProcessLocked(procs.get(i), false, true, "kill all background"); + } } } finally { Binder.restoreCallingIdentity(callingId); @@ -3364,7 +3421,7 @@ public final class ActivityManagerService extends ActivityManagerNative private final boolean killPackageProcessesLocked(String packageName, int uid, int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, - boolean evenPersistent) { + boolean evenPersistent, String reason) { ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); // Remove all processes this package may have touched: all with the @@ -3399,7 +3456,7 @@ public final class ActivityManagerService extends ActivityManagerNative int N = procs.size(); for (int i=0; i<N; i++) { - removeProcessLocked(procs.get(i), callerWillRestart, allowRestart); + removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); } return N > 0; } @@ -3430,7 +3487,7 @@ public final class ActivityManagerService extends ActivityManagerNative } boolean didSomething = killPackageProcessesLocked(name, uid, -100, - callerWillRestart, false, doit, evenPersistent); + callerWillRestart, false, doit, evenPersistent, "force stop"); TaskRecord lastTask = null; for (i=0; i<mMainStack.mHistory.size(); i++) { @@ -3518,11 +3575,11 @@ public final class ActivityManagerService extends ActivityManagerNative } private final boolean removeProcessLocked(ProcessRecord app, - boolean callerWillRestart, boolean allowRestart) { + boolean callerWillRestart, boolean allowRestart, String reason) { final String name = app.processName; final int uid = app.info.uid; if (DEBUG_PROCESSES) Slog.d( - TAG, "Force removing process " + app + " (" + name + TAG, "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")"); mProcessNames.remove(name, uid); @@ -3537,9 +3594,10 @@ public final class ActivityManagerService extends ActivityManagerNative mPidsSelfLocked.remove(pid); mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); } + Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); handleAppDiedLocked(app, true, allowRestart); mLruProcesses.remove(app); - Process.killProcess(pid); + Process.killProcessQuiet(pid); if (app.persistent) { if (!callerWillRestart) { @@ -6846,7 +6904,7 @@ public final class ActivityManagerService extends ActivityManagerNative for (int i=procsToKill.size()-1; i>=0; i--) { ProcessRecord proc = procsToKill.get(i); Slog.i(TAG, "Removing system update proc: " + proc); - removeProcessLocked(proc, true, false); + removeProcessLocked(proc, true, false, "system update done"); } } @@ -7042,7 +7100,7 @@ public final class ActivityManagerService extends ActivityManagerNative // Don't let services in this process be restarted and potentially // annoy the user repeatedly. Unless it is persistent, since those // processes run critical code. - removeProcessLocked(app, false, false); + removeProcessLocked(app, false, false, "crash"); mMainStack.resumeTopActivityLocked(null); return false; } @@ -9298,8 +9356,10 @@ public final class ActivityManagerService extends ActivityManagerNative } final void dumpApplicationMemoryUsage(FileDescriptor fd, - PrintWriter pw, String prefix, String[] args, boolean brief) { + PrintWriter pw, String prefix, String[] args, boolean brief, + PrintWriter categoryPw) { boolean dumpAll = false; + boolean oomOnly = false; int opti = 0; while (opti < args.length) { @@ -9310,9 +9370,12 @@ public final class ActivityManagerService extends ActivityManagerNative opti++; if ("-a".equals(opt)) { dumpAll = true; + } else if ("--oom".equals(opt)) { + oomOnly = true; } else if ("-h".equals(opt)) { - pw.println("meminfo dump options: [-a] [process]"); + pw.println("meminfo dump options: [-a] [--oom] [process]"); pw.println(" -a: include all available information for each process."); + pw.println(" --oom: only show processes organized by oom adj."); pw.println("If [process] is specified it can be the name or "); pw.println("pid of a specific process to dump."); return; @@ -9438,7 +9501,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } - if (!brief) { + if (!brief && !oomOnly) { pw.println(); pw.println("Total PSS by process:"); dumpMemItems(pw, " ", procMems, true); @@ -9446,10 +9509,11 @@ public final class ActivityManagerService extends ActivityManagerNative } pw.println("Total PSS by OOM adjustment:"); dumpMemItems(pw, " ", oomMems, false); - if (!brief) { - pw.println(); - pw.println("Total PSS by category:"); - dumpMemItems(pw, " ", catMems, true); + if (!oomOnly) { + PrintWriter out = categoryPw != null ? categoryPw : pw; + out.println(); + out.println("Total PSS by category:"); + dumpMemItems(out, " ", catMems, true); } pw.println(); pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb"); diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java index e49acaf4d119..423a78fff4b8 100644 --- a/services/java/com/android/server/connectivity/Tethering.java +++ b/services/java/com/android/server/connectivity/Tethering.java @@ -81,6 +81,9 @@ public class Tethering extends INetworkManagementEventObserver.Stub { 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 @@ public class Tethering extends INetworkManagementEventObserver.Stub { 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 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } 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 @@ public class Tethering extends INetworkManagementEventObserver.Stub { 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 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } 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 class Tethering extends INetworkManagementEventObserver.Stub { 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 class Tethering extends INetworkManagementEventObserver.Stub { 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 class Tethering extends INetworkManagementEventObserver.Stub { 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 class Tethering extends INetworkManagementEventObserver.Stub { 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 @@ public class Tethering extends INetworkManagementEventObserver.Stub { 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 class Tethering extends INetworkManagementEventObserver.Stub { 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 @@ public class Tethering extends INetworkManagementEventObserver.Stub { return true; } + // TODO - return copies so people can't tamper public String[] getTetherableUsbRegexs() { return mTetherableUsbRegexs; } @@ -561,7 +583,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { 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 class Tethering extends INetworkManagementEventObserver.Stub { } 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 class Tethering extends INetworkManagementEventObserver.Stub { 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); + 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 { - 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); - } + 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 class Tethering extends INetworkManagementEventObserver.Stub { 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 class Tethering extends INetworkManagementEventObserver.Stub { 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 class Tethering extends INetworkManagementEventObserver.Stub { 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 @@ public class Tethering extends INetworkManagementEventObserver.Stub { 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 @@ public class Tethering extends INetworkManagementEventObserver.Stub { 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 @@ public class Tethering extends INetworkManagementEventObserver.Stub { 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 @@ public class Tethering extends INetworkManagementEventObserver.Stub { 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/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java index 289ea1fe1019..2a1b1db0bf77 100644 --- a/services/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java @@ -190,6 +190,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private static final int MSG_METERED_IFACES_CHANGED = 2; private static final int MSG_FOREGROUND_ACTIVITIES_CHANGED = 3; private static final int MSG_PROCESS_DIED = 4; + private static final int MSG_LIMIT_REACHED = 5; private final Context mContext; private final IActivityManager mActivityManager; @@ -225,8 +226,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { /** Set of currently active {@link Notification} tags. */ private HashSet<String> mActiveNotifs = Sets.newHashSet(); - /** Current values from {@link #setPolicyDataEnable(int, boolean)}. */ - private SparseBooleanArray mActiveNetworkEnabled = new SparseBooleanArray(); /** Foreground at both UID and PID granularity. */ private SparseBooleanArray mUidForeground = new SparseBooleanArray(); @@ -424,19 +423,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // only someone like NMS should be calling us mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); - synchronized (mRulesLock) { - if (mMeteredIfaces.contains(iface) && !LIMIT_GLOBAL_ALERT.equals(limitName)) { - try { - // force stats update to make sure we have numbers that - // caused alert to trigger. - mNetworkStats.forceUpdate(); - } catch (RemoteException e) { - // ignored; service lives in system_server - } - - updateNetworkEnabledLocked(); - updateNotificationsLocked(); - } + if (!LIMIT_GLOBAL_ALERT.equals(limitName)) { + mHandler.obtainMessage(MSG_LIMIT_REACHED, iface).sendToTarget(); } } }; @@ -1481,6 +1469,25 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } return true; } + case MSG_LIMIT_REACHED: { + final String iface = (String) msg.obj; + + synchronized (mRulesLock) { + if (mMeteredIfaces.contains(iface)) { + try { + // force stats update to make sure we have + // numbers that caused alert to trigger. + mNetworkStats.forceUpdate(); + } catch (RemoteException e) { + // ignored; service lives in system_server + } + + updateNetworkEnabledLocked(); + updateNotificationsLocked(); + } + } + return true; + } default: { return false; } @@ -1519,21 +1526,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } /** - * Control {@link IConnectivityManager#setPolicyDataEnable(int, boolean)}, - * dispatching only when actually changed. + * Control {@link IConnectivityManager#setPolicyDataEnable(int, boolean)}. */ private void setPolicyDataEnable(int networkType, boolean enabled) { - synchronized (mActiveNetworkEnabled) { - final boolean prevEnabled = mActiveNetworkEnabled.get(networkType, true); - if (prevEnabled == enabled) return; - - try { - mConnManager.setPolicyDataEnable(networkType, enabled); - } catch (RemoteException e) { - // ignored; service lives in system_server - } - - mActiveNetworkEnabled.put(networkType, enabled); + try { + mConnManager.setPolicyDataEnable(networkType, enabled); + } catch (RemoteException e) { + // ignored; service lives in system_server } } diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java index 494c655ba048..77b0d96f4242 100644 --- a/services/java/com/android/server/net/NetworkStatsService.java +++ b/services/java/com/android/server/net/NetworkStatsService.java @@ -152,10 +152,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private static final String TAG_NETSTATS_ERROR = "netstats_error"; - private static final String DEV = "dev"; - private static final String XT = "xt"; - private static final String UID = "uid"; - private final Context mContext; private final INetworkManagementService mNetworkManager; private final IAlarmManager mAlarmManager; @@ -278,6 +274,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { readNetworkXtStatsLocked(); } + // bootstrap initial stats to prevent double-counting later + bootstrapStats(); + // watch for network interfaces to be claimed final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION_IMMEDIATE); mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler); @@ -311,9 +310,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { registerPollAlarmLocked(); registerGlobalAlert(); - // bootstrap initial stats to prevent double-counting later - bootstrapStats(); - mDropBox = (DropBoxManager) mContext.getSystemService(Context.DROPBOX_SERVICE); } @@ -837,9 +833,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // persist when enough network data has occurred final long persistNetworkDevDelta = computeStatsDelta( - mLastPersistNetworkDevSnapshot, networkDevSnapshot, true, DEV).getTotalBytes(); + mLastPersistNetworkDevSnapshot, networkDevSnapshot, true, "devp").getTotalBytes(); final long persistNetworkXtDelta = computeStatsDelta( - mLastPersistNetworkXtSnapshot, networkXtSnapshot, true, XT).getTotalBytes(); + mLastPersistNetworkXtSnapshot, networkXtSnapshot, true, "xtp").getTotalBytes(); final boolean networkOverThreshold = persistNetworkDevDelta > threshold || persistNetworkXtDelta > threshold; if (persistForce || (persistNetwork && networkOverThreshold)) { @@ -851,7 +847,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // persist when enough uid data has occurred final long persistUidDelta = computeStatsDelta( - mLastPersistUidSnapshot, uidSnapshot, true, UID).getTotalBytes(); + mLastPersistUidSnapshot, uidSnapshot, true, "uidp").getTotalBytes(); if (persistForce || (persistUid && persistUidDelta > threshold)) { writeUidStatsLocked(); mLastPersistUidSnapshot = uidSnapshot; @@ -880,7 +876,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final HashSet<String> unknownIface = Sets.newHashSet(); final NetworkStats delta = computeStatsDelta( - mLastPollNetworkDevSnapshot, networkDevSnapshot, false, DEV); + mLastPollNetworkDevSnapshot, networkDevSnapshot, false, "dev"); final long timeStart = currentTime - delta.getElapsedRealtime(); NetworkStats.Entry entry = null; @@ -910,7 +906,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final HashSet<String> unknownIface = Sets.newHashSet(); final NetworkStats delta = computeStatsDelta( - mLastPollNetworkXtSnapshot, networkXtSnapshot, false, XT); + mLastPollNetworkXtSnapshot, networkXtSnapshot, false, "xt"); final long timeStart = currentTime - delta.getElapsedRealtime(); NetworkStats.Entry entry = null; @@ -940,9 +936,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { ensureUidStatsLoadedLocked(); final NetworkStats delta = computeStatsDelta( - mLastPollUidSnapshot, uidSnapshot, false, UID); + mLastPollUidSnapshot, uidSnapshot, false, "uid"); final NetworkStats operationsDelta = computeStatsDelta( - mLastPollOperationsSnapshot, mOperations, false, UID); + mLastPollOperationsSnapshot, mOperations, false, "uidop"); final long timeStart = currentTime - delta.getElapsedRealtime(); NetworkStats.Entry entry = null; @@ -971,8 +967,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } mLastPollUidSnapshot = uidSnapshot; - mLastPollOperationsSnapshot = mOperations; - mOperations = new NetworkStats(0L, 10); + mLastPollOperationsSnapshot = mOperations.clone(); } /** @@ -1516,7 +1511,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // record error for debugging final StringBuilder builder = new StringBuilder(); - builder.append("found non-monotonic " + type + "values at left[" + e.leftIndex + builder.append("found non-monotonic " + type + " values at left[" + e.leftIndex + "] - right[" + e.rightIndex + "]\n"); builder.append("left=").append(e.left).append('\n'); builder.append("right=").append(e.right).append('\n'); diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java index 131f11c19fbd..8fc9a70faad9 100644 --- a/services/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java @@ -88,13 +88,14 @@ class ScreenRotationAnimation { 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/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp index d2d2d8baa066..c2c6b4d469be 100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp @@ -478,8 +478,9 @@ status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection if (ns < 0) return BAD_VALUE; - if (ns == 0) { - ns = sensor->getSensor().getMinDelayNs(); + nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs(); + if (ns < minDelayNs) { + ns = minDelayNs; } if (ns < MINIMUM_EVENTS_PERIOD) diff --git a/services/surfaceflinger/LayerScreenshot.cpp b/services/surfaceflinger/LayerScreenshot.cpp index e30ccbf6bfbb..68e66606ed1f 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 @@ LayerScreenshot::~LayerScreenshot() } } +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 e3a2b1975215..ab9004741fca 100644 --- a/services/surfaceflinger/LayerScreenshot.h +++ b/services/surfaceflinger/LayerScreenshot.h @@ -41,12 +41,18 @@ public: 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 a6d4147c1952..1b00e9380a62 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1217,23 +1217,25 @@ void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state, sp<Client> client( static_cast<Client *>(s.client.get()) ); transactionFlags |= setClientStateLocked(client, s.state); } + if (transactionFlags) { + // this triggers the transaction setTransactionFlags(transactionFlags); - } - // if this is a synchronous transaction, wait for it to take effect before - // returning. - if (flags & eSynchronous) { - mTransationPending = true; - } - while (mTransationPending) { - status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); - if (CC_UNLIKELY(err != NO_ERROR)) { - // just in case something goes wrong in SF, return to the - // called after a few seconds. - LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); - mTransationPending = false; - break; + // if this is a synchronous transaction, wait for it to take effect + // before returning. + if (flags & eSynchronous) { + mTransationPending = true; + } + while (mTransationPending) { + status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); + if (CC_UNLIKELY(err != NO_ERROR)) { + // just in case something goes wrong in SF, return to the + // called after a few seconds. + LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); + mTransationPending = false; + break; + } } } } @@ -1360,11 +1362,6 @@ sp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface( 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 ea5bfa718f32..17028dbb64fa 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -186,6 +186,8 @@ public: 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 @@ private: 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/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java index 34f88489ed6a..f2ccb5bf016e 100644 --- a/telephony/java/android/telephony/PhoneNumberUtils.java +++ b/telephony/java/android/telephony/PhoneNumberUtils.java @@ -1513,14 +1513,65 @@ public class PhoneNumberUtils static final int MIN_MATCH = 7; /** - * isEmergencyNumber: checks a given number against the list of - * emergency numbers provided by the RIL and SIM card. + * Checks a given number against the list of + * emergency numbers provided by the RIL and SIM card. * * @param number the number to look up. - * @return if the number is in the list of emergency numbers - * listed in the ril / sim, then return true, otherwise false. + * @return true if the number is in the list of emergency numbers + * listed in the RIL / SIM, otherwise return false. */ public static boolean isEmergencyNumber(String number) { + // Return true only if the specified number *exactly* matches + // one of the emergency numbers listed by the RIL / SIM. + return isEmergencyNumberInternal(number, true /* useExactMatch */); + } + + /** + * Checks if given number might *potentially* result in + * a call to an emergency service on the current network. + * + * Specifically, this method will return true if the specified number + * is an emergency number according to the list managed by the RIL or + * SIM, *or* if the specified number simply starts with the same + * digits as any of the emergency numbers listed in the RIL / SIM. + * + * This method is intended for internal use by the phone app when + * deciding whether to allow ACTION_CALL intents from 3rd party apps + * (where we're required to *not* allow emergency calls to be placed.) + * + * @param number the number to look up. + * @return true if the number is in the list of emergency numbers + * listed in the RIL / SIM, *or* if the number starts with the + * same digits as any of those emergency numbers. + * + * @hide + */ + public static boolean isPotentialEmergencyNumber(String number) { + // Check against the emergency numbers listed by the RIL / SIM, + // and *don't* require an exact match. + return isEmergencyNumberInternal(number, false /* useExactMatch */); + } + + /** + * Helper function for isEmergencyNumber(String) and + * isPotentialEmergencyNumber(String). + * + * @param number the number to look up. + * + * @param useExactMatch if true, consider a number to be an emergency + * number only if it *exactly* matches a number listed in + * the RIL / SIM. If false, a number is considered to be an + * emergency number if it simply starts with the same digits + * as any of the emergency numbers listed in the RIL / SIM. + * (Setting useExactMatch to false allows you to identify + * number that could *potentially* result in emergency calls + * since many networks will actually ignore trailing digits + * after a valid emergency number.) + * + * @return true if the number is in the list of emergency numbers + * listed in the RIL / sim, otherwise return false. + */ + private static boolean isEmergencyNumberInternal(String number, boolean useExactMatch) { // If the number passed in is null, just return false: if (number == null) return false; @@ -1540,16 +1591,26 @@ public class PhoneNumberUtils // searches through the comma-separated list for a match, // return true if one is found. for (String emergencyNum : numbers.split(",")) { - if (number.startsWith(emergencyNum)) { - return true; + if (useExactMatch) { + if (number.equals(emergencyNum)) { + return true; + } + } else { + if (number.startsWith(emergencyNum)) { + return true; + } } } // no matches found against the list! return false; } - //no ecclist system property, so use our own list. - return (number.startsWith("112") || number.startsWith("911")); + // No ecclist system property, so use our own list. + if (useExactMatch) { + return (number.equals("112") || number.equals("911")); + } else { + return (number.startsWith("112") || number.startsWith("911")); + } } /** @@ -1559,31 +1620,81 @@ public class PhoneNumberUtils * @param defaultCountryIso the specific country which the number should be checked against * @return if the number is an emergency number for the specific country, then return true, * otherwise false + * * @hide */ public static boolean isEmergencyNumber(String number, String defaultCountryIso) { - PhoneNumberUtil util = PhoneNumberUtil.getInstance(); - try { - PhoneNumber pn = util.parse(number, defaultCountryIso); - // libphonenumber guarantees short numbers such as emergency numbers are classified as - // invalid. Therefore, if the number passes the validation test, we believe it is not an - // emergency number. - // TODO: Compare against a list of country-specific known emergency numbers instead, once - // that has been collected. - if (util.isValidNumber(pn)) { - return false; - } else if ("BR".equalsIgnoreCase(defaultCountryIso) && number.length() >= 8) { - // This is to prevent Brazilian local numbers which start with 911 being incorrectly - // classified as emergency numbers. 911 is not an emergency number in Brazil; it is also - // not possible to append additional digits to an emergency number to dial the number in - // Brazil - it won't connect. - // TODO: Clean this up once a list of country-specific known emergency numbers is - // collected. - return false; - } - } catch (NumberParseException e) { - } - return isEmergencyNumber(number); + return isEmergencyNumberInternal(number, + defaultCountryIso, + true /* useExactMatch */); + } + + /** + * Checks if a given number might *potentially* result in a call to an + * emergency service, for a specific country. + * + * Specifically, this method will return true if the specified number + * is an emergency number in the specified country, *or* if the number + * simply starts with the same digits as any emergency number for that + * country. + * + * This method is intended for internal use by the phone app when + * deciding whether to allow ACTION_CALL intents from 3rd party apps + * (where we're required to *not* allow emergency calls to be placed.) + * + * @param number the number to look up. + * @param defaultCountryIso the specific country which the number should be checked against + * @return true if the number is an emergency number for the specific + * country, *or* if the number starts with the same digits as + * any of those emergency numbers. + * + * @hide + */ + public static boolean isPotentialEmergencyNumber(String number, String defaultCountryIso) { + return isEmergencyNumberInternal(number, + defaultCountryIso, + false /* useExactMatch */); + } + + /** + * Helper function for isEmergencyNumber(String, String) and + * isPotentialEmergencyNumber(String, String). + * + * @param number the number to look up. + * @param defaultCountryIso the specific country which the number should be checked against + * @param useExactMatch if true, consider a number to be an emergency + * number only if it *exactly* matches a number listed in + * the RIL / SIM. If false, a number is considered to be an + * emergency number if it simply starts with the same digits + * as any of the emergency numbers listed in the RIL / SIM. + * + * @return true if the number is an emergency number for the specified country. + */ + private static boolean isEmergencyNumberInternal(String number, + String defaultCountryIso, + boolean useExactMatch) { + PhoneNumberUtil util = PhoneNumberUtil.getInstance(); + try { + PhoneNumber pn = util.parse(number, defaultCountryIso); + // libphonenumber guarantees short numbers such as emergency numbers are classified as + // invalid. Therefore, if the number passes the validation test, we believe it is not an + // emergency number. + // TODO: Compare against a list of country-specific known emergency numbers instead, once + // that has been collected. + if (util.isValidNumber(pn)) { + return false; + } else if ("BR".equalsIgnoreCase(defaultCountryIso) && number.length() >= 8) { + // This is to prevent Brazilian local numbers which start with 911 being incorrectly + // classified as emergency numbers. 911 is not an emergency number in Brazil; it is also + // not possible to append additional digits to an emergency number to dial the number in + // Brazil - it won't connect. + // TODO: Clean this up once a list of country-specific known emergency numbers is + // collected. + return false; + } + } catch (NumberParseException e) { + } + return isEmergencyNumberInternal(number, useExactMatch); } /** @@ -1592,12 +1703,66 @@ public class PhoneNumberUtils * * @param number the number to look up. * @param context the specific context which the number should be checked against - * @return if a phone number is an emergency number for a local country, based on the - * CountryDetector. + * @return true if the specified number is an emergency number for a local country, based on the + * CountryDetector. + * * @see android.location.CountryDetector * @hide */ public static boolean isLocalEmergencyNumber(String number, Context context) { + return isLocalEmergencyNumberInternal(number, + context, + true /* useExactMatch */); + } + + /** + * Checks if a given number might *potentially* result in a call to an + * emergency service, for the country that the user is in. The current + * country is determined using the CountryDetector. + * + * Specifically, this method will return true if the specified number + * is an emergency number in the current country, *or* if the number + * simply starts with the same digits as any emergency number for the + * current country. + * + * This method is intended for internal use by the phone app when + * deciding whether to allow ACTION_CALL intents from 3rd party apps + * (where we're required to *not* allow emergency calls to be placed.) + * + * @param number the number to look up. + * @param context the specific context which the number should be checked against + * @return true if the specified number is an emergency number for a local country, based on the + * CountryDetector. + * + * @see android.location.CountryDetector + * @hide + */ + public static boolean isPotentialLocalEmergencyNumber(String number, Context context) { + return isLocalEmergencyNumberInternal(number, + context, + false /* useExactMatch */); + } + + /** + * Helper function for isLocalEmergencyNumber() and + * isPotentialLocalEmergencyNumber(). + * + * @param number the number to look up. + * @param context the specific context which the number should be checked against + * @param useExactMatch if true, consider a number to be an emergency + * number only if it *exactly* matches a number listed in + * the RIL / SIM. If false, a number is considered to be an + * emergency number if it simply starts with the same digits + * as any of the emergency numbers listed in the RIL / SIM. + * + * @return true if the specified number is an emergency number for a + * local country, based on the CountryDetector. + * + * @see android.location.CountryDetector + */ + private static boolean isLocalEmergencyNumberInternal(String number, + Context context, + boolean useExactMatch) { String countryIso; CountryDetector detector = (CountryDetector) context.getSystemService( Context.COUNTRY_DETECTOR); @@ -1609,7 +1774,7 @@ public class PhoneNumberUtils Log.w(LOG_TAG, "No CountryDetector; falling back to countryIso based on locale: " + countryIso); } - return isEmergencyNumber(number, countryIso); + return isEmergencyNumberInternal(number, countryIso, useExactMatch); } /** diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java index fc8a145fcd71..141074717c21 100644 --- a/telephony/java/android/telephony/SmsMessage.java +++ b/telephony/java/android/telephony/SmsMessage.java @@ -291,12 +291,31 @@ public class SmsMessage { // flexibly... int limit; - if (ted.msgCount > 1) { - limit = (ted.codeUnitSize == ENCODING_7BIT) ? - MAX_USER_DATA_SEPTETS_WITH_HEADER : MAX_USER_DATA_BYTES_WITH_HEADER; + if (ted.codeUnitSize == ENCODING_7BIT) { + int udhLength; + if (ted.languageTable != 0 && ted.languageShiftTable != 0) { + udhLength = GsmAlphabet.UDH_SEPTET_COST_TWO_SHIFT_TABLES; + } else if (ted.languageTable != 0 || ted.languageShiftTable != 0) { + udhLength = GsmAlphabet.UDH_SEPTET_COST_ONE_SHIFT_TABLE; + } else { + udhLength = 0; + } + + if (ted.msgCount > 1) { + udhLength += GsmAlphabet.UDH_SEPTET_COST_CONCATENATED_MESSAGE; + } + + if (udhLength != 0) { + udhLength += GsmAlphabet.UDH_SEPTET_COST_LENGTH; + } + + limit = MAX_USER_DATA_SEPTETS - udhLength; } else { - limit = (ted.codeUnitSize == ENCODING_7BIT) ? - MAX_USER_DATA_SEPTETS : MAX_USER_DATA_BYTES; + if (ted.msgCount > 1) { + limit = MAX_USER_DATA_BYTES_WITH_HEADER; + } else { + limit = MAX_USER_DATA_BYTES; + } } int pos = 0; // Index in code units. diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java index 171b3714d527..3dd57ee742f2 100644 --- a/telephony/java/com/android/internal/telephony/CallManager.java +++ b/telephony/java/com/android/internal/telephony/CallManager.java @@ -379,18 +379,19 @@ public final class CallManager { 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/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java index 5b13603a924f..410e9614e9dd 100644 --- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java @@ -167,7 +167,9 @@ public abstract class DataConnectionTracker extends Handler { // independent of mInternalDataEnabled and requests for APN access // persisted protected boolean mUserDataEnabled = true; - protected boolean mPolicyDataEnabled = true; + + // TODO: move away from static state once 5587429 is fixed. + protected static boolean sPolicyDataEnabled = true; private boolean[] dataEnabled = new boolean[APN_NUM_TYPES]; @@ -766,7 +768,7 @@ public abstract class DataConnectionTracker extends Handler { public boolean getAnyDataEnabled() { final boolean result; synchronized (mDataEnabledLock) { - result = (mInternalDataEnabled && mUserDataEnabled && mPolicyDataEnabled + result = (mInternalDataEnabled && mUserDataEnabled && sPolicyDataEnabled && (enabledCount != 0)); } if (!result && DBG) log("getAnyDataEnabled " + result); @@ -1132,8 +1134,8 @@ public abstract class DataConnectionTracker extends Handler { protected void onSetPolicyDataEnabled(boolean enabled) { synchronized (mDataEnabledLock) { final boolean prevEnabled = getAnyDataEnabled(); - if (mPolicyDataEnabled != enabled) { - mPolicyDataEnabled = enabled; + if (sPolicyDataEnabled != enabled) { + sPolicyDataEnabled = enabled; if (prevEnabled != getAnyDataEnabled()) { if (!prevEnabled) { resetAllRetryCounts(); diff --git a/telephony/java/com/android/internal/telephony/GsmAlphabet.java b/telephony/java/com/android/internal/telephony/GsmAlphabet.java index 2e998490e875..25647ac8ad1f 100644 --- a/telephony/java/com/android/internal/telephony/GsmAlphabet.java +++ b/telephony/java/com/android/internal/telephony/GsmAlphabet.java @@ -60,25 +60,25 @@ public class GsmAlphabet { * all combinations of header elements below will have at least one free bit * when padding to the nearest septet boundary. */ - private static final int UDH_SEPTET_COST_LENGTH = 1; + public static final int UDH_SEPTET_COST_LENGTH = 1; /** * Using a non-default language locking shift table OR single shift table * requires a user data header of 3 octets, or 4 septets, plus UDH length. */ - private static final int UDH_SEPTET_COST_ONE_SHIFT_TABLE = 4; + public static final int UDH_SEPTET_COST_ONE_SHIFT_TABLE = 4; /** * Using a non-default language locking shift table AND single shift table * requires a user data header of 6 octets, or 7 septets, plus UDH length. */ - private static final int UDH_SEPTET_COST_TWO_SHIFT_TABLES = 7; + public static final int UDH_SEPTET_COST_TWO_SHIFT_TABLES = 7; /** * Multi-part messages require a user data header of 5 octets, or 6 septets, * plus UDH length. */ - private static final int UDH_SEPTET_COST_CONCATENATED_MESSAGE = 6; + public static final int UDH_SEPTET_COST_CONCATENATED_MESSAGE = 6; /** * Converts a char to a GSM 7 bit table index. diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index 865caf63224c..7cd01a167d78 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -549,7 +549,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { @Override public boolean getAnyDataEnabled() { synchronized (mDataEnabledLock) { - if (!(mInternalDataEnabled && mUserDataEnabled && mPolicyDataEnabled)) return false; + if (!(mInternalDataEnabled && mUserDataEnabled && sPolicyDataEnabled)) return false; for (ApnContext apnContext : mApnContexts.values()) { // Make sure we dont have a context that going down // and is explicitly disabled. diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java index 41a719e1b64d..595066957435 100644 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java +++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java @@ -16,11 +16,14 @@ package com.android.internal.telephony; +import android.telephony.TelephonyManager; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; + import com.android.internal.telephony.gsm.SmsMessage; import com.android.internal.util.HexDump; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; +import java.util.ArrayList; public class GsmSmsTest extends AndroidTestCase { @@ -232,6 +235,110 @@ public class GsmSmsTest extends AndroidTestCase { }; @SmallTest + public void testFragmentText() throws Exception { + boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() == + TelephonyManager.PHONE_TYPE_GSM); + + // Valid 160 character 7-bit text. + String text = "123456789012345678901234567890123456789012345678901234567890" + + "1234567890123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890"; + SmsMessageBase.TextEncodingDetails ted = SmsMessage.calculateLength(text, false); + assertEquals(1, ted.msgCount); + assertEquals(160, ted.codeUnitCount); + assertEquals(1, ted.codeUnitSize); + assertEquals(0, ted.languageTable); + assertEquals(0, ted.languageShiftTable); + if (isGsmPhone) { + ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); + assertEquals(1, fragments.size()); + } + + // Valid 161 character 7-bit text. + text = "123456789012345678901234567890123456789012345678901234567890" + + "1234567890123456789012345678901234567890123456789012345678901234567890" + + "1234567890123456789012345678901"; + ted = SmsMessage.calculateLength(text, false); + assertEquals(2, ted.msgCount); + assertEquals(161, ted.codeUnitCount); + assertEquals(1, ted.codeUnitSize); + assertEquals(0, ted.languageTable); + assertEquals(0, ted.languageShiftTable); + if (isGsmPhone) { + ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); + assertEquals(2, fragments.size()); + assertEquals(text, fragments.get(0) + fragments.get(1)); + assertEquals(153, fragments.get(0).length()); + assertEquals(8, fragments.get(1).length()); + } + } + + @SmallTest + public void testFragmentTurkishText() throws Exception { + boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() == + TelephonyManager.PHONE_TYPE_GSM); + + int[] oldTables = GsmAlphabet.getEnabledSingleShiftTables(); + int[] turkishTable = { 1 }; + GsmAlphabet.setEnabledSingleShiftTables(turkishTable); + + // Valid 77 character text with Turkish characters. + String text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" + + "ĞŞİğşıĞŞİğşıĞŞİğş"; + SmsMessageBase.TextEncodingDetails ted = SmsMessage.calculateLength(text, false); + assertEquals(1, ted.msgCount); + assertEquals(154, ted.codeUnitCount); + assertEquals(1, ted.codeUnitSize); + assertEquals(0, ted.languageTable); + assertEquals(1, ted.languageShiftTable); + if (isGsmPhone) { + ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); + assertEquals(1, fragments.size()); + assertEquals(text, fragments.get(0)); + assertEquals(77, fragments.get(0).length()); + } + + // Valid 78 character text with Turkish characters. + text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" + + "ĞŞİğşıĞŞİğşıĞŞİğşı"; + ted = SmsMessage.calculateLength(text, false); + assertEquals(2, ted.msgCount); + assertEquals(156, ted.codeUnitCount); + assertEquals(1, ted.codeUnitSize); + assertEquals(0, ted.languageTable); + assertEquals(1, ted.languageShiftTable); + if (isGsmPhone) { + ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); + assertEquals(2, fragments.size()); + assertEquals(text, fragments.get(0) + fragments.get(1)); + assertEquals(74, fragments.get(0).length()); + assertEquals(4, fragments.get(1).length()); + } + + // Valid 160 character text with Turkish characters. + text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" + + "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğ" + + "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı"; + ted = SmsMessage.calculateLength(text, false); + assertEquals(3, ted.msgCount); + assertEquals(320, ted.codeUnitCount); + assertEquals(1, ted.codeUnitSize); + assertEquals(0, ted.languageTable); + assertEquals(1, ted.languageShiftTable); + if (isGsmPhone) { + ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); + assertEquals(3, fragments.size()); + assertEquals(text, fragments.get(0) + fragments.get(1) + fragments.get(2)); + assertEquals(74, fragments.get(0).length()); + assertEquals(74, fragments.get(1).length()); + assertEquals(12, fragments.get(2).length()); + } + + GsmAlphabet.setEnabledSingleShiftTables(oldTables); + } + + + @SmallTest public void testDecode() throws Exception { decodeSingle(0); // default table decodeSingle(1); // Turkish locking shift table diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java index e2349afbf85e..d34a7c50b980 100644 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java +++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java @@ -550,21 +550,51 @@ public class PhoneNumberUtilsTest extends AndroidTestCase { } @SmallTest public void testIsEmergencyNumber() { - assertTrue(PhoneNumberUtils.isEmergencyNumber("911", "US")); - assertTrue(PhoneNumberUtils.isEmergencyNumber("112", "US")); - // The next two numbers are not valid phone numbers in the US, but can be used to trick the - // system to dial 911 and 112, which are emergency numbers in the US. For the purpose of - // addressing that, they are also classified as emergency numbers in the US. - assertTrue(PhoneNumberUtils.isEmergencyNumber("91112345", "US")); - assertTrue(PhoneNumberUtils.isEmergencyNumber("11212345", "US")); - // A valid mobile phone number from Singapore shouldn't be classified as an emergency number - // in Singapore, as 911 is not an emergency number there. - assertFalse(PhoneNumberUtils.isEmergencyNumber("91121234", "SG")); - // A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number - // in Brazil, as 112 is not an emergency number there. - assertFalse(PhoneNumberUtils.isEmergencyNumber("1121234567", "BR")); - // A valid local phone number from Brazil shouldn't be classified as an emergency number in - // Brazil. - assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345", "BR")); + // There are two parallel sets of tests here: one for the + // regular isEmergencyNumber() method, and the other for + // isPotentialEmergencyNumber(). + // + // (The difference is that isEmergencyNumber() will return true + // only if the specified number exactly matches an actual + // emergency number, but isPotentialEmergencyNumber() will + // return true if the specified number simply starts with the + // same digits as any actual emergency number.) + + // Tests for isEmergencyNumber(): + assertTrue(PhoneNumberUtils.isEmergencyNumber("911", "US")); + assertTrue(PhoneNumberUtils.isEmergencyNumber("112", "US")); + // The next two numbers are not valid phone numbers in the US, + // so do not count as emergency numbers (but they *are* "potential" + // emergency numbers; see below.) + assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345", "US")); + assertFalse(PhoneNumberUtils.isEmergencyNumber("11212345", "US")); + // A valid mobile phone number from Singapore shouldn't be classified as an emergency number + // in Singapore, as 911 is not an emergency number there. + assertFalse(PhoneNumberUtils.isEmergencyNumber("91121234", "SG")); + // A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number + // in Brazil, as 112 is not an emergency number there. + assertFalse(PhoneNumberUtils.isEmergencyNumber("1121234567", "BR")); + // A valid local phone number from Brazil shouldn't be classified as an emergency number in + // Brazil. + assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345", "BR")); + + // Tests for isPotentialEmergencyNumber(): + // These first two are obviously emergency numbers: + assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("911", "US")); + assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("112", "US")); + // The next two numbers are not valid phone numbers in the US, but can be used to trick the + // system to dial 911 and 112, which are emergency numbers in the US. For the purpose of + // addressing that, they are also classified as "potential" emergency numbers in the US. + assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("91112345", "US")); + assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("11212345", "US")); + // A valid mobile phone number from Singapore shouldn't be classified as an emergency number + // in Singapore, as 911 is not an emergency number there. + assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("91121234", "SG")); + // A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number + // in Brazil, as 112 is not an emergency number there. + assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("1121234567", "BR")); + // A valid local phone number from Brazil shouldn't be classified as an emergency number in + // Brazil. + assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("91112345", "BR")); } } diff --git a/tests/FrameworkPerf/AndroidManifest.xml b/tests/FrameworkPerf/AndroidManifest.xml index aa663f3b78f2..e88f4fb6e02f 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 62b1a7ae36a5..781264881ceb 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 39799024f41f..175f227f7e0f 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; + TestConnection mCurConnection; + boolean mConnectionBound; - class RunResult { - final String name; - final String fgLongName; - final String bgLongName; - final long fgTime; - final long fgOps; - final long bgTime; - final long bgOps; + final ArrayList<RunResult> mResults = new ArrayList<RunResult>(); + + class TestConnection implements ServiceConnection, IBinder.DeathRecipient { + Messenger mService; + boolean mLinked; - RunResult(TestRunner op) { - name = op.getName(); - fgLongName = op.getForegroundLongName(); - bgLongName = op.getBackgroundLongName(); - fgTime = op.getForegroundTime(); - fgOps = op.getForegroundOps(); - bgTime = op.getBackgroundTime(); - bgOps = op.getBackgroundOps(); + @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(); + } } - float getFgMsPerOp() { - return fgOps != 0 ? (fgTime / (float)fgOps) : 0; + @Override public void onServiceDisconnected(ComponentName name) { } - float getBgMsPerOp() { - return bgOps != 0 ? (bgTime / (float)bgOps) : 0; + @Override public void binderDied() { + cleanup(); + connectionDied(this); + } + + void cleanup() { + if (mLinked) { + mLinked = false; + mService.getBinder().unlinkToDeath(this, 0); + } } } - final ArrayList<RunResult> mResults = new ArrayList<RunResult>(); + 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 @@ public class FrameworkPerfActivity extends Activity } }); mStopButton.setEnabled(false); + mLocalCheckBox = (CheckBox)findViewById(R.id.local); mLog = (TextView)findViewById(R.id.log); @@ -262,11 +195,13 @@ public class FrameworkPerfActivity extends Activity @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 @@ public class FrameworkPerfActivity extends Activity } } - 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) { + 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 = mFgTest; - bgOp = mAvailOps[mCurOpIndex]; + 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 { - // Skip null test. - if (mCurOpIndex == 0) { - mCurOpIndex = 1; + mCurOpIndex++; + if (mCurOpIndex >= TestService.mAvailOps.length) { + log("Finished"); + stopRunning(); + return; } - 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(); + 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"); } - 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(); } - }); + 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 @@ public class FrameworkPerfActivity extends Activity mStarted = true; mStartButton.setEnabled(false); mStopButton.setEnabled(true); + mLocalCheckBox.setEnabled(false); mTestTime.setEnabled(false); mFgSpinner.setEnabled(false); mBgSpinner.setEnabled(false); @@ -371,9 +383,11 @@ public class FrameworkPerfActivity extends Activity 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 @@ public class FrameworkPerfActivity extends Activity 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 000000000000..09c6be8343ad --- /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 000000000000..d14e434c90df --- /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 000000000000..f2f7c5675bcf --- /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 000000000000..3d939bdf6a80 --- /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(); + } + } +} diff --git a/wifi/java/android/net/wifi/WifiApConfigStore.java b/wifi/java/android/net/wifi/WifiApConfigStore.java index bb5427d01879..0531ca376149 100644 --- a/wifi/java/android/net/wifi/WifiApConfigStore.java +++ b/wifi/java/android/net/wifi/WifiApConfigStore.java @@ -19,11 +19,16 @@ package android.net.wifi; import android.content.Context; import android.net.wifi.WifiConfiguration.KeyMgmt; import android.os.Environment; -import android.os.Message; import android.os.Handler; -import android.os.HandlerThread; +import android.os.Message; +import android.os.Messenger; import android.util.Log; +import com.android.internal.util.AsyncChannel; +import com.android.internal.R; +import com.android.internal.util.State; +import com.android.internal.util.StateMachine; + import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; @@ -34,16 +39,13 @@ import java.io.IOException; import java.net.InetAddress; import java.util.UUID; -import com.android.internal.R; - - /** * Provides API to the WifiStateMachine for doing read/write access * to soft access point configuration */ -class WifiApConfigStore { +class WifiApConfigStore extends StateMachine { - private static Context sContext; + private Context mContext; private static final String TAG = "WifiApConfigStore"; private static final String AP_CONFIG_FILE = Environment.getDataDirectory() + @@ -51,131 +53,160 @@ class WifiApConfigStore { private static final int AP_CONFIG_FILE_VERSION = 1; - private static WifiConfiguration sApConfig = new WifiConfiguration(); - private static final Object sApConfigLock = new Object(); + private State mDefaultState = new DefaultState(); + private State mInactiveState = new InactiveState(); + private State mActiveState = new ActiveState(); + + private WifiConfiguration mWifiApConfig = null; + private AsyncChannel mReplyChannel = new AsyncChannel(); - private static FileReadWriteHandler sFileReadWriteHandler; - private static final int READ_AP_CONFIG = 1; - private static final int WRITE_AP_CONFIG = 2; + WifiApConfigStore(Context context, Handler target) { + super(TAG, target.getLooper()); - static void initialize(Context context) { - sContext = context; + mContext = context; + addState(mDefaultState); + addState(mInactiveState, mDefaultState); + addState(mActiveState, mDefaultState); - /* File operations happen on a seperate thread */ - HandlerThread configThread = new HandlerThread("WifiApConfigStore"); - configThread.start(); - sFileReadWriteHandler = new FileReadWriteHandler(configThread.getLooper()); - Message.obtain(sFileReadWriteHandler, READ_AP_CONFIG).sendToTarget(); + setInitialState(mInactiveState); } + public static WifiApConfigStore makeWifiApConfigStore(Context context, Handler target) { + WifiApConfigStore s = new WifiApConfigStore(context, target); + s.start(); + return s; + } - static void setApConfiguration(WifiConfiguration config) { - synchronized (sApConfigLock) { - sApConfig = config; + class DefaultState extends State { + public boolean processMessage(Message message) { + switch (message.what) { + case WifiStateMachine.CMD_SET_AP_CONFIG: + case WifiStateMachine.CMD_SET_AP_CONFIG_COMPLETED: + Log.e(TAG, "Unexpected message: " + message); + break; + case WifiStateMachine.CMD_REQUEST_AP_CONFIG: + mReplyChannel.replyToMessage(message, + WifiStateMachine.CMD_RESPONSE_AP_CONFIG, mWifiApConfig); + break; + default: + Log.e(TAG, "Failed to handle " + message); + break; + } + return HANDLED; } - Message.obtain(sFileReadWriteHandler, WRITE_AP_CONFIG, new WifiConfiguration(config)) - .sendToTarget(); } - static WifiConfiguration getApConfiguration() { - synchronized (sApConfigLock) { - return new WifiConfiguration(sApConfig); + class InactiveState extends State { + public boolean processMessage(Message message) { + switch (message.what) { + case WifiStateMachine.CMD_SET_AP_CONFIG: + mWifiApConfig = (WifiConfiguration) message.obj; + transitionTo(mActiveState); + break; + default: + return NOT_HANDLED; + } + return HANDLED; } } - /** - * File read/write handler - */ - private static class FileReadWriteHandler extends Handler { - - public FileReadWriteHandler(android.os.Looper looper) { - super(looper); + class ActiveState extends State { + public void enter() { + new Thread(new Runnable() { + public void run() { + writeApConfiguration(mWifiApConfig); + sendMessage(WifiStateMachine.CMD_SET_AP_CONFIG_COMPLETED); + } + }).start(); } - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case WRITE_AP_CONFIG: - writeApConfiguration((WifiConfiguration) msg.obj); + public boolean processMessage(Message message) { + switch (message.what) { + //TODO: have feedback to the user when we do this + //to indicate the write is currently in progress + case WifiStateMachine.CMD_SET_AP_CONFIG: + deferMessage(message); break; - case READ_AP_CONFIG: - readApConfiguration(); + case WifiStateMachine.CMD_SET_AP_CONFIG_COMPLETED: + transitionTo(mInactiveState); break; default: - Log.e(TAG, "Unknown command in FileReadWriteHandler: " + msg); - break; + return NOT_HANDLED; } + return HANDLED; } + } - private static void writeApConfiguration(final WifiConfiguration config) { - DataOutputStream out = null; - try { - out = new DataOutputStream(new BufferedOutputStream( - new FileOutputStream(AP_CONFIG_FILE))); - - out.writeInt(AP_CONFIG_FILE_VERSION); - out.writeUTF(config.SSID); - int authType = config.getAuthType(); - out.writeInt(authType); - if(authType != KeyMgmt.NONE) { - out.writeUTF(config.preSharedKey); - } - } catch (IOException e) { - Log.e(TAG, "Error writing hotspot configuration" + e); - } finally { - if (out != null) { - try { - out.close(); - } catch (IOException e) {} - } - } - } + void loadApConfiguration() { + DataInputStream in = null; + try { + WifiConfiguration config = new WifiConfiguration(); + in = new DataInputStream(new BufferedInputStream(new FileInputStream( + AP_CONFIG_FILE))); - private static void readApConfiguration() { - DataInputStream in = null; - try { - WifiConfiguration config = new WifiConfiguration(); - in = new DataInputStream(new BufferedInputStream(new FileInputStream( - AP_CONFIG_FILE))); - - int version = in.readInt(); - if (version != 1) { - Log.e(TAG, "Bad version on hotspot configuration file, set defaults"); - setDefaultApConfiguration(); - return; - } - config.SSID = in.readUTF(); - int authType = in.readInt(); - config.allowedKeyManagement.set(authType); - if (authType != KeyMgmt.NONE) { - config.preSharedKey = in.readUTF(); - } - synchronized (sApConfigLock) { - sApConfig = config; - } - } catch (IOException ignore) { + int version = in.readInt(); + if (version != 1) { + Log.e(TAG, "Bad version on hotspot configuration file, set defaults"); setDefaultApConfiguration(); - } finally { - if (in != null) { - try { - in.close(); - } catch (IOException e) {} - } + return; + } + config.SSID = in.readUTF(); + int authType = in.readInt(); + config.allowedKeyManagement.set(authType); + if (authType != KeyMgmt.NONE) { + config.preSharedKey = in.readUTF(); + } + mWifiApConfig = config; + } catch (IOException ignore) { + setDefaultApConfiguration(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) {} } } + } - /* Generate a default WPA2 based configuration with a random password. - We are changing the Wifi Ap configuration storage from secure settings to a - flat file accessible only by the system. A WPA2 based default configuration - will keep the device secure after the update */ - private static void setDefaultApConfiguration() { - WifiConfiguration config = new WifiConfiguration(); - config.SSID = sContext.getString(R.string.wifi_tether_configure_ssid_default); - config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK); - String randomUUID = UUID.randomUUID().toString(); - //first 12 chars from xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx - config.preSharedKey = randomUUID.substring(0, 8) + randomUUID.substring(9,13); - setApConfiguration(config); + Messenger getMessenger() { + return new Messenger(getHandler()); + } + + private void writeApConfiguration(final WifiConfiguration config) { + DataOutputStream out = null; + try { + out = new DataOutputStream(new BufferedOutputStream( + new FileOutputStream(AP_CONFIG_FILE))); + + out.writeInt(AP_CONFIG_FILE_VERSION); + out.writeUTF(config.SSID); + int authType = config.getAuthType(); + out.writeInt(authType); + if(authType != KeyMgmt.NONE) { + out.writeUTF(config.preSharedKey); + } + } catch (IOException e) { + Log.e(TAG, "Error writing hotspot configuration" + e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) {} + } } } + + /* Generate a default WPA2 based configuration with a random password. + We are changing the Wifi Ap configuration storage from secure settings to a + flat file accessible only by the system. A WPA2 based default configuration + will keep the device secure after the update */ + private void setDefaultApConfiguration() { + WifiConfiguration config = new WifiConfiguration(); + config.SSID = mContext.getString(R.string.wifi_tether_configure_ssid_default); + config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK); + String randomUUID = UUID.randomUUID().toString(); + //first 12 chars from xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx + config.preSharedKey = randomUUID.substring(0, 8) + randomUUID.substring(9,13); + sendMessage(WifiStateMachine.CMD_SET_AP_CONFIG, config); + } } diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index 00fae2ee2ddb..aadcaadaa663 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -184,6 +184,7 @@ public class WifiStateMachine extends StateMachine { private WifiP2pManager mWifiP2pManager; //Used to initiate a connection with WifiP2pService private AsyncChannel mWifiP2pChannel = new AsyncChannel(); + private AsyncChannel mWifiApConfigChannel = new AsyncChannel(); // Event log tags (must be in sync with event-log-tags) private static final int EVENTLOG_WIFI_STATE_CHANGED = 50021; @@ -233,12 +234,16 @@ public class WifiStateMachine extends StateMachine { static final int CMD_STOP_AP = BASE + 24; /* Set the soft access point configuration */ static final int CMD_SET_AP_CONFIG = BASE + 25; - /* Get the soft access point configuration */ - static final int CMD_GET_AP_CONFIG = BASE + 26; + /* Soft access point configuration set completed */ + static final int CMD_SET_AP_CONFIG_COMPLETED = BASE + 26; + /* Request the soft access point configuration */ + static final int CMD_REQUEST_AP_CONFIG = BASE + 27; + /* Response to access point configuration request */ + static final int CMD_RESPONSE_AP_CONFIG = BASE + 28; /* Set configuration on tether interface */ - static final int CMD_TETHER_INTERFACE = BASE + 27; + static final int CMD_TETHER_INTERFACE = BASE + 29; - static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE = BASE + 28; + static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE = BASE + 30; /* Supplicant commands */ /* Is supplicant alive ? */ @@ -530,6 +535,11 @@ public class WifiStateMachine extends StateMachine { mWpsStateMachine = new WpsStateMachine(context, this, getHandler()); mLinkProperties = new LinkProperties(); + WifiApConfigStore wifiApConfigStore = WifiApConfigStore.makeWifiApConfigStore( + context, getHandler()); + wifiApConfigStore.loadApConfiguration(); + mWifiApConfigChannel.connectSync(mContext, getHandler(), wifiApConfigStore.getMessenger()); + mNetworkInfo.setIsAvailable(false); mLinkProperties.clear(); mLastBssid = null; @@ -659,11 +669,11 @@ public class WifiStateMachine extends StateMachine { } public void setWifiApConfiguration(WifiConfiguration config) { - sendMessage(obtainMessage(CMD_SET_AP_CONFIG, config)); + mWifiApConfigChannel.sendMessage(CMD_SET_AP_CONFIG, config); } - public WifiConfiguration syncGetWifiApConfiguration(AsyncChannel channel) { - Message resultMsg = channel.sendMessageSynchronously(CMD_GET_AP_CONFIG); + public WifiConfiguration syncGetWifiApConfiguration() { + Message resultMsg = mWifiApConfigChannel.sendMessageSynchronously(CMD_REQUEST_AP_CONFIG); WifiConfiguration ret = (WifiConfiguration) resultMsg.obj; resultMsg.recycle(); return ret; @@ -1714,25 +1724,27 @@ public class WifiStateMachine extends StateMachine { * TODO: Add control channel setup through hostapd that allows changing config * on a running daemon */ - private boolean startSoftApWithConfig(WifiConfiguration config) { - if (config == null) { - config = WifiApConfigStore.getApConfiguration(); - } else { - WifiApConfigStore.setApConfiguration(config); - } - try { - mNwService.startAccessPoint(config, mInterfaceName, SOFTAP_IFACE); - } catch (Exception e) { - loge("Exception in softap start " + e); - try { - mNwService.stopAccessPoint(mInterfaceName); - mNwService.startAccessPoint(config, mInterfaceName, SOFTAP_IFACE); - } catch (Exception e1) { - loge("Exception in softap re-start " + e1); - return false; + private void startSoftApWithConfig(final WifiConfiguration config) { + // start hostapd on a seperate thread + new Thread(new Runnable() { + public void run() { + try { + mNwService.startAccessPoint(config, mInterfaceName, SOFTAP_IFACE); + } catch (Exception e) { + loge("Exception in softap start " + e); + try { + mNwService.stopAccessPoint(mInterfaceName); + mNwService.startAccessPoint(config, mInterfaceName, SOFTAP_IFACE); + } catch (Exception e1) { + loge("Exception in softap re-start " + e1); + sendMessage(CMD_START_AP_FAILURE); + return; + } + } + if (DBG) log("Soft AP start successful"); + sendMessage(CMD_START_AP_SUCCESS); } - } - return true; + }).start(); } /******************************************************** @@ -1775,13 +1787,6 @@ public class WifiStateMachine extends StateMachine { case CMD_ENABLE_BACKGROUND_SCAN: mEnableBackgroundScan = (message.arg1 == 1); break; - case CMD_SET_AP_CONFIG: - WifiApConfigStore.setApConfiguration((WifiConfiguration) message.obj); - break; - case CMD_GET_AP_CONFIG: - WifiConfiguration config = WifiApConfigStore.getApConfiguration(); - mReplyChannel.replyToMessage(message, message.what, config); - break; /* Discard */ case CMD_LOAD_DRIVER: case CMD_UNLOAD_DRIVER: @@ -1823,6 +1828,11 @@ public class WifiStateMachine extends StateMachine { case CMD_ENABLE_ALL_NETWORKS: case DhcpStateMachine.CMD_PRE_DHCP_ACTION: case DhcpStateMachine.CMD_POST_DHCP_ACTION: + /* Handled by WifiApConfigStore */ + case CMD_SET_AP_CONFIG: + case CMD_SET_AP_CONFIG_COMPLETED: + case CMD_REQUEST_AP_CONFIG: + case CMD_RESPONSE_AP_CONFIG: break; case WifiMonitor.DRIVER_HUNG_EVENT: setWifiEnabled(false); @@ -1856,8 +1866,6 @@ public class WifiStateMachine extends StateMachine { // 50021 wifi_state_changed (custom|1|5) EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName()); - WifiApConfigStore.initialize(mContext); - if (WifiNative.isDriverLoaded()) { transitionTo(mDriverLoadedState); } @@ -3243,21 +3251,19 @@ public class WifiStateMachine extends StateMachine { if (DBG) log(getName() + "\n"); EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName()); - final Message message = Message.obtain(getCurrentMessage()); - final WifiConfiguration config = (WifiConfiguration) message.obj; + final Message message = getCurrentMessage(); + if (message.what == CMD_START_AP) { + final WifiConfiguration config = (WifiConfiguration) message.obj; - // start hostapd on a seperate thread - new Thread(new Runnable() { - public void run() { - if (startSoftApWithConfig(config)) { - if (DBG) log("Soft AP start successful"); - sendMessage(CMD_START_AP_SUCCESS); - } else { - loge("Soft AP start failed"); - sendMessage(CMD_START_AP_FAILURE); - } + if (config == null) { + mWifiApConfigChannel.sendMessage(CMD_REQUEST_AP_CONFIG); + } else { + mWifiApConfigChannel.sendMessage(CMD_SET_AP_CONFIG, config); + startSoftApWithConfig(config); } - }).start(); + } else { + throw new RuntimeException("Illegal transition to SoftApStartingState: " + message); + } } @Override public boolean processMessage(Message message) { @@ -3282,6 +3288,15 @@ public class WifiStateMachine extends StateMachine { case WifiP2pService.P2P_ENABLE_PENDING: deferMessage(message); break; + case WifiStateMachine.CMD_RESPONSE_AP_CONFIG: + WifiConfiguration config = (WifiConfiguration) message.obj; + if (config != null) { + startSoftApWithConfig(config); + } else { + loge("Softap config is null!"); + sendMessage(CMD_START_AP_FAILURE); + } + break; case CMD_START_AP_SUCCESS: setWifiApState(WIFI_AP_STATE_ENABLED); transitionTo(mSoftApStartedState); |