Merge "Remove HotwordRecognition APIs" into klp-dev
diff --git a/api/current.txt b/api/current.txt
index 07e69e9..e43b151 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -845,7 +845,6 @@
     field public static final int prompt = 16843131; // 0x101017b
     field public static final int propertyName = 16843489; // 0x10102e1
     field public static final int protectionLevel = 16842761; // 0x1010009
-    field public static final int provideAssistData = 16843758; // 0x10103ee
     field public static final int publicKey = 16843686; // 0x10103a6
     field public static final int queryActionMsg = 16843227; // 0x10101db
     field public static final int queryAfterZeroResults = 16843394; // 0x1010282
@@ -4246,7 +4245,6 @@
     method public void onCreate();
     method public void onDestroy();
     method public void onLowMemory();
-    method public void onProvideAssistData(android.os.Bundle);
     method public void onRebind(android.content.Intent);
     method public deprecated void onStart(android.content.Intent, int);
     method public int onStartCommand(android.content.Intent, int, int);
@@ -6406,7 +6404,6 @@
     field public static final java.lang.String ACTION_USER_INITIALIZE = "android.intent.action.USER_INITIALIZE";
     field public static final java.lang.String ACTION_USER_PRESENT = "android.intent.action.USER_PRESENT";
     field public static final java.lang.String ACTION_VIEW = "android.intent.action.VIEW";
-    field public static final java.lang.String ACTION_VOICE_ASSIST = "android.intent.action.VOICE_ASSIST";
     field public static final java.lang.String ACTION_VOICE_COMMAND = "android.intent.action.VOICE_COMMAND";
     field public static final deprecated java.lang.String ACTION_WALLPAPER_CHANGED = "android.intent.action.WALLPAPER_CHANGED";
     field public static final java.lang.String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH";
@@ -6448,8 +6445,6 @@
     field public static final deprecated java.lang.String EXTRA_ALLOW_REPLACE = "android.intent.extra.ALLOW_REPLACE";
     field public static final java.lang.String EXTRA_ASSIST_CONTEXT = "android.intent.extra.ASSIST_CONTEXT";
     field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
-    field public static final java.lang.String EXTRA_ASSIST_SERVICES_CONTEXTS = "android.intent.extra.ASSIST_SERVICES_CONTEXTS";
-    field public static final java.lang.String EXTRA_ASSIST_SERVICES_PACKAGES = "android.intent.extra.ASSIST_SERVICES_PACKAGES";
     field public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC";
     field public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
     field public static final java.lang.String EXTRA_CC = "android.intent.extra.CC";
@@ -7449,7 +7444,6 @@
     method public void dump(android.util.Printer, java.lang.String);
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int FLAG_ISOLATED_PROCESS = 2; // 0x2
-    field public static final int FLAG_PROVIDE_ASSIST_DATA = 4; // 0x4
     field public static final int FLAG_SINGLE_USER = 1073741824; // 0x40000000
     field public static final int FLAG_STOP_WITH_TASK = 1; // 0x1
     field public int flags;
@@ -9925,7 +9919,7 @@
     method public abstract void onFrameAvailable(android.graphics.SurfaceTexture);
   }
 
-  public static class SurfaceTexture.OutOfResourcesException extends java.lang.Exception {
+  public static deprecated class SurfaceTexture.OutOfResourcesException extends java.lang.Exception {
     ctor public SurfaceTexture.OutOfResourcesException();
     ctor public SurfaceTexture.OutOfResourcesException(java.lang.String);
   }
@@ -12790,6 +12784,7 @@
     ctor public MediaMuxer(java.lang.String, int) throws java.io.IOException;
     method public int addTrack(android.media.MediaFormat);
     method public void release();
+    method public void setLocation(float, float);
     method public void setOrientationHint(int);
     method public void start();
     method public void stop();
@@ -15266,7 +15261,7 @@
     method public final void notifyUnhandled();
     method public final android.os.IBinder onBind(android.content.Intent);
     method public abstract void onDeactivated(int);
-    method public byte[] processCommandApdu(byte[], android.os.Bundle);
+    method public abstract byte[] processCommandApdu(byte[], android.os.Bundle);
     method public final void sendResponseApdu(byte[]);
     field public static final int DEACTIVATION_DESELECTED = 1; // 0x1
     field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0
@@ -27280,7 +27275,7 @@
     field public static final int ROTATION_90 = 1; // 0x1
   }
 
-  public static class Surface.OutOfResourcesException extends java.lang.Exception {
+  public static class Surface.OutOfResourcesException extends java.lang.RuntimeException {
     ctor public Surface.OutOfResourcesException();
     ctor public Surface.OutOfResourcesException(java.lang.String);
   }
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 6394299..86da673 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -1027,6 +1027,8 @@
             long currentPlayTime = currentTime - mStartTime;
             long timeLeft = mDuration - currentPlayTime;
             mStartTime = currentTime - timeLeft;
+        } else if (mStarted) {
+            end();
         } else {
             start(true);
         }
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 653559d..370db31 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1917,7 +1917,8 @@
             data.enforceInterface(IActivityManager.descriptor);
             int pid = data.readInt();
             boolean aboveSystem = data.readInt() != 0;
-            long res = inputDispatchingTimedOut(pid, aboveSystem);
+            String reason = data.readString();
+            long res = inputDispatchingTimedOut(pid, aboveSystem, reason);
             reply.writeNoException();
             reply.writeLong(res);
             return true;
@@ -1936,8 +1937,7 @@
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
             Bundle extras = data.readBundle();
-            int index = data.readInt();
-            reportAssistContextExtras(token, extras, index);
+            reportAssistContextExtras(token, extras);
             reply.writeNoException();
             return true;
         }
@@ -4462,12 +4462,14 @@
         reply.recycle();
     }
 
-    public long inputDispatchingTimedOut(int pid, boolean aboveSystem) throws RemoteException {
+    public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason)
+            throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeInt(pid);
         data.writeInt(aboveSystem ? 1 : 0);
+        data.writeString(reason);
         mRemote.transact(INPUT_DISPATCHING_TIMED_OUT_TRANSACTION, data, reply, 0);
         reply.readException();
         long res = reply.readInt();
@@ -4489,14 +4491,13 @@
         return res;
     }
 
-    public void reportAssistContextExtras(IBinder token, Bundle extras, int index)
+    public void reportAssistContextExtras(IBinder token, Bundle extras)
             throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(token);
         data.writeBundle(extras);
-        data.writeInt(index);
         mRemote.transact(REPORT_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 018fbe0..209514a 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -528,7 +528,6 @@
         IBinder activityToken;
         IBinder requestToken;
         int requestType;
-        int index;
     }
 
     private native void dumpGraphicsInfo(FileDescriptor fd);
@@ -1194,12 +1193,11 @@
 
         @Override
         public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken,
-                int requestType, int index) {
+                int requestType) {
             RequestAssistContextExtras cmd = new RequestAssistContextExtras();
             cmd.activityToken = activityToken;
             cmd.requestToken = requestToken;
             cmd.requestType = requestType;
-            cmd.index = index;
             queueOrSendMessage(H.REQUEST_ASSIST_CONTEXT_EXTRAS, cmd);
         }
 
@@ -2278,18 +2276,13 @@
         if (r != null) {
             r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
             r.activity.onProvideAssistData(data);
-        } else {
-            Service service = mServices.get(cmd.activityToken);
-            if (service != null) {
-                service.onProvideAssistData(data);
-            }
         }
         if (data.isEmpty()) {
             data = null;
         }
         IActivityManager mgr = ActivityManagerNative.getDefault();
         try {
-            mgr.reportAssistContextExtras(cmd.requestToken, data, cmd.index);
+            mgr.reportAssistContextExtras(cmd.requestToken, data);
         } catch (RemoteException e) {
         }
     }
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 19a028d..3e4795c 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -185,11 +185,11 @@
             OP_CALL_PHONE,
             OP_READ_SMS,
             OP_WRITE_SMS,
-            OP_READ_SMS,
-            OP_READ_SMS,
-            OP_READ_SMS,
-            OP_READ_SMS,
-            OP_WRITE_SMS,
+            OP_RECEIVE_SMS,
+            OP_RECEIVE_SMS,
+            OP_RECEIVE_SMS,
+            OP_RECEIVE_SMS,
+            OP_SEND_SMS,
             OP_READ_SMS,
             OP_WRITE_SMS,
             OP_WRITE_SETTINGS,
@@ -575,6 +575,10 @@
         }
     }
 
+    private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
+        return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
+    }
+
     /**
      * Do a quick check for whether an application might be able to perform an operation.
      * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
@@ -595,7 +599,7 @@
         try {
             int mode = mService.checkOperation(op, uid, packageName);
             if (mode == MODE_ERRORED) {
-                throw new SecurityException("Operation not allowed");
+                throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
             }
             return mode;
         } catch (RemoteException e) {
@@ -650,7 +654,7 @@
         try {
             int mode = mService.noteOperation(op, uid, packageName);
             if (mode == MODE_ERRORED) {
-                throw new SecurityException("Operation not allowed");
+                throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
             }
             return mode;
         } catch (RemoteException e) {
@@ -672,7 +676,7 @@
 
     /** @hide */
     public int noteOp(int op) {
-        return noteOp(op, Process.myUid(), mContext.getBasePackageName());
+        return noteOp(op, Process.myUid(), mContext.getOpPackageName());
     }
 
     /** @hide */
@@ -710,7 +714,7 @@
         try {
             int mode = mService.startOperation(getToken(mService), op, uid, packageName);
             if (mode == MODE_ERRORED) {
-                throw new SecurityException("Operation not allowed");
+                throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
             }
             return mode;
         } catch (RemoteException e) {
@@ -732,7 +736,7 @@
 
     /** @hide */
     public int startOp(int op) {
-        return startOp(op, Process.myUid(), mContext.getBasePackageName());
+        return startOp(op, Process.myUid(), mContext.getOpPackageName());
     }
 
     /**
@@ -749,6 +753,6 @@
     }
 
     public void finishOp(int op) {
-        finishOp(op, Process.myUid(), mContext.getBasePackageName());
+        finishOp(op, Process.myUid(), mContext.getOpPackageName());
     }
 }
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index ab2739d..e522b78 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1275,7 +1275,7 @@
                                              int newState, int flags) {
         try {
             mPM.setApplicationEnabledSetting(packageName, newState, flags,
-                    mContext.getUserId(), mContext.getBasePackageName());
+                    mContext.getUserId(), mContext.getOpPackageName());
         } catch (RemoteException e) {
             // Should never happen!
         }
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index c0080be..a4e80e5 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -606,8 +606,7 @@
             IBinder activityToken = data.readStrongBinder();
             IBinder requestToken = data.readStrongBinder();
             int requestType = data.readInt();
-            int index = data.readInt();
-            requestAssistContextExtras(activityToken, requestToken, requestType, index);
+            requestAssistContextExtras(activityToken, requestToken, requestType);
             reply.writeNoException();
             return true;
         }
@@ -1243,13 +1242,12 @@
 
     @Override
     public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken,
-            int requestType, int index) throws RemoteException {
+            int requestType) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(activityToken);
         data.writeStrongBinder(requestToken);
         data.writeInt(requestType);
-        data.writeInt(index);
         mRemote.transact(REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, null,
                 IBinder.FLAG_ONEWAY);
         data.recycle();
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 7ff7562..fe8c506 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -183,6 +183,7 @@
 
     /*package*/ LoadedApk mPackageInfo;
     private String mBasePackageName;
+    private String mOpPackageName;
     private Resources mResources;
     /*package*/ ActivityThread mMainThread;
     private Context mOuterContext;
@@ -679,6 +680,12 @@
         return mBasePackageName != null ? mBasePackageName : getPackageName();
     }
 
+    /** @hide */
+    @Override
+    public String getOpPackageName() {
+        return mOpPackageName != null ? mOpPackageName : getBasePackageName();
+    }
+
     @Override
     public ApplicationInfo getApplicationInfo() {
         if (mPackageInfo != null) {
@@ -1961,6 +1968,7 @@
     public ContextImpl(ContextImpl context) {
         mPackageInfo = context.mPackageInfo;
         mBasePackageName = context.mBasePackageName;
+        mOpPackageName = context.mOpPackageName;
         mResources = context.mResources;
         mMainThread = context.mMainThread;
         mContentResolver = context.mContentResolver;
@@ -1977,7 +1985,21 @@
     final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread,
             Resources container, String basePackageName, UserHandle user) {
         mPackageInfo = packageInfo;
-        mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;
+        if (basePackageName != null) {
+            mBasePackageName = mOpPackageName = basePackageName;
+        } else {
+            mBasePackageName = packageInfo.mPackageName;
+            ApplicationInfo ainfo = packageInfo.getApplicationInfo();
+            if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) {
+                // Special case: system components allow themselves to be loaded in to other
+                // processes.  For purposes of app ops, we must then consider the context as
+                // belonging to the package of this process, not the system itself, otherwise
+                // the package+uid verifications in app ops will fail.
+                mOpPackageName = ActivityThread.currentPackageName();
+            } else {
+                mOpPackageName = mBasePackageName;
+            }
+        }
         mResources = mPackageInfo.getResources(mainThread);
         mResourcesManager = ResourcesManager.getInstance();
 
@@ -2011,6 +2033,7 @@
     final void init(Resources resources, ActivityThread mainThread, UserHandle user) {
         mPackageInfo = null;
         mBasePackageName = null;
+        mOpPackageName = null;
         mResources = resources;
         mMainThread = mainThread;
         mContentResolver = new ApplicationContentResolver(this, mainThread, user);
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index af9a245..b2ae298 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -384,12 +384,12 @@
 
     public void requestBugReport() throws RemoteException;
 
-    public long inputDispatchingTimedOut(int pid, boolean aboveSystem) throws RemoteException;
+    public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason)
+            throws RemoteException;
 
     public Bundle getAssistContextExtras(int requestType) throws RemoteException;
 
-    public void reportAssistContextExtras(IBinder token, Bundle extras, int index)
-            throws RemoteException;
+    public void reportAssistContextExtras(IBinder token, Bundle extras) throws RemoteException;
 
     public void killUid(int uid, String reason) throws RemoteException;
 
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 01a0a91..058b975 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -133,8 +133,8 @@
     void dumpGfxInfo(FileDescriptor fd, String[] args) throws RemoteException;
     void dumpDbInfo(FileDescriptor fd, String[] args) throws RemoteException;
     void unstableProviderDied(IBinder provider) throws RemoteException;
-    void requestAssistContextExtras(IBinder activityToken, IBinder requestToken, int requestType,
-            int index) throws RemoteException;
+    void requestAssistContextExtras(IBinder activityToken, IBinder requestToken, int requestType)
+            throws RemoteException;
     void scheduleTranslucentConversionComplete(IBinder token, boolean timeout)
             throws RemoteException;
     void setProcessState(int state) throws RemoteException;
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index dbafc78..3ee4306 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -133,7 +133,7 @@
         }
         if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
         try {
-            service.enqueueNotificationWithTag(pkg, mContext.getBasePackageName(), tag, id,
+            service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
                     notification, idOut, UserHandle.myUserId());
             if (id != idOut[0]) {
                 Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
@@ -158,7 +158,7 @@
         }
         if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
         try {
-            service.enqueueNotificationWithTag(pkg, mContext.getBasePackageName(), tag, id,
+            service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
                     notification, idOut, user.getIdentifier());
             if (id != idOut[0]) {
                 Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 1254bac..3967740 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -23,7 +23,6 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.os.Build;
-import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.IBinder;
 import android.util.Log;
@@ -308,18 +307,6 @@
     }
 
     /**
-     * This is called on foreground services when the user is requesting an assist, to build a
-     * full {@link Intent#ACTION_ASSIST} Intent with all of the context of the current
-     * running foreground services.  You can override this method to place into the bundle
-     * anything you would like to appear as an item in the
-     * {@link Intent#EXTRA_ASSIST_SERVICES_CONTEXTS} part of the assist Intent.
-     * This method will not be called if this service is not in the foreground.
-     * The default implementation does nothing.
-     */
-    public void onProvideAssistData(Bundle data) {
-    }
-
-    /**
      * @deprecated Implement {@link #onStartCommand(Intent, int, int)} instead.
      */
     @Deprecated
diff --git a/core/java/android/content/ClipboardManager.java b/core/java/android/content/ClipboardManager.java
index 69f9d4a..73e6fd0 100644
--- a/core/java/android/content/ClipboardManager.java
+++ b/core/java/android/content/ClipboardManager.java
@@ -122,7 +122,7 @@
             if (clip != null) {
                 clip.prepareToLeaveProcess();
             }
-            getService().setPrimaryClip(clip, mContext.getBasePackageName());
+            getService().setPrimaryClip(clip, mContext.getOpPackageName());
         } catch (RemoteException e) {
         }
     }
@@ -132,7 +132,7 @@
      */
     public ClipData getPrimaryClip() {
         try {
-            return getService().getPrimaryClip(mContext.getBasePackageName());
+            return getService().getPrimaryClip(mContext.getOpPackageName());
         } catch (RemoteException e) {
             return null;
         }
@@ -144,7 +144,7 @@
      */
     public ClipDescription getPrimaryClipDescription() {
         try {
-            return getService().getPrimaryClipDescription(mContext.getBasePackageName());
+            return getService().getPrimaryClipDescription(mContext.getOpPackageName());
         } catch (RemoteException e) {
             return null;
         }
@@ -155,7 +155,7 @@
      */
     public boolean hasPrimaryClip() {
         try {
-            return getService().hasPrimaryClip(mContext.getBasePackageName());
+            return getService().hasPrimaryClip(mContext.getOpPackageName());
         } catch (RemoteException e) {
             return false;
         }
@@ -166,7 +166,7 @@
             if (mPrimaryClipChangedListeners.size() == 0) {
                 try {
                     getService().addPrimaryClipChangedListener(
-                            mPrimaryClipChangedServiceListener, mContext.getBasePackageName());
+                            mPrimaryClipChangedServiceListener, mContext.getOpPackageName());
                 } catch (RemoteException e) {
                 }
             }
@@ -213,7 +213,7 @@
      */
     public boolean hasText() {
         try {
-            return getService().hasClipboardText(mContext.getBasePackageName());
+            return getService().hasClipboardText(mContext.getOpPackageName());
         } catch (RemoteException e) {
             return false;
         }
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 3438419..0a1d3f9a 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -918,8 +918,10 @@
      *
      * @param url The Uri to remove any canonicalization from.
      *
-     * @return Return the non-canonical representation of <var>url</var>, or return
-     * the <var>url</var> as-is if there is nothing to do.  Never return null.
+     * @return Return the non-canonical representation of <var>url</var>, return
+     * the <var>url</var> as-is if there is nothing to do, or return null if
+     * the data identified by the canonical representation can not be found in
+     * the current environment.
      */
     public Uri uncanonicalize(Uri url) {
         return url;
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index e914604..f250029 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -261,7 +261,7 @@
 
     public ContentResolver(Context context) {
         mContext = context != null ? context : ActivityThread.currentApplication();
-        mPackageName = mContext.getBasePackageName();
+        mPackageName = mContext.getOpPackageName();
     }
 
     /** @hide */
@@ -548,14 +548,16 @@
      * it to its local non-canonical form.  This can be useful in some cases where
      * you know that you will only be using the Uri in the current environment and
      * want to avoid any possible overhead when using it with the content
-     * provider.
+     * provider or want to verify that the referenced data exists at all in the
+     * new environment.
      *
      * @param url The canonical {@link Uri} that is to be convered back to its
      * non-canonical form.
      *
-     * @return Returns the non-canonical representation of <var>url</var>.  This
-     * function never returns null; if there is no conversion to be done, it returns
-     * the same Uri that was provided.
+     * @return Returns the non-canonical representation of <var>url</var>.  This will
+     * return null if data identified by the canonical Uri can not be found in
+     * the current environment; callers must always check for null and deal with
+     * that by appropriately falling back to an alternative.
      *
      * @see #canonicalize
      */
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 8df5bee..7b15e63 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -435,6 +435,13 @@
     /** @hide Return the name of the base context this context is derived from. */
     public abstract String getBasePackageName();
 
+    /** @hide Return the package name that should be used for app ops calls from
+     * this context.  This is the same as {@link #getBasePackageName()} except in
+     * cases where system components are loaded into other app processes, in which
+     * case this will be the name of the primary package in that process (so that app
+     * ops uid verification will work with the name). */
+    public abstract String getOpPackageName();
+
     /** Return the full application info for this context's package. */
     public abstract ApplicationInfo getApplicationInfo();
 
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index e09d367..a708dad 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -141,6 +141,12 @@
         return mBase.getBasePackageName();
     }
 
+    /** @hide */
+    @Override
+    public String getOpPackageName() {
+        return mBase.getOpPackageName();
+    }
+
     @Override
     public ApplicationInfo getApplicationInfo() {
         return mBase.getApplicationInfo();
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 2f2aae4..7925123 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1153,9 +1153,8 @@
     /**
      * Activity Action: Perform assist action.
      * <p>
-     * Input: {@link #EXTRA_ASSIST_PACKAGE}, {@link #EXTRA_ASSIST_CONTEXT},
-     * {@link #EXTRA_ASSIST_SERVICES_PACKAGES}, and {@link #EXTRA_ASSIST_SERVICES_CONTEXTS} can
-     * provide additional optional contextual information about where the user was when they
+     * Input: {@link #EXTRA_ASSIST_PACKAGE}, {@link #EXTRA_ASSIST_CONTEXT}, can provide
+     * additional optional contextual information about where the user was when they
      * requested the assist.
      * Output: nothing.
      */
@@ -1165,52 +1164,31 @@
     /**
      * Activity Action: Perform voice assist action.
      * <p>
-     * Input: {@link #EXTRA_ASSIST_PACKAGE}, {@link #EXTRA_ASSIST_CONTEXT},
-     * {@link #EXTRA_ASSIST_SERVICES_PACKAGES}, and {@link #EXTRA_ASSIST_SERVICES_CONTEXTS} can
-     * provide additional optional contextual information about where the user was when they
+     * Input: {@link #EXTRA_ASSIST_PACKAGE}, {@link #EXTRA_ASSIST_CONTEXT}, can provide
+     * additional optional contextual information about where the user was when they
      * requested the voice assist.
      * Output: nothing.
+     * @hide
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_VOICE_ASSIST = "android.intent.action.VOICE_ASSIST";
 
     /**
-     * An optional field on {@link #ACTION_ASSIST} and {@link #ACTION_VOICE_ASSIST}
-     * containing the name of the current foreground application package at the time
-     * the assist was invoked.
+     * An optional field on {@link #ACTION_ASSIST} containing the name of the current foreground
+     * application package at the time the assist was invoked.
      */
     public static final String EXTRA_ASSIST_PACKAGE
             = "android.intent.extra.ASSIST_PACKAGE";
 
     /**
-     * An optional field on {@link #ACTION_ASSIST} and {@link #ACTION_VOICE_ASSIST}
-     * containing additional contextual information supplied by the current
-     * foreground app at the time of the assist request.  This is a {@link Bundle} of
-     * additional data.
+     * An optional field on {@link #ACTION_ASSIST} and containing additional contextual
+     * information supplied by the current foreground app at the time of the assist request.
+     * This is a {@link Bundle} of additional data.
      */
     public static final String EXTRA_ASSIST_CONTEXT
             = "android.intent.extra.ASSIST_CONTEXT";
 
     /**
-     * An optional field on {@link #ACTION_ASSIST} and {@link #ACTION_VOICE_ASSIST}
-     * containing the application package names of foreground services at the time
-     * of the assist request.  This is an array of {@link String}s, with one entry
-     * per service.
-     */
-    public static final String EXTRA_ASSIST_SERVICES_PACKAGES
-            = "android.intent.extra.ASSIST_SERVICES_PACKAGES";
-
-    /**
-     * An optional field on {@link #ACTION_ASSIST} and {@link #ACTION_VOICE_ASSIST}
-     * containing additional contextual information supplied by the current
-     * foreground services at the time of the assist request.  This is an array
-     * of {@link Bundle}s of additional data, with one {@link Bundle} per service.
-     */
-    public static final String EXTRA_ASSIST_SERVICES_CONTEXTS
-            = "android.intent.extra.ASSIST_SERVICES_CONTEXTS";
-
-
-    /**
      * Activity Action: List all available applications
      * <p>Input: Nothing.
      * <p>Output: nothing.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 6760f49..4494e69 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3015,11 +3015,6 @@
 
         s.info.flags = 0;
         if (sa.getBoolean(
-                com.android.internal.R.styleable.AndroidManifestService_provideAssistData,
-                false)) {
-            s.info.flags |= ServiceInfo.FLAG_PROVIDE_ASSIST_DATA;
-        }
-        if (sa.getBoolean(
                 com.android.internal.R.styleable.AndroidManifestService_stopWithTask,
                 false)) {
             s.info.flags |= ServiceInfo.FLAG_STOP_WITH_TASK;
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
index 3dc8717..796c2a4 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -49,14 +49,6 @@
     public static final int FLAG_ISOLATED_PROCESS = 0x0002;
 
     /**
-     * Bit in {@link #flags}: If set,
-     * {@link android.app.Service#onProvideAssistData(android.os.Bundle)} will
-     * be called on the service when it is running in the foreground. Set from
-     * the {@link android.R.attr#provideAssistData} attribute.
-     */
-    public static final int FLAG_PROVIDE_ASSIST_DATA = 0x0004;
-
-    /**
      * Bit in {@link #flags}: If set, a single instance of the service will
      * run for all users on the device.  Set from the
      * {@link android.R.attr#singleUser} attribute.
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 8903b4a..ff9282e 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -55,7 +55,7 @@
 
     private final ICameraService mCameraService;
     private ArrayList<String> mDeviceIdList;
-    private HashSet<CameraListener> mListenerSet = new HashSet<CameraListener>();
+    private final HashSet<CameraListener> mListenerSet = new HashSet<CameraListener>();
     private final Context mContext;
     private final Object mLock = new Object();
 
@@ -332,7 +332,7 @@
 
                 Integer oldStatus = mDeviceStatus.put(id, status);
 
-                if (oldStatus == status) {
+                if (oldStatus != null && oldStatus == status) {
                     Log.v(TAG, String.format(
                             "Device status changed to 0x%x, which is what it already was",
                             status));
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 4cf38b6..c78a973 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -1476,4 +1476,20 @@
         } catch (RemoteException e) {
         }
     }
+
+    /**
+     * Set the value for enabling/disabling airplane mode
+     *
+     * @param enable whether to enable airplane mode or not
+     *
+     * <p>This method requires the call to hold the permission
+     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
+     * @hide
+     */
+    public void setAirplaneMode(boolean enable) {
+        try {
+            mService.setAirplaneMode(enable);
+        } catch (RemoteException e) {
+        }
+    }
 }
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index a6f10ec..b3fa79f 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -156,4 +156,6 @@
     LinkQualityInfo[] getAllLinkQualityInfo();
 
     void setProvisioningNotificationVisible(boolean visible, int networkType, in String extraInfo, in String url);
+
+    void setAirplaneMode(boolean enable);
 }
diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
index 41c6603..40a3612 100644
--- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -22,6 +22,7 @@
 import android.content.pm.ServiceInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.graphics.drawable.Drawable;
@@ -80,10 +81,15 @@
     final boolean mRequiresDeviceUnlock;
 
     /**
+     * The id of the service banner specified in XML.
+     */
+    final int mBannerResourceId;
+
+    /**
      * @hide
      */
     public ApduServiceInfo(ResolveInfo info, boolean onHost, String description,
-            ArrayList<AidGroup> aidGroups, boolean requiresUnlock) {
+            ArrayList<AidGroup> aidGroups, boolean requiresUnlock, int bannerResource) {
         this.mService = info;
         this.mDescription = description;
         this.mAidGroups = aidGroups;
@@ -95,6 +101,7 @@
             this.mCategoryToGroup.put(aidGroup.category, aidGroup);
             this.mAids.addAll(aidGroup.aids);
         }
+        this.mBannerResourceId = bannerResource;
     }
 
     public ApduServiceInfo(PackageManager pm, ResolveInfo info, boolean onHost)
@@ -105,12 +112,8 @@
             if (onHost) {
                 parser = si.loadXmlMetaData(pm, HostApduService.SERVICE_META_DATA);
                 if (parser == null) {
-                    Log.d(TAG, "Didn't find service meta-data, trying legacy.");
-                    parser = si.loadXmlMetaData(pm, HostApduService.OLD_SERVICE_META_DATA);
-                    if (parser == null) {
-                        throw new XmlPullParserException("No " + HostApduService.SERVICE_META_DATA +
-                                " meta-data");
-                    }
+                    throw new XmlPullParserException("No " + HostApduService.SERVICE_META_DATA +
+                            " meta-data");
                 }
             } else {
                 parser = si.loadXmlMetaData(pm, OffHostApduService.SERVICE_META_DATA);
@@ -145,6 +148,9 @@
                 mRequiresDeviceUnlock = sa.getBoolean(
                         com.android.internal.R.styleable.HostApduService_requireDeviceUnlock,
                         false);
+                mBannerResourceId = sa.getResourceId(
+                        com.android.internal.R.styleable.HostApduService_apduServiceBanner, -1);
+                sa.recycle();
             } else {
                 TypedArray sa = res.obtainAttributes(attrs,
                         com.android.internal.R.styleable.OffHostApduService);
@@ -152,6 +158,9 @@
                 mDescription = sa.getString(
                         com.android.internal.R.styleable.OffHostApduService_description);
                 mRequiresDeviceUnlock = false;
+                mBannerResourceId = sa.getResourceId(
+                        com.android.internal.R.styleable.HostApduService_apduServiceBanner, -1);
+                sa.recycle();
             }
 
             mAidGroups = new ArrayList<AidGroup>();
@@ -187,6 +196,7 @@
                     } else {
                         currentGroup = new AidGroup(groupCategory, groupDescription);
                     }
+                    groupAttrs.recycle();
                 } else if (eventType == XmlPullParser.END_TAG && "aid-group".equals(tagName) &&
                         currentGroup != null) {
                     if (currentGroup.aids.size() > 0) {
@@ -210,6 +220,7 @@
                     } else {
                         Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid);
                     }
+                    a.recycle();
                 }
             }
         } catch (NameNotFoundException e) {
@@ -252,6 +263,21 @@
         return mService.loadIcon(pm);
     }
 
+    public Drawable loadBanner(PackageManager pm) {
+        Resources res;
+        try {
+            res = pm.getResourcesForApplication(mService.serviceInfo.packageName);
+            Drawable banner = res.getDrawable(mBannerResourceId);
+            return banner;
+        } catch (NotFoundException e) {
+            Log.e(TAG, "Could not load banner.");
+            return null;
+        } catch (NameNotFoundException e) {
+            Log.e(TAG, "Could not load banner.");
+            return null;
+        }
+    }
+
     static boolean isValidAid(String aid) {
         if (aid == null)
             return false;
@@ -306,6 +332,7 @@
             dest.writeTypedList(mAidGroups);
         }
         dest.writeInt(mRequiresDeviceUnlock ? 1 : 0);
+        dest.writeInt(mBannerResourceId);
     };
 
     public static final Parcelable.Creator<ApduServiceInfo> CREATOR =
@@ -321,7 +348,8 @@
                 source.readTypedList(aidGroups, AidGroup.CREATOR);
             }
             boolean requiresUnlock = (source.readInt() != 0) ? true : false;
-            return new ApduServiceInfo(info, onHost, description, aidGroups, requiresUnlock);
+            int bannerResource = source.readInt();
+            return new ApduServiceInfo(info, onHost, description, aidGroups, requiresUnlock, bannerResource);
         }
 
         @Override
diff --git a/core/java/android/nfc/cardemulation/CardEmulationManager.java b/core/java/android/nfc/cardemulation/CardEmulationManager.java
deleted file mode 100644
index 124ea1c..0000000
--- a/core/java/android/nfc/cardemulation/CardEmulationManager.java
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (C) 2013 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.nfc.cardemulation;
-
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.app.ActivityThread;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.nfc.INfcCardEmulation;
-import android.nfc.NfcAdapter;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * TODO Remove when calling .apks are upgraded
- * @hide
- */
-public final class CardEmulationManager {
-    static final String TAG = "CardEmulationManager";
-
-    /**
-     * Activity action: ask the user to change the default
-     * card emulation service for a certain category. This will
-     * show a dialog that asks the user whether he wants to
-     * replace the current default service with the service
-     * identified with the ComponentName specified in
-     * {@link #EXTRA_SERVICE_COMPONENT}, for the category
-     * specified in {@link #EXTRA_CATEGORY}
-     */
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_CHANGE_DEFAULT =
-            "android.nfc.cardemulation.ACTION_CHANGE_DEFAULT";
-
-    /**
-     * The category extra for {@link #ACTION_CHANGE_DEFAULT}
-     *
-     * @see #ACTION_CHANGE_DEFAULT
-     */
-    public static final String EXTRA_CATEGORY = "category";
-
-    /**
-     * The ComponentName object passed in as a parcelable
-     * extra for {@link #ACTION_CHANGE_DEFAULT}
-     *
-     * @see #ACTION_CHANGE_DEFAULT
-     */
-    public static final String EXTRA_SERVICE_COMPONENT = "component";
-
-    /**
-     * The payment category can be used to indicate that an AID
-     * represents a payment application.
-     */
-    public static final String CATEGORY_PAYMENT = "payment";
-
-    /**
-     * If an AID group does not contain a category, or the
-     * specified category is not defined by the platform version
-     * that is parsing the AID group, all AIDs in the group will
-     * automatically be categorized under the {@link #CATEGORY_OTHER}
-     * category.
-     */
-    public static final String CATEGORY_OTHER = "other";
-
-    /**
-     * Return value for {@link #getSelectionModeForCategory(String)}.
-     *
-     * <p>In this mode, the user has set a default service for this
-     *    AID category. If a remote reader selects any of the AIDs
-     *    that the default service has registered in this category,
-     *    that service will automatically be bound to to handle
-     *    the transaction.
-     *
-     * <p>There are still cases where a service that is
-     *    not the default for a category can selected:
-     *    <p>
-     *    If a remote reader selects an AID in this category
-     *    that is not handled by the default service, and there is a set
-     *    of other services {S} that do handle this AID, the
-     *    user is asked if he wants to use any of the services in
-     *    {S} instead.
-     *    <p>
-     *    As a special case, if the size of {S} is one, containing a single service X,
-     *    and all AIDs X has registered in this category are not
-     *    registered by any other service, then X will be
-     *    selected automatically without asking the user.
-     *    <p>Example:
-     *    <ul>
-     *    <li>Service A registers AIDs "1", "2" and "3" in the category
-     *    <li>Service B registers AIDs "3" and "4" in the category
-     *    <li>Service C registers AIDs "5" and "6" in the category
-     *    </ul>
-     *    In this case, the following will happen when service A
-     *    is the default:
-     *    <ul>
-     *    <li>Reader selects AID "1", "2" or "3": service A is invoked automatically
-     *    <li>Reader selects AID "4": the user is asked to confirm he
-     *        wants to use service B, because its AIDs overlap with service A.
-     *    <li>Reader selects AID "5" or "6": service C is invoked automatically,
-     *        because all AIDs it has asked for are only registered by C,
-     *        and there is no overlap.
-     *    </ul>
-     *
-     */
-    public static final int SELECTION_MODE_PREFER_DEFAULT = 0;
-
-    /**
-     * Return value for {@link #getSelectionModeForCategory(String)}.
-     *
-     * <p>In this mode, whenever an AID of this category is selected,
-     *    the user is asked which service he wants to use to handle
-     *    the transaction, even if there is only one matching service.
-     */
-    public static final int SELECTION_MODE_ALWAYS_ASK = 1;
-
-    /**
-     * Return value for {@link #getSelectionModeForCategory(String)}.
-     *
-     * <p>In this mode, the user will only be asked to select a service
-     *    if the selected AID has been registered by multiple applications.
-     */
-    public static final int SELECTION_MODE_ASK_IF_CONFLICT = 2;
-
-    static boolean sIsInitialized = false;
-    static HashMap<Context, CardEmulationManager> sCardEmuManagers = new HashMap();
-    static INfcCardEmulation sService;
-
-    final Context mContext;
-
-    private CardEmulationManager(Context context, INfcCardEmulation service) {
-        mContext = context.getApplicationContext();
-        sService = service;
-    }
-
-    public static synchronized CardEmulationManager getInstance(NfcAdapter adapter) {
-        if (adapter == null) throw new NullPointerException("NfcAdapter is null");
-        Context context = adapter.getContext();
-        if (context == null) {
-            Log.e(TAG, "NfcAdapter context is null.");
-            throw new UnsupportedOperationException();
-        }
-        if (!sIsInitialized) {
-            IPackageManager pm = ActivityThread.getPackageManager();
-            if (pm == null) {
-                Log.e(TAG, "Cannot get PackageManager");
-                throw new UnsupportedOperationException();
-            }
-            try {
-                if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
-                    Log.e(TAG, "This device does not support card emulation");
-                    throw new UnsupportedOperationException();
-                }
-            } catch (RemoteException e) {
-                Log.e(TAG, "PackageManager query failed.");
-                throw new UnsupportedOperationException();
-            }
-            sIsInitialized = true;
-        }
-        CardEmulationManager manager = sCardEmuManagers.get(context);
-        if (manager == null) {
-            // Get card emu service
-            INfcCardEmulation service = adapter.getCardEmulationService();
-            manager = new CardEmulationManager(context, service);
-            sCardEmuManagers.put(context, manager);
-        }
-        return manager;
-    }
-
-    /**
-     * Allows an application to query whether a service is currently
-     * the default service to handle a card emulation category.
-     *
-     * <p>Note that if {@link #getSelectionModeForCategory(String)}
-     * returns {@link #SELECTION_MODE_ALWAYS_ASK}, this method will always
-     * return false.
-     *
-     * @param service The ComponentName of the service
-     * @param category The category
-     * @return whether service is currently the default service for the category.
-     */
-    public boolean isDefaultServiceForCategory(ComponentName service, String category) {
-        try {
-            return sService.isDefaultServiceForCategory(UserHandle.myUserId(), service, category);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-            try {
-                return sService.isDefaultServiceForCategory(UserHandle.myUserId(), service,
-                        category);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-        }
-    }
-
-    /**
-     *
-     * Allows an application to query whether a service is currently
-     * the default handler for a specified ISO7816-4 Application ID.
-     *
-     * @param service The ComponentName of the service
-     * @param aid The ISO7816-4 Application ID
-     * @return
-     */
-    public boolean isDefaultServiceForAid(ComponentName service, String aid) {
-        try {
-            return sService.isDefaultServiceForAid(UserHandle.myUserId(), service, aid);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-            try {
-                return sService.isDefaultServiceForAid(UserHandle.myUserId(), service, aid);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                return false;
-            }
-        }
-    }
-
-    /**
-     * Returns the application selection mode for the passed in category.
-     * Valid return values are:
-     * <p>{@link #SELECTION_MODE_PREFER_DEFAULT} the user has requested a default
-     *    application for this category, which will be preferred.
-     * <p>{@link #SELECTION_MODE_ALWAYS_ASK} the user has requested to be asked
-     *    every time what app he would like to use in this category.
-     * <p>{@link #SELECTION_MODE_ASK_IF_CONFLICT} the user will only be asked
-     *    to pick a service if there is a conflict.
-     * @param category The category, for example {@link #CATEGORY_PAYMENT}
-     * @return
-     */
-    public int getSelectionModeForCategory(String category) {
-        if (CATEGORY_PAYMENT.equals(category)) {
-            String defaultComponent = Settings.Secure.getString(mContext.getContentResolver(),
-                    Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT);
-            if (defaultComponent != null) {
-                return SELECTION_MODE_PREFER_DEFAULT;
-            } else {
-                return SELECTION_MODE_ALWAYS_ASK;
-            }
-        } else {
-            // All other categories are in "only ask if conflict" mode
-            return SELECTION_MODE_ASK_IF_CONFLICT;
-        }
-    }
-
-    /**
-     * @hide
-     */
-    public boolean setDefaultServiceForCategory(ComponentName service, String category) {
-        try {
-            return sService.setDefaultServiceForCategory(UserHandle.myUserId(), service, category);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-            try {
-                return sService.setDefaultServiceForCategory(UserHandle.myUserId(), service,
-                        category);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                return false;
-            }
-        }
-    }
-
-    /**
-     * @hide
-     */
-    public boolean setDefaultForNextTap(ComponentName service) {
-        try {
-            return sService.setDefaultForNextTap(UserHandle.myUserId(), service);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-            try {
-                return sService.setDefaultForNextTap(UserHandle.myUserId(), service);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                return false;
-            }
-        }
-    }
-    /**
-     * @hide
-     */
-    public List<ApduServiceInfo> getServices(String category) {
-        try {
-            return sService.getServices(UserHandle.myUserId(), category);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return null;
-            }
-            try {
-                return sService.getServices(UserHandle.myUserId(), category);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                return null;
-            }
-        }
-    }
-
-    void recoverService() {
-        NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
-        sService = adapter.getCardEmulationService();
-    }
-}
diff --git a/core/java/android/nfc/cardemulation/HostApduService.java b/core/java/android/nfc/cardemulation/HostApduService.java
index 174acc0..e2c3ca6 100644
--- a/core/java/android/nfc/cardemulation/HostApduService.java
+++ b/core/java/android/nfc/cardemulation/HostApduService.java
@@ -50,23 +50,6 @@
             "android.nfc.cardemulation.host_apdu_service";
 
     /**
-     * The {@link Intent} that must be declared as handled by the service.
-     * TODO Remove
-     * @hide
-     */
-    public static final String OLD_SERVICE_INTERFACE =
-            "android.nfc.HostApduService";
-
-    /**
-     * The name of the meta-data element that contains
-     * more information about this service.
-     *
-     * TODO Remove
-     * @hide
-     */
-    public static final String OLD_SERVICE_META_DATA = "android.nfc.HostApduService";
-
-    /**
      * Reason for {@link #onDeactivated(int)}.
      * Indicates deactivation was due to the NFC link
      * being lost.
@@ -282,37 +265,7 @@
      * @return a byte-array containing the response APDU, or null if no
      *         response APDU can be sent at this point.
      */
-    public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {
-        // TODO make this abstract
-        return processCommandApdu(commandApdu, 0);
-    }
-
-    /**
-     * <p>This method will be called when a command APDU has been received
-     * from a remote device. A response APDU can be provided directly
-     * by returning a byte-array in this method. Note that in general
-     * response APDUs must be sent as quickly as possible, given the fact
-     * that the user is likely holding his device over an NFC reader
-     * when this method is called.
-     *
-     * <p class="note">If there are multiple services that have registered for the same
-     * AIDs in their meta-data entry, you will only get called if the user has
-     * explicitly selected your service, either as a default or just for the next tap.
-     *
-     * <p class="note">This method is running on the main thread of your application.
-     * If you cannot return a response APDU immediately, return null
-     * and use the {@link #sendResponseApdu(byte[])} method later.
-     *
-     * @deprecated use {@link #processCommandApdu(byte[], Bundle)}
-     * @param commandApdu
-     * @param flags
-     * @return a byte-array containing the response APDU, or null if no
-     *         response APDU can be sent at this point.
-     * @hide
-     */
-    public byte[] processCommandApdu(byte[] commandApdu, int flags) {
-        return null;
-    }
+    public abstract byte[] processCommandApdu(byte[] commandApdu, Bundle extras);
 
     /**
      * This method will be called in two possible scenarios:
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 52e5f38..5e0d489 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -407,7 +407,7 @@
      */
     public WakeLock newWakeLock(int levelAndFlags, String tag) {
         validateWakeLockParameters(levelAndFlags, tag);
-        return new WakeLock(levelAndFlags, tag, mContext.getBasePackageName());
+        return new WakeLock(levelAndFlags, tag, mContext.getOpPackageName());
     }
 
     /** @hide */
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index e66fb285..700f80d 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -39,7 +39,7 @@
     }
 
     public SystemVibrator(Context context) {
-        mPackageName = context.getBasePackageName();
+        mPackageName = context.getOpPackageName();
         mService = IVibratorService.Stub.asInterface(
                 ServiceManager.getService("vibrator"));
     }
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 9d52c83..a6f23a8 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -137,8 +137,18 @@
         public static final String NUMBER = "number";
 
         /**
-         * The number presenting rules set by the network for "allowed",
-         * "payphone", "restricted" or "unknown".
+         * The number presenting rules set by the network.
+         *
+         * <p>
+         * Allowed values:
+         * <ul>
+         * <li>{@link #PRESENTATION_ALLOWED}</li>
+         * <li>{@link #PRESENTATION_RESTRICTED}</li>
+         * <li>{@link #PRESENTATION_UNKNOWN}</li>
+         * <li>{@link #PRESENTATION_PAYPHONE}</li>
+         * </ul>
+         * </p>
+         *
          * <P>Type: INTEGER</P>
          */
         public static final String NUMBER_PRESENTATION = "presentation";
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 91b3b48..43120c4 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -459,6 +459,7 @@
     private static final String PATH_SEARCH = "search";
 
     private static final String PARAM_QUERY = "query";
+    private static final String PARAM_MANAGE = "manage";
 
     /**
      * Build Uri representing the roots of a document provider. When queried, a
@@ -583,6 +584,16 @@
         return searchDocumentsUri.getQueryParameter(PARAM_QUERY);
     }
 
+    /** {@hide} */
+    public static Uri setManageMode(Uri uri) {
+        return uri.buildUpon().appendQueryParameter(PARAM_MANAGE, "true").build();
+    }
+
+    /** {@hide} */
+    public static boolean isManageMode(Uri uri) {
+        return uri.getBooleanQueryParameter(PARAM_MANAGE, false);
+    }
+
     /**
      * Return list of all documents that the calling package has "open." These
      * are Uris matching {@link DocumentsContract} to which persistent
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 1b0fc4d..d801827 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -167,6 +167,14 @@
             String parentDocumentId, String[] projection, String sortOrder)
             throws FileNotFoundException;
 
+    /** {@hide} */
+    @SuppressWarnings("unused")
+    public Cursor queryChildDocumentsForManage(
+            String parentDocumentId, String[] projection, String sortOrder)
+            throws FileNotFoundException {
+        throw new UnsupportedOperationException("Manage not supported");
+    }
+
     /**
      * Return documents that that match the given query, starting the search at
      * the given directory.
@@ -262,7 +270,12 @@
                 case MATCH_DOCUMENT:
                     return queryDocument(getDocumentId(uri), projection);
                 case MATCH_CHILDREN:
-                    return queryChildDocuments(getDocumentId(uri), projection, sortOrder);
+                    if (DocumentsContract.isManageMode(uri)) {
+                        return queryChildDocumentsForManage(
+                                getDocumentId(uri), projection, sortOrder);
+                    } else {
+                        return queryChildDocuments(getDocumentId(uri), projection, sortOrder);
+                    }
                 case MATCH_SEARCH:
                     return querySearchDocuments(
                             getDocumentId(uri), getSearchDocumentsQuery(uri), projection);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1a80818..b70d74a 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2439,7 +2439,9 @@
             SIP_CALL_OPTIONS,
             SIP_RECEIVE_CALLS,
             POINTER_SPEED,
-            VIBRATE_WHEN_RINGING
+            VIBRATE_WHEN_RINGING,
+            RINGTONE,
+            NOTIFICATION_SOUND
         };
 
         // Settings moved to Settings.Secure
diff --git a/core/java/android/speech/RecognizerIntent.java b/core/java/android/speech/RecognizerIntent.java
index 457e66c..e991d84 100644
--- a/core/java/android/speech/RecognizerIntent.java
+++ b/core/java/android/speech/RecognizerIntent.java
@@ -55,7 +55,10 @@
      * <p>Starting this intent with just {@link Activity#startActivity(Intent)} is not supported.
      * You must either use {@link Activity#startActivityForResult(Intent, int)}, or provide a
      * PendingIntent, to receive recognition results.
-     * 
+     *
+     * <p>The implementation of this API is likely to stream audio to remote servers to perform
+     * speech recognition which can use a substantial amount of bandwidth.
+     *
      * <p>Required extras:
      * <ul>
      *   <li>{@link #EXTRA_LANGUAGE_MODEL}
diff --git a/core/java/android/speech/SpeechRecognizer.java b/core/java/android/speech/SpeechRecognizer.java
index 8fee41d..94aedbd 100644
--- a/core/java/android/speech/SpeechRecognizer.java
+++ b/core/java/android/speech/SpeechRecognizer.java
@@ -39,8 +39,14 @@
  * This class provides access to the speech recognition service. This service allows access to the
  * speech recognizer. Do not instantiate this class directly, instead, call
  * {@link SpeechRecognizer#createSpeechRecognizer(Context)}. This class's methods must be
- * invoked only from the main application thread. Please note that the application must have
- * {@link android.Manifest.permission#RECORD_AUDIO} permission to use this class.
+ * invoked only from the main application thread. 
+ *
+ * <p>The implementation of this API is likely to stream audio to remote servers to perform speech
+ * recognition. As such this API is not intended to be used for continuous recognition, which would
+ * consume a significant amount of battery and bandwidth.
+ *
+ * <p>Please note that the application must have {@link android.Manifest.permission#RECORD_AUDIO}
+ * permission to use this class.
  */
 public class SpeechRecognizer {
     /** DEBUG value to enable verbose debug prints */
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index 59df183..8ea9d48 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -122,6 +122,10 @@
     // Whether this transition is currently paused, due to a call to pause()
     boolean mPaused = false;
 
+    // Whether this transition has ended. Used to avoid pause/resume on transitions
+    // that have completed
+    private boolean mEnded = false;
+
     // The set of listeners to be sent transition lifecycle events.
     ArrayList<TransitionListener> mListeners = null;
 
@@ -914,21 +918,23 @@
      * @hide
      */
     public void pause() {
-        ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
-        int numOldAnims = runningAnimators.size();
-        for (int i = numOldAnims - 1; i >= 0; i--) {
-            Animator anim = runningAnimators.keyAt(i);
-            anim.pause();
-        }
-        if (mListeners != null && mListeners.size() > 0) {
-            ArrayList<TransitionListener> tmpListeners =
-                    (ArrayList<TransitionListener>) mListeners.clone();
-            int numListeners = tmpListeners.size();
-            for (int i = 0; i < numListeners; ++i) {
-                tmpListeners.get(i).onTransitionPause(this);
+        if (!mEnded) {
+            ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+            int numOldAnims = runningAnimators.size();
+            for (int i = numOldAnims - 1; i >= 0; i--) {
+                Animator anim = runningAnimators.keyAt(i);
+                anim.pause();
             }
+            if (mListeners != null && mListeners.size() > 0) {
+                ArrayList<TransitionListener> tmpListeners =
+                        (ArrayList<TransitionListener>) mListeners.clone();
+                int numListeners = tmpListeners.size();
+                for (int i = 0; i < numListeners; ++i) {
+                    tmpListeners.get(i).onTransitionPause(this);
+                }
+            }
+            mPaused = true;
         }
-        mPaused = true;
     }
 
     /**
@@ -940,18 +946,20 @@
      */
     public void resume() {
         if (mPaused) {
-            ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
-            int numOldAnims = runningAnimators.size();
-            for (int i = numOldAnims - 1; i >= 0; i--) {
-                Animator anim = runningAnimators.keyAt(i);
-                anim.resume();
-            }
-            if (mListeners != null && mListeners.size() > 0) {
-                ArrayList<TransitionListener> tmpListeners =
-                        (ArrayList<TransitionListener>) mListeners.clone();
-                int numListeners = tmpListeners.size();
-                for (int i = 0; i < numListeners; ++i) {
-                    tmpListeners.get(i).onTransitionResume(this);
+            if (!mEnded) {
+                ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+                int numOldAnims = runningAnimators.size();
+                for (int i = numOldAnims - 1; i >= 0; i--) {
+                    Animator anim = runningAnimators.keyAt(i);
+                    anim.resume();
+                }
+                if (mListeners != null && mListeners.size() > 0) {
+                    ArrayList<TransitionListener> tmpListeners =
+                            (ArrayList<TransitionListener>) mListeners.clone();
+                    int numListeners = tmpListeners.size();
+                    for (int i = 0; i < numListeners; ++i) {
+                        tmpListeners.get(i).onTransitionResume(this);
+                    }
                 }
             }
             mPaused = false;
@@ -1071,6 +1079,7 @@
                     tmpListeners.get(i).onTransitionStart(this);
                 }
             }
+            mEnded = false;
         }
         mNumInstances++;
     }
@@ -1111,6 +1120,7 @@
                     v.setHasTransientState(false);
                 }
             }
+            mEnded = true;
         }
     }
 
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index ba64f6b..f215189 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -34,6 +34,8 @@
 import android.os.Trace;
 import android.util.DisplayMetrics;
 import android.util.Log;
+import android.view.Surface.OutOfResourcesException;
+
 import com.google.android.gles_jni.EGLImpl;
 
 import javax.microedition.khronos.egl.EGL10;
@@ -74,7 +76,7 @@
      * System property used to enable or disable dirty regions invalidation.
      * This property is only queried if {@link #RENDER_DIRTY_REGIONS} is true.
      * The default value of this property is assumed to be true.
-     * 
+     *
      * Possible values:
      * "true", to enable partial invalidates
      * "false", to disable partial invalidates
@@ -134,7 +136,7 @@
 
     /**
      * System property used to debug EGL configuration choice.
-     * 
+     *
      * Possible values:
      * "choice", print the chosen configuration only
      * "all", print all possible configurations
@@ -147,7 +149,7 @@
      * Possible values:
      * "true", to enable dirty regions debugging
      * "false", to disable dirty regions debugging
-     * 
+     *
      * @hide
      */
     public static final String DEBUG_DIRTY_REGIONS_PROPERTY = "debug.hwui.show_dirty_regions";
@@ -208,14 +210,14 @@
     /**
      * A process can set this flag to false to prevent the use of hardware
      * rendering.
-     * 
+     *
      * @hide
      */
     public static boolean sRendererDisabled = false;
 
     /**
      * Further hardware renderer disabling for the system process.
-     * 
+     *
      * @hide
      */
     public static boolean sSystemRendererDisabled = false;
@@ -235,7 +237,7 @@
 
     /**
      * Invoke this method to disable hardware rendering in the current process.
-     * 
+     *
      * @hide
      */
     public static void disable(boolean system) {
@@ -248,7 +250,7 @@
     /**
      * Indicates whether hardware acceleration is available under any form for
      * the view hierarchy.
-     * 
+     *
      * @return True if the view hierarchy can potentially be hardware accelerated,
      *         false otherwise
      */
@@ -258,30 +260,30 @@
 
     /**
      * Destroys the hardware rendering context.
-     * 
+     *
      * @param full If true, destroys all associated resources.
      */
     abstract void destroy(boolean full);
 
     /**
      * Initializes the hardware renderer for the specified surface.
-     * 
+     *
      * @param surface The surface to hardware accelerate
-     * 
+     *
      * @return True if the initialization was successful, false otherwise.
      */
-    abstract boolean initialize(Surface surface) throws Surface.OutOfResourcesException;
-    
+    abstract boolean initialize(Surface surface) throws OutOfResourcesException;
+
     /**
      * Updates the hardware renderer for the specified surface.
      *
      * @param surface The surface to hardware accelerate
      */
-    abstract void updateSurface(Surface surface) throws Surface.OutOfResourcesException;
+    abstract void updateSurface(Surface surface) throws OutOfResourcesException;
 
     /**
      * Destroys the layers used by the specified view hierarchy.
-     * 
+     *
      * @param view The root of the view hierarchy
      */
     abstract void destroyLayers(View view);
@@ -289,11 +291,11 @@
     /**
      * Destroys all hardware rendering resources associated with the specified
      * view hierarchy.
-     * 
+     *
      * @param view The root of the view hierarchy
      */
     abstract void destroyHardwareResources(View view);
-    
+
     /**
      * This method should be invoked whenever the current hardware renderer
      * context should be reset.
@@ -306,7 +308,7 @@
      * This method should be invoked to ensure the hardware renderer is in
      * valid state (for instance, to ensure the correct EGL context is bound
      * to the current thread.)
-     * 
+     *
      * @return true if the renderer is now valid, false otherwise
      */
     abstract boolean validate();
@@ -314,7 +316,7 @@
     /**
      * This method ensures the hardware renderer is in a valid state
      * before executing the specified action.
-     * 
+     *
      * This method will attempt to set a valid state even if the window
      * the renderer is attached to was destroyed.
      *
@@ -325,7 +327,7 @@
     /**
      * Setup the hardware renderer for drawing. This is called whenever the
      * size of the target surface changes or when the surface is first created.
-     * 
+     *
      * @param width Width of the drawing surface.
      * @param height Height of the drawing surface.
      */
@@ -384,7 +386,7 @@
     /**
      * Sets the directory to use as a persistent storage for hardware rendering
      * resources.
-     * 
+     *
      * @param cacheDir A directory the current process can write to
      *
      * @hide
@@ -447,7 +449,7 @@
     /**
      * Indicates that the specified hardware layer needs to be updated
      * as soon as possible.
-     * 
+     *
      * @param layer The hardware layer that needs an update
      *
      * @see #flushLayerUpdates()
@@ -481,7 +483,7 @@
          * Invoked before a view is drawn by a hardware renderer.
          * This method can be used to apply transformations to the
          * canvas but no drawing command should be issued.
-         * 
+         *
          * @param canvas The Canvas used to render the view.
          */
         void onHardwarePreDraw(HardwareCanvas canvas);
@@ -489,7 +491,7 @@
         /**
          * Invoked after a view is drawn by a hardware renderer.
          * It is safe to invoke drawing commands from this method.
-         * 
+         *
          * @param canvas The Canvas used to render the view.
          */
         void onHardwarePostDraw(HardwareCanvas canvas);
@@ -509,9 +511,9 @@
     /**
      * Creates a new display list that can be used to record batches of
      * drawing operations.
-     * 
+     *
      * @param name The name of the display list, used for debugging purpose. May be null.
-     * 
+     *
      * @return A new display list.
      *
      * @hide
@@ -521,20 +523,20 @@
     /**
      * Creates a new hardware layer. A hardware layer built by calling this
      * method will be treated as a texture layer, instead of as a render target.
-     * 
+     *
      * @param isOpaque Whether the layer should be opaque or not
-     * 
+     *
      * @return A hardware layer
      */
     abstract HardwareLayer createHardwareLayer(boolean isOpaque);
 
     /**
      * Creates a new hardware layer.
-     * 
+     *
      * @param width The minimum width of the layer
      * @param height The minimum height of the layer
      * @param isOpaque Whether the layer should be opaque or not
-     * 
+     *
      * @return A hardware layer
      */
     abstract HardwareLayer createHardwareLayer(int width, int height, boolean isOpaque);
@@ -544,7 +546,7 @@
      * specified hardware layer.
      *
      * @param layer The layer to render into using a {@link android.graphics.SurfaceTexture}
-     * 
+     *
      * @return A {@link SurfaceTexture}
      */
     abstract SurfaceTexture createSurfaceTexture(HardwareLayer layer);
@@ -560,11 +562,11 @@
 
     /**
      * Detaches the specified functor from the current functor execution queue.
-     * 
+     *
      * @param functor The native functor to remove from the execution queue.
-     *                
-     * @see HardwareCanvas#callDrawGLFunction(int) 
-     * @see #attachFunctor(android.view.View.AttachInfo, int) 
+     *
+     * @see HardwareCanvas#callDrawGLFunction(int)
+     * @see #attachFunctor(android.view.View.AttachInfo, int)
      */
     abstract void detachFunctor(int functor);
 
@@ -591,12 +593,12 @@
      * @param width The width of the drawing surface.
      * @param height The height of the drawing surface.
      * @param surface The surface to hardware accelerate
-     *                
+     *
      * @return true if the surface was initialized, false otherwise. Returning
      *         false might mean that the surface was already initialized.
      */
     boolean initializeIfNeeded(int width, int height, Surface surface)
-            throws Surface.OutOfResourcesException {
+            throws OutOfResourcesException {
         if (isRequested()) {
             // We lost the gl context, so recreate it.
             if (!isEnabled()) {
@@ -618,10 +620,10 @@
 
     /**
      * Creates a hardware renderer using OpenGL.
-     * 
+     *
      * @param glVersion The version of OpenGL to use (1 for OpenGL 1, 11 for OpenGL 1.1, etc.)
      * @param translucent True if the surface is translucent, false otherwise
-     * 
+     *
      * @return A hardware renderer backed by OpenGL.
      */
     static HardwareRenderer createGlRenderer(int glVersion, boolean translucent) {
@@ -636,7 +638,7 @@
      * Invoke this method when the system is running out of memory. This
      * method will attempt to recover as much memory as possible, based on
      * the specified hint.
-     * 
+     *
      * @param level Hint about the amount of memory that should be trimmed,
      *              see {@link android.content.ComponentCallbacks}
      */
@@ -649,7 +651,7 @@
      * Starts the process of trimming memory. Usually this call will setup
      * hardware rendering context and reclaim memory.Extra cleanup might
      * be required by calling {@link #endTrimMemory()}.
-     * 
+     *
      * @param level Hint about the amount of memory that should be trimmed,
      *              see {@link android.content.ComponentCallbacks}
      */
@@ -667,7 +669,7 @@
 
     /**
      * Indicates whether hardware acceleration is currently enabled.
-     * 
+     *
      * @return True if hardware acceleration is in use, false otherwise.
      */
     boolean isEnabled() {
@@ -676,7 +678,7 @@
 
     /**
      * Indicates whether hardware acceleration is currently enabled.
-     * 
+     *
      * @param enabled True if the hardware renderer is in use, false otherwise.
      */
     void setEnabled(boolean enabled) {
@@ -686,7 +688,7 @@
     /**
      * Indicates whether hardware acceleration is currently request but not
      * necessarily enabled yet.
-     * 
+     *
      * @return True if requested, false otherwise.
      */
     boolean isRequested() {
@@ -696,7 +698,7 @@
     /**
      * Indicates whether hardware acceleration is currently requested but not
      * necessarily enabled yet.
-     * 
+     *
      * @return True to request hardware acceleration, false otherwise.
      */
     void setRequested(boolean requested) {
@@ -837,7 +839,7 @@
         Thread mEglThread;
 
         EGLSurface mEglSurface;
-        
+
         GL mGl;
         HardwareCanvas mCanvas;
 
@@ -1050,7 +1052,7 @@
         }
 
         @Override
-        boolean initialize(Surface surface) throws Surface.OutOfResourcesException {
+        boolean initialize(Surface surface) throws OutOfResourcesException {
             if (isRequested() && !isEnabled()) {
                 boolean contextCreated = initializeEgl();
                 mGl = createEglSurface(surface);
@@ -1078,9 +1080,9 @@
             }
             return false;
         }
-        
+
         @Override
-        void updateSurface(Surface surface) throws Surface.OutOfResourcesException {
+        void updateSurface(Surface surface) throws OutOfResourcesException {
             if (isRequested() && isEnabled()) {
                 createEglSurface(surface);
             }
@@ -1094,15 +1096,15 @@
             synchronized (sEglLock) {
                 if (sEgl == null && sEglConfig == null) {
                     sEgl = (EGL10) EGLContext.getEGL();
-                    
+
                     // Get to the default display.
                     sEglDisplay = sEgl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
-                    
+
                     if (sEglDisplay == EGL_NO_DISPLAY) {
                         throw new RuntimeException("eglGetDisplay failed "
                                 + GLUtils.getEGLErrorString(sEgl.eglGetError()));
                     }
-                    
+
                     // We can now initialize EGL for that display
                     int[] version = new int[2];
                     if (!sEgl.eglInitialize(sEglDisplay, version)) {
@@ -1216,7 +1218,7 @@
             Log.d(LOG_TAG, "  CONFIG_CAVEAT = 0x" + Integer.toHexString(value[0]));
         }
 
-        GL createEglSurface(Surface surface) throws Surface.OutOfResourcesException {
+        GL createEglSurface(Surface surface) throws OutOfResourcesException {
             // Check preconditions.
             if (sEgl == null) {
                 throw new RuntimeException("egl not initialized");
@@ -1228,7 +1230,7 @@
                 throw new RuntimeException("eglConfig not initialized");
             }
             if (Thread.currentThread() != mEglThread) {
-                throw new IllegalStateException("HardwareRenderer cannot be used " 
+                throw new IllegalStateException("HardwareRenderer cannot be used "
                         + "from multiple threads");
             }
 
@@ -1394,8 +1396,8 @@
 
         boolean canDraw() {
             return mGl != null && mCanvas != null;
-        }        
-        
+        }
+
         int onPreDraw(Rect dirty) {
             return DisplayList.STATUS_DONE;
         }
@@ -1732,7 +1734,7 @@
          * Ensures the current EGL context and surface are the ones we expect.
          * This method throws an IllegalStateException if invoked from a thread
          * that did not initialize EGL.
-         * 
+         *
          * @return {@link #SURFACE_STATE_ERROR} if the correct EGL context cannot be made current,
          *         {@link #SURFACE_STATE_UPDATED} if the EGL context was changed or
          *         {@link #SURFACE_STATE_SUCCESS} if the EGL context was the correct one
diff --git a/core/java/android/view/IApplicationToken.aidl b/core/java/android/view/IApplicationToken.aidl
index 5f0600f..633b40f 100644
--- a/core/java/android/view/IApplicationToken.aidl
+++ b/core/java/android/view/IApplicationToken.aidl
@@ -23,7 +23,7 @@
     void windowsDrawn();
     void windowsVisible();
     void windowsGone();
-    boolean keyDispatchingTimedOut();
+    boolean keyDispatchingTimedOut(String reason);
     long getKeyDispatchingTimeout();
 }
 
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 409db84..1bfda2d 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -116,6 +116,7 @@
      *
      * @param surfaceTexture The {@link SurfaceTexture} that is updated by this
      * Surface.
+     * @throws OutOfResourcesException if the surface could not be created.
      */
     public Surface(SurfaceTexture surfaceTexture) {
         if (surfaceTexture == null) {
@@ -124,12 +125,7 @@
 
         synchronized (mLock) {
             mName = surfaceTexture.toString();
-            try {
-                setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture));
-            } catch (OutOfResourcesException ex) {
-                // We can't throw OutOfResourcesException because it would be an API change.
-                throw new RuntimeException(ex);
-            }
+            setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture));
         }
     }
 
@@ -229,9 +225,12 @@
      * The caller may also pass <code>null</code> instead, in the case where the
      * entire surface should be redrawn.
      * @return A canvas for drawing into the surface.
+     *
+     * @throws IllegalArgumentException If the inOutDirty rectangle is not valid.
+     * @throws OutOfResourcesException If the canvas cannot be locked.
      */
     public Canvas lockCanvas(Rect inOutDirty)
-            throws OutOfResourcesException, IllegalArgumentException {
+            throws Surface.OutOfResourcesException, IllegalArgumentException {
         synchronized (mLock) {
             checkNotReleasedLocked();
             if (mLockedObject != 0) {
@@ -239,7 +238,7 @@
                 // double-lock, but that won't happen if mNativeObject was updated.  We can't
                 // abandon the old mLockedObject because it might still be in use, so instead
                 // we just refuse to re-lock the Surface.
-                throw new RuntimeException("Surface was already locked");
+                throw new IllegalStateException("Surface was already locked");
             }
             mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
             return mCanvas;
@@ -266,7 +265,7 @@
                         Integer.toHexString(mLockedObject) +")");
             }
             if (mLockedObject == 0) {
-                throw new RuntimeException("Surface was not locked");
+                throw new IllegalStateException("Surface was not locked");
             }
             nativeUnlockCanvasAndPost(mLockedObject, canvas);
             nativeRelease(mLockedObject);
@@ -411,9 +410,11 @@
     }
 
     /**
-     * Exception thrown when a surface couldn't be created or resized.
+     * Exception thrown when a Canvas couldn't be locked with {@link Surface#lockCanvas}, or
+     * when a SurfaceTexture could not successfully be allocated.
      */
-    public static class OutOfResourcesException extends Exception {
+    @SuppressWarnings("serial")
+    public static class OutOfResourcesException extends RuntimeException {
         public OutOfResourcesException() {
         }
         public OutOfResourcesException(String name) {
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index dc31e0b..b22d5cf 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -24,6 +24,7 @@
 import android.os.IBinder;
 import android.os.SystemProperties;
 import android.util.Log;
+import android.view.Surface.OutOfResourcesException;
 
 /**
  * SurfaceControl
@@ -75,23 +76,12 @@
 
 
     private final CloseGuard mCloseGuard = CloseGuard.get();
-    private String mName;
+    private final String mName;
     int mNativeObject; // package visibility only for Surface.java access
 
     private static final boolean HEADLESS = "1".equals(
         SystemProperties.get("ro.config.headless", "0"));
 
-    /**
-     * Exception thrown when a surface couldn't be created or resized.
-     */
-    public static class OutOfResourcesException extends Exception {
-        public OutOfResourcesException() {
-        }
-        public OutOfResourcesException(String name) {
-            super(name);
-        }
-    }
-
     /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */
 
     /**
@@ -220,6 +210,8 @@
      * @param h The surface initial height.
      * @param flags The surface creation flags.  Should always include {@link #HIDDEN}
      * in the creation flags.
+     *
+     * @throws throws OutOfResourcesException If the SurfaceControl cannot be created.
      */
     public SurfaceControl(SurfaceSession session,
             String name, int w, int h, int format, int flags)
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 8b2b556..1e4b29f 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -43,7 +43,7 @@
  * You can control the format of this surface and, if you like, its size; the
  * SurfaceView takes care of placing the surface at the correct location on the
  * screen
- * 
+ *
  * <p>The surface is Z ordered so that it is behind the window holding its
  * SurfaceView; the SurfaceView punches a hole in its window to allow its
  * surface to be displayed. The view hierarchy will take care of correctly
@@ -52,7 +52,7 @@
  * buttons on top of the Surface, though note however that it can have an
  * impact on performance since a full alpha-blended composite will be performed
  * each time the Surface changes.
- * 
+ *
  * <p> The transparent region that makes the surface visible is based on the
  * layout positions in the view hierarchy. If the post-layout transform
  * properties are used to draw a sibling view on top of the SurfaceView, the
@@ -60,16 +60,16 @@
  *
  * <p>Access to the underlying surface is provided via the SurfaceHolder interface,
  * which can be retrieved by calling {@link #getHolder}.
- * 
+ *
  * <p>The Surface will be created for you while the SurfaceView's window is
  * visible; you should implement {@link SurfaceHolder.Callback#surfaceCreated}
  * and {@link SurfaceHolder.Callback#surfaceDestroyed} to discover when the
  * Surface is created and destroyed as the window is shown and hidden.
- * 
+ *
  * <p>One of the purposes of this class is to provide a surface in which a
  * secondary thread can render into the screen. If you are going to use it
  * this way, you need to be aware of some threading semantics:
- * 
+ *
  * <ul>
  * <li> All SurfaceView and
  * {@link SurfaceHolder.Callback SurfaceHolder.Callback} methods will be called
@@ -91,7 +91,7 @@
             = new ArrayList<SurfaceHolder.Callback>();
 
     final int[] mLocation = new int[2];
-    
+
     final ReentrantLock mSurfaceLock = new ReentrantLock();
     final Surface mSurface = new Surface();       // Current surface in use
     final Surface mNewSurface = new Surface();    // New surface we are switching to
@@ -106,13 +106,13 @@
     final Rect mOverscanInsets = new Rect();
     final Rect mContentInsets = new Rect();
     final Configuration mConfiguration = new Configuration();
-    
+
     static final int KEEP_SCREEN_ON_MSG = 1;
     static final int GET_NEW_SURFACE_MSG = 2;
     static final int UPDATE_WINDOW_MSG = 3;
-    
+
     int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
-    
+
     boolean mIsCreating = false;
 
     final Handler mHandler = new Handler() {
@@ -131,14 +131,15 @@
             }
         }
     };
-    
+
     final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener
             = new ViewTreeObserver.OnScrollChangedListener() {
+                    @Override
                     public void onScrollChanged() {
                         updateWindow(false, false);
                     }
             };
-            
+
     boolean mRequestedVisible = false;
     boolean mWindowVisibility = false;
     boolean mViewVisibility = false;
@@ -152,7 +153,7 @@
     boolean mHaveFrame = false;
     boolean mSurfaceCreated = false;
     long mLastLockTime = 0;
-    
+
     boolean mVisible = false;
     int mLeft = -1;
     int mTop = -1;
@@ -169,7 +170,7 @@
             new ViewTreeObserver.OnPreDrawListener() {
                 @Override
                 public boolean onPreDraw() {
-                    // reposition ourselves where the surface is 
+                    // reposition ourselves where the surface is
                     mHaveFrame = getWidth() > 0 && getHeight() > 0;
                     updateWindow(false, false);
                     return true;
@@ -181,7 +182,7 @@
         super(context);
         init();
     }
-    
+
     public SurfaceView(Context context, AttributeSet attrs) {
         super(context, attrs);
         init();
@@ -195,11 +196,11 @@
     private void init() {
         setWillNotDraw(true);
     }
-    
+
     /**
      * Return the SurfaceHolder providing access and control over this
      * SurfaceView's underlying surface.
-     * 
+     *
      * @return SurfaceHolder The holder of the surface.
      */
     public SurfaceHolder getHolder() {
@@ -285,7 +286,7 @@
                 : getDefaultSize(0, heightMeasureSpec);
         setMeasuredDimension(width, height);
     }
-    
+
     /** @hide */
     @Override
     protected boolean setFrame(int left, int top, int right, int bottom) {
@@ -299,7 +300,7 @@
         if (mWindowType == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
             return super.gatherTransparentRegion(region);
         }
-        
+
         boolean opaque = true;
         if ((mPrivateFlags & PFLAG_SKIP_DRAW) == 0) {
             // this view draws, remove it from the transparent region
@@ -350,10 +351,10 @@
      * regular surface view in the window (but still behind the window itself).
      * This is typically used to place overlays on top of an underlying media
      * surface view.
-     * 
+     *
      * <p>Note that this must be set before the surface view's containing
      * window is attached to the window manager.
-     * 
+     *
      * <p>Calling this overrides any previous call to {@link #setZOrderOnTop}.
      */
     public void setZOrderMediaOverlay(boolean isMediaOverlay) {
@@ -361,7 +362,7 @@
                 ? WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY
                 : WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
     }
-    
+
     /**
      * Control whether the surface view's surface is placed on top of its
      * window.  Normally it is placed behind the window, to allow it to
@@ -369,10 +370,10 @@
      * hierarchy.  By setting this, you cause it to be placed above the
      * window.  This means that none of the contents of the window this
      * SurfaceView is in will be visible on top of its surface.
-     * 
+     *
      * <p>Note that this must be set before the surface view's containing
      * window is attached to the window manager.
-     * 
+     *
      * <p>Calling this overrides any previous call to {@link #setZOrderMediaOverlay}.
      */
     public void setZOrderOnTop(boolean onTop) {
@@ -427,7 +428,7 @@
         if (mTranslator != null) {
             mSurface.setCompatibilityTranslator(mTranslator);
         }
-        
+
         int myWidth = mRequestedWidth;
         if (myWidth <= 0) myWidth = getWidth();
         int myHeight = mRequestedHeight;
@@ -458,7 +459,7 @@
                 mFormat = mRequestedFormat;
 
                 // Scaling/Translate window's layout here because mLayout is not used elsewhere.
-                
+
                 // Places the window relative
                 mLayout.x = mLeft;
                 mLayout.y = mTop;
@@ -467,7 +468,7 @@
                 if (mTranslator != null) {
                     mTranslator.translateLayoutParamsInAppWindowToScreen(mLayout);
                 }
-                
+
                 mLayout.format = mRequestedFormat;
                 mLayout.flags |=WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                               | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
@@ -489,7 +490,7 @@
                     mSession.addToDisplayWithoutInputChannel(mWindow, mWindow.mSeq, mLayout,
                             mVisible ? VISIBLE : GONE, display.getDisplayId(), mContentInsets);
                 }
-                
+
                 boolean realSizeChanged;
                 boolean reportDrawNeeded;
 
@@ -501,7 +502,7 @@
                     reportDrawNeeded = mReportDrawNeeded;
                     mReportDrawNeeded = false;
                     mDrawingStopped = !visible;
-    
+
                     if (DEBUG) Log.i(TAG, "Cur surface: " + mSurface);
 
                     relayoutResult = mSession.relayout(
@@ -527,7 +528,7 @@
                         mSurfaceFrame.right = (int) (mWinFrame.width() * appInvertedScale + 0.5f);
                         mSurfaceFrame.bottom = (int) (mWinFrame.height() * appInvertedScale + 0.5f);
                     }
-                    
+
                     final int surfaceWidth = mSurfaceFrame.right;
                     final int surfaceHeight = mSurfaceFrame.bottom;
                     realSizeChanged = mLastSurfaceWidth != surfaceWidth
@@ -667,10 +668,12 @@
             }
         }
 
+        @Override
         public void dispatchAppVisibility(boolean visible) {
             // The point of SurfaceView is to let the app control the surface.
         }
 
+        @Override
         public void dispatchGetNewSurface() {
             SurfaceView surfaceView = mSurfaceView.get();
             if (surfaceView != null) {
@@ -679,10 +682,12 @@
             }
         }
 
+        @Override
         public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) {
             Log.w("SurfaceView", "Unexpected focus in surface: focus=" + hasFocus + ", touchEnabled=" + touchEnabled);
         }
 
+        @Override
         public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
         }
 
@@ -690,30 +695,34 @@
         int mCurHeight = -1;
     }
 
-    private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
-        
+    private final SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
+
         private static final String LOG_TAG = "SurfaceHolder";
-        
+
+        @Override
         public boolean isCreating() {
             return mIsCreating;
         }
 
+        @Override
         public void addCallback(Callback callback) {
             synchronized (mCallbacks) {
-                // This is a linear search, but in practice we'll 
+                // This is a linear search, but in practice we'll
                 // have only a couple callbacks, so it doesn't matter.
-                if (mCallbacks.contains(callback) == false) {      
+                if (mCallbacks.contains(callback) == false) {
                     mCallbacks.add(callback);
                 }
             }
         }
 
+        @Override
         public void removeCallback(Callback callback) {
             synchronized (mCallbacks) {
                 mCallbacks.remove(callback);
             }
         }
-        
+
+        @Override
         public void setFixedSize(int width, int height) {
             if (mRequestedWidth != width || mRequestedHeight != height) {
                 mRequestedWidth = width;
@@ -722,6 +731,7 @@
             }
         }
 
+        @Override
         public void setSizeFromLayout() {
             if (mRequestedWidth != -1 || mRequestedHeight != -1) {
                 mRequestedWidth = mRequestedHeight = -1;
@@ -729,6 +739,7 @@
             }
         }
 
+        @Override
         public void setFormat(int format) {
 
             // for backward compatibility reason, OPAQUE always
@@ -745,15 +756,17 @@
         /**
          * @deprecated setType is now ignored.
          */
+        @Override
         @Deprecated
         public void setType(int type) { }
 
+        @Override
         public void setKeepScreenOn(boolean screenOn) {
             Message msg = mHandler.obtainMessage(KEEP_SCREEN_ON_MSG);
             msg.arg1 = screenOn ? 1 : 0;
             mHandler.sendMessage(msg);
         }
-        
+
         /**
          * Gets a {@link Canvas} for drawing into the SurfaceView's Surface
          *
@@ -763,6 +776,7 @@
          * The caller must redraw the entire surface.
          * @return A canvas for drawing into the surface.
          */
+        @Override
         public Canvas lockCanvas() {
             return internalLockCanvas(null);
         }
@@ -782,6 +796,7 @@
          * entire surface should be redrawn.
          * @return A canvas for drawing into the surface.
          */
+        @Override
         public Canvas lockCanvas(Rect inOutDirty) {
             return internalLockCanvas(inOutDirty);
         }
@@ -806,7 +821,7 @@
                 mLastLockTime = SystemClock.uptimeMillis();
                 return c;
             }
-            
+
             // If the Surface is not ready to be drawn, then return null,
             // but throttle calls to this function so it isn't called more
             // than every 100ms.
@@ -821,7 +836,7 @@
             }
             mLastLockTime = now;
             mSurfaceLock.unlock();
-            
+
             return null;
         }
 
@@ -831,15 +846,18 @@
          *
          * @param canvas The canvas previously obtained from {@link #lockCanvas}.
          */
+        @Override
         public void unlockCanvasAndPost(Canvas canvas) {
             mSurface.unlockCanvasAndPost(canvas);
             mSurfaceLock.unlock();
         }
 
+        @Override
         public Surface getSurface() {
             return mSurface;
         }
 
+        @Override
         public Rect getSurfaceFrame() {
             return mSurfaceFrame;
         }
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index cea7e49..107d2c6 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -702,6 +702,7 @@
             @Override
             public void run() {
                 mView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+                mView.buildLayer();
             }
         };
         final int currentLayerType = mView.getLayerType();
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index c7d61eb0..50d5d45 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -68,6 +68,7 @@
 import android.view.animation.Interpolator;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
+import android.view.Surface.OutOfResourcesException;
 import android.widget.Scroller;
 
 import com.android.internal.R;
@@ -187,7 +188,7 @@
     InputQueue mInputQueue;
     FallbackEventHandler mFallbackEventHandler;
     Choreographer mChoreographer;
-    
+
     final Rect mTempRect; // used in the transaction to not thrash the heap.
     final Rect mVisRect; // used to retrieve visible rect of focused view.
 
@@ -278,8 +279,8 @@
     volatile Object mLocalDragState;
     final PointF mDragPoint = new PointF();
     final PointF mLastTouchPoint = new PointF();
-    
-    private boolean mProfileRendering;    
+
+    private boolean mProfileRendering;
     private Choreographer.FrameCallback mRenderProfiler;
     private boolean mRenderProfilingEnabled;
 
@@ -291,7 +292,7 @@
     private int mFpsNumFrames;
 
     private final ArrayList<DisplayList> mDisplayLists = new ArrayList<DisplayList>();
-    
+
     /**
      * see {@link #playSoundEffect(int)}
      */
@@ -332,7 +333,7 @@
         int localValue;
         int localChanges;
     }
-    
+
     public ViewRootImpl(Context context, Display display) {
         mContext = context;
         mWindowSession = WindowManagerGlobal.getWindowSession();
@@ -383,13 +384,13 @@
             }
         }
     }
-    
+
     public static void addConfigCallback(ComponentCallbacks callback) {
         synchronized (sConfigCallbacks) {
             sConfigCallbacks.add(callback);
         }
     }
-    
+
     // FIXME for perf testing only
     private boolean mProfile = false;
 
@@ -514,7 +515,7 @@
                         attrs.restore();
                     }
                 }
-                
+
                 if (mTranslator != null) {
                     mTranslator.translateRectInScreenToAppWindow(mAttachInfo.mContentInsets);
                 }
@@ -680,7 +681,7 @@
         if (mTranslator != null) return;
 
         // Try to enable hardware acceleration if requested
-        final boolean hardwareAccelerated = 
+        final boolean hardwareAccelerated =
                 (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
 
         if (hardwareAccelerated) {
@@ -707,7 +708,7 @@
                 // Don't enable hardware acceleration when we're not on the main thread
                 if (!HardwareRenderer.sSystemRendererDisabled &&
                         Looper.getMainLooper() != Looper.myLooper()) {
-                    Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware " 
+                    Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware "
                             + "acceleration outside of the main thread, aborting");
                     return;
                 }
@@ -918,6 +919,7 @@
         return r.intersect(0, 0, mWidth, mHeight);
     }
 
+    @Override
     public void bringChildToFront(View child) {
     }
 
@@ -1152,9 +1154,9 @@
                 mLastInCompatMode = true;
             }
         }
-        
+
         mWindowAttributesChangesFlag = 0;
-        
+
         Rect frame = mWinFrame;
         if (mFirst) {
             mFullRedrawNeeded = true;
@@ -1522,7 +1524,7 @@
                             try {
                                 hwInitialized = mAttachInfo.mHardwareRenderer.initialize(
                                         mHolder.getSurface());
-                            } catch (Surface.OutOfResourcesException e) {
+                            } catch (OutOfResourcesException e) {
                                 handleOutOfResourcesException(e);
                                 return;
                             }
@@ -1549,7 +1551,7 @@
                     mFullRedrawNeeded = true;
                     try {
                         mAttachInfo.mHardwareRenderer.updateSurface(mHolder.getSurface());
-                    } catch (Surface.OutOfResourcesException e) {
+                    } catch (OutOfResourcesException e) {
                         handleOutOfResourcesException(e);
                         return;
                     }
@@ -1644,23 +1646,23 @@
                         || mHeight != host.getMeasuredHeight() || contentInsetsChanged) {
                     int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
                     int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
-    
+
                     if (DEBUG_LAYOUT) Log.v(TAG, "Ooops, something changed!  mWidth="
                             + mWidth + " measuredWidth=" + host.getMeasuredWidth()
                             + " mHeight=" + mHeight
                             + " measuredHeight=" + host.getMeasuredHeight()
                             + " coveredInsetsChanged=" + contentInsetsChanged);
-    
+
                      // Ask host how big it wants to be
                     performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
-    
+
                     // Implementation of weights from WindowManager.LayoutParams
                     // We just grow the dimensions as needed and re-measure if
                     // needs be
                     int width = host.getMeasuredWidth();
                     int height = host.getMeasuredHeight();
                     boolean measureAgain = false;
-    
+
                     if (lp.horizontalWeight > 0.0f) {
                         width += (int) ((mWidth - width) * lp.horizontalWeight);
                         childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width,
@@ -1673,14 +1675,14 @@
                                 MeasureSpec.EXACTLY);
                         measureAgain = true;
                     }
-    
+
                     if (measureAgain) {
                         if (DEBUG_LAYOUT) Log.v(TAG,
                                 "And hey let's measure once more: width=" + width
                                 + " height=" + height);
                         performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
                     }
-    
+
                     layoutRequested = true;
                 }
             }
@@ -1851,7 +1853,7 @@
                     }
                     mPendingTransitions.clear();
                 }
-    
+
                 performDraw();
             }
         } else {
@@ -2078,6 +2080,7 @@
         return validLayoutRequesters;
     }
 
+    @Override
     public void requestTransparentRegion(View child) {
         // the test below should not fail unless someone is messing with us
         checkThread();
@@ -2128,10 +2131,12 @@
     int mResizeAlpha;
     final Paint mResizePaint = new Paint();
 
+    @Override
     public void onHardwarePreDraw(HardwareCanvas canvas) {
         canvas.translate(0, -mHardwareYOffset);
     }
 
+    @Override
     public void onHardwarePostDraw(HardwareCanvas canvas) {
         if (mResizeBuffer != null) {
             mResizePaint.setAlpha(mResizeAlpha);
@@ -2365,7 +2370,7 @@
                     try {
                         attachInfo.mHardwareRenderer.initializeIfNeeded(mWidth, mHeight,
                                 mHolder.getSurface());
-                    } catch (Surface.OutOfResourcesException e) {
+                    } catch (OutOfResourcesException e) {
                         handleOutOfResourcesException(e);
                         return;
                     }
@@ -2741,6 +2746,7 @@
         mAccessibilityFocusedVirtualView = node;
     }
 
+    @Override
     public void requestChildFocus(View child, View focused) {
         if (DEBUG_INPUT_RESIZE) {
             Log.v(TAG, "Request child focus: focus now " + focused);
@@ -2749,6 +2755,7 @@
         scheduleTraversals();
     }
 
+    @Override
     public void clearChildFocus(View child) {
         if (DEBUG_INPUT_RESIZE) {
             Log.v(TAG, "Clearing child focus");
@@ -2762,6 +2769,7 @@
         return null;
     }
 
+    @Override
     public void focusableViewAvailable(View v) {
         checkThread();
         if (mView != null) {
@@ -2783,6 +2791,7 @@
         }
     }
 
+    @Override
     public void recomputeViewAttributes(View child) {
         checkThread();
         if (mView == child) {
@@ -3076,7 +3085,7 @@
                             try {
                                 mAttachInfo.mHardwareRenderer.initializeIfNeeded(
                                         mWidth, mHeight, mHolder.getSurface());
-                            } catch (Surface.OutOfResourcesException e) {
+                            } catch (OutOfResourcesException e) {
                                 Log.e(TAG, "OutOfResourcesException locking surface", e);
                                 try {
                                     if (!mWindowSession.outOfMemory(mWindow)) {
@@ -4990,7 +4999,7 @@
             // most recent data.
             mSeq = args.seq;
             mAttachInfo.mForceReportNewAttributes = true;
-            scheduleTraversals();            
+            scheduleTraversals();
         }
         if (mView == null) return;
         if (args.localChanges != 0) {
@@ -5080,7 +5089,7 @@
         if (restore) {
             params.restore();
         }
-        
+
         if (mTranslator != null) {
             mTranslator.translateRectInScreenToAppWinFrame(mWinFrame);
             mTranslator.translateRectInScreenToAppWindow(mPendingOverscanInsets);
@@ -5093,6 +5102,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public void playSoundEffect(int effectId) {
         checkThread();
 
@@ -5133,6 +5143,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public boolean performHapticFeedback(int effectId, boolean always) {
         try {
             return mWindowSession.performHapticFeedback(mWindow, effectId, always);
@@ -5144,6 +5155,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public View focusSearch(View focused, int direction) {
         checkThread();
         if (!(mView instanceof ViewGroup)) {
@@ -5155,7 +5167,7 @@
     public void debug() {
         mView.debug();
     }
-    
+
     public void dumpGfxInfo(int[] info) {
         info[0] = info[1] = 0;
         if (mView != null) {
@@ -5574,8 +5586,8 @@
 
     final class InvalidateOnAnimationRunnable implements Runnable {
         private boolean mPosted;
-        private ArrayList<View> mViews = new ArrayList<View>();
-        private ArrayList<AttachInfo.InvalidateInfo> mViewRects =
+        private final ArrayList<View> mViews = new ArrayList<View>();
+        private final ArrayList<AttachInfo.InvalidateInfo> mViewRects =
                 new ArrayList<AttachInfo.InvalidateInfo>();
         private View[] mTempViews;
         private AttachInfo.InvalidateInfo[] mTempViewRects;
@@ -5813,20 +5825,25 @@
         }
     }
 
+    @Override
     public boolean showContextMenuForChild(View originalView) {
         return false;
     }
 
+    @Override
     public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback) {
         return null;
     }
 
+    @Override
     public void createContextMenu(ContextMenu menu) {
     }
 
+    @Override
     public void childDrawableStateChanged(View child) {
     }
 
+    @Override
     public boolean requestSendAccessibilityEvent(View child, AccessibilityEvent event) {
         if (mView == null) {
             return false;
@@ -5958,10 +5975,12 @@
         }
     }
 
+    @Override
     public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
         // ViewAncestor never intercepts touch event, so this can be a no-op
     }
 
+    @Override
     public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
         final boolean scrolled = scrollToRectOrFocus(rectangle, immediate);
         if (rectangle != null) {
@@ -5977,6 +5996,7 @@
         return scrolled;
     }
 
+    @Override
     public void childHasTransientStateChanged(View child, boolean hasTransientState) {
         // Do nothing.
     }
@@ -5997,20 +6017,23 @@
             // Not currently interesting -- from changing between fixed and layout size.
         }
 
+        @Override
         public void setFormat(int format) {
             ((RootViewSurfaceTaker)mView).setSurfaceFormat(format);
         }
 
+        @Override
         public void setType(int type) {
             ((RootViewSurfaceTaker)mView).setSurfaceType(type);
         }
-        
+
         @Override
         public void onUpdateSurface() {
             // We take care of format and type changes on our own.
             throw new IllegalStateException("Shouldn't be here");
         }
 
+        @Override
         public boolean isCreating() {
             return mIsCreating;
         }
@@ -6020,7 +6043,8 @@
             throw new UnsupportedOperationException(
                     "Currently only support sizing from layout");
         }
-        
+
+        @Override
         public void setKeepScreenOn(boolean screenOn) {
             ((RootViewSurfaceTaker)mView).setSurfaceKeepScreenOn(screenOn);
         }
@@ -6035,6 +6059,7 @@
             mWindowSession = viewAncestor.mWindowSession;
         }
 
+        @Override
         public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
                 Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
@@ -6052,6 +6077,7 @@
             }
         }
 
+        @Override
         public void dispatchAppVisibility(boolean visible) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
@@ -6059,6 +6085,7 @@
             }
         }
 
+        @Override
         public void dispatchScreenState(boolean on) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
@@ -6066,6 +6093,7 @@
             }
         }
 
+        @Override
         public void dispatchGetNewSurface() {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
@@ -6073,6 +6101,7 @@
             }
         }
 
+        @Override
         public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
@@ -6089,6 +6118,7 @@
             }
         }
 
+        @Override
         public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
@@ -6119,14 +6149,16 @@
                 }
             }
         }
-        
+
+        @Override
         public void closeSystemDialogs(String reason) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
                 viewAncestor.dispatchCloseSystemDialogs(reason);
             }
         }
-        
+
+        @Override
         public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
                 boolean sync) {
             if (sync) {
@@ -6137,6 +6169,7 @@
             }
         }
 
+        @Override
         public void dispatchWallpaperCommand(String action, int x, int y,
                 int z, Bundle extras, boolean sync) {
             if (sync) {
@@ -6148,6 +6181,7 @@
         }
 
         /* Drag/drop */
+        @Override
         public void dispatchDragEvent(DragEvent event) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
@@ -6155,6 +6189,7 @@
             }
         }
 
+        @Override
         public void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility,
                 int localValue, int localChanges) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
@@ -6164,6 +6199,7 @@
             }
         }
 
+        @Override
         public void doneAnimating() {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
@@ -6178,50 +6214,63 @@
         }
     }
 
-    private SurfaceHolder mHolder = new SurfaceHolder() {
+    private final SurfaceHolder mHolder = new SurfaceHolder() {
         // we only need a SurfaceHolder for opengl. it would be nice
         // to implement everything else though, especially the callback
         // support (opengl doesn't make use of it right now, but eventually
         // will).
+        @Override
         public Surface getSurface() {
             return mSurface;
         }
 
+        @Override
         public boolean isCreating() {
             return false;
         }
 
+        @Override
         public void addCallback(Callback callback) {
         }
 
+        @Override
         public void removeCallback(Callback callback) {
         }
 
+        @Override
         public void setFixedSize(int width, int height) {
         }
 
+        @Override
         public void setSizeFromLayout() {
         }
 
+        @Override
         public void setFormat(int format) {
         }
 
+        @Override
         public void setType(int type) {
         }
 
+        @Override
         public void setKeepScreenOn(boolean screenOn) {
         }
 
+        @Override
         public Canvas lockCanvas() {
             return null;
         }
 
+        @Override
         public Canvas lockCanvas(Rect dirty) {
             return null;
         }
 
+        @Override
         public void unlockCanvasAndPost(Canvas canvas) {
         }
+        @Override
         public Rect getSurfaceFrame() {
             return null;
         }
@@ -6316,6 +6365,7 @@
      */
     final class AccessibilityInteractionConnectionManager
             implements AccessibilityStateChangeListener {
+        @Override
         public void onAccessibilityStateChanged(boolean enabled) {
             if (enabled) {
                 ensureConnection();
@@ -6491,6 +6541,7 @@
         public View mSource;
         public long mLastEventTimeMillis;
 
+        @Override
         public void run() {
             // The accessibility may be turned off while we were waiting so check again.
             if (AccessibilityManager.getInstance(mContext).isEnabled()) {
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 389d9d6..b239fbd 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1555,8 +1555,9 @@
             } else if (mItemCount != mAdapter.getCount()) {
                 throw new IllegalStateException("The content of the adapter has changed but "
                         + "ListView did not receive a notification. Make sure the content of "
-                        + "your adapter is not modified from a background thread, but only "
-                        + "from the UI thread. [in ListView(" + getId() + ", " + getClass() 
+                        + "your adapter is not modified from a background thread, but only from "
+                        + "the UI thread. Make sure your adapter calls notifyDataSetChanged() "
+                        + "when its content changes. [in ListView(" + getId() + ", " + getClass()
                         + ") with Adapter(" + mAdapter.getClass() + ")]");
             }
 
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index b87ed7a..b75d36f 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -412,6 +412,8 @@
     public void setAdapter(SpinnerAdapter adapter) {
         super.setAdapter(adapter);
 
+        mRecycler.clear();
+
         if (mPopup != null) {
             mPopup.setAdapter(new DropDownAdapter(adapter));
         } else {
@@ -426,9 +428,8 @@
         if (getChildCount() > 0) {
             child = getChildAt(0);
         } else if (mAdapter != null && mAdapter.getCount() > 0) {
-            child = makeAndAddView(0);
+            child = makeView(0, false);
             mRecycler.put(0, child);
-            removeAllViewsInLayout();
         }
 
         if (child != null) {
@@ -536,7 +537,7 @@
         mFirstPosition = mSelectedPosition;
 
         if (mAdapter != null) {
-            View sel = makeAndAddView(mSelectedPosition);
+            View sel = makeView(mSelectedPosition, true);
             int width = sel.getMeasuredWidth();
             int selectedOffset = childrenLeft;
             final int layoutDirection = getLayoutDirection();
@@ -571,17 +572,17 @@
      * from the old to new positions.
      *
      * @param position Position in the spinner for the view to obtain
-     * @return A view that has been added to the spinner
+     * @param addChild true to add the child to the spinner, false to obtain and configure only.
+     * @return A view for the given position
      */
-    private View makeAndAddView(int position) {
-
+    private View makeView(int position, boolean addChild) {
         View child;
 
         if (!mDataChanged) {
             child = mRecycler.get(position);
             if (child != null) {
                 // Position the view
-                setUpChild(child);
+                setUpChild(child, addChild);
 
                 return child;
             }
@@ -591,7 +592,7 @@
         child = mAdapter.getView(position, null, this);
 
         // Position the view
-        setUpChild(child);
+        setUpChild(child, addChild);
 
         return child;
     }
@@ -601,8 +602,9 @@
      * and fill out its layout paramters.
      *
      * @param child The view to position
+     * @param addChild true if the child should be added to the Spinner during setup
      */
-    private void setUpChild(View child) {
+    private void setUpChild(View child, boolean addChild) {
 
         // Respect layout params that are already in the view. Otherwise
         // make some up...
@@ -611,7 +613,9 @@
             lp = generateDefaultLayoutParams();
         }
 
-        addViewInLayout(child, 0, lp);
+        if (addChild) {
+            addViewInLayout(child, 0, lp);
+        }
 
         child.setSelected(hasFocus());
         if (mDisableChildrenWhenDisabled) {
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 1ff0d635..8cb152d 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -479,7 +479,13 @@
     if (fWrappedPixelRef) {
         // delegate java obj management to the wrapped ref
         fWrappedPixelRef->globalRef(localref);
-    } else if (fOnJavaHeap && sk_atomic_inc(&fGlobalRefCnt) == 0) {
+
+        // Note: we only ref and unref the wrapped AndroidPixelRef so that
+        // bitmap->pixelRef()->globalRef() and globalUnref() can be used in a pair, even if
+        // the bitmap has its underlying AndroidPixelRef swapped out/wrapped
+        return;
+    }
+    if (fOnJavaHeap && sk_atomic_inc(&fGlobalRefCnt) == 0) {
         JNIEnv *env = vm2env(fVM);
 
         // If JNI ref was passed, it is always used
@@ -506,7 +512,9 @@
     if (fWrappedPixelRef) {
         // delegate java obj management to the wrapped ref
         fWrappedPixelRef->globalUnref();
-    } else if (fOnJavaHeap && sk_atomic_dec(&fGlobalRefCnt) == 1) {
+        return;
+    }
+    if (fOnJavaHeap && sk_atomic_dec(&fGlobalRefCnt) == 1) {
         JNIEnv *env = vm2env(fVM);
         if (!fHasGlobalRef) {
             SkDebugf("We don't have a global ref!");
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index bacfdf6..0c9b3bc 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -37,7 +37,7 @@
 namespace android {
 
 static const char* const OutOfResourcesException =
-    "android/graphics/SurfaceTexture$OutOfResourcesException";
+    "android/view/Surface$OutOfResourcesException";
 static const char* const IllegalStateException = "java/lang/IllegalStateException";
 const char* const kSurfaceTextureClassPathName = "android/graphics/SurfaceTexture";
 
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 05ca120..d2ada7a 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1379,9 +1379,6 @@
              component specific values). -->
         <attr name="enabled" />
         <attr name="exported" />
-        <!-- If set to true, onProvideAssistData will be called on this service when this service
-             is running in the foreground. -->
-        <attr name="provideAssistData" format="boolean" />
         <!-- If set to true, this service with be automatically stopped
              when the user remove a task rooted in an activity owned by
              the application.  The default is false. -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 1b4a083..cd1402c 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2077,6 +2077,5 @@
   <public type="attr" name="supportsSwitchingToNextInputMethod" />
   <public type="attr" name="requireDeviceUnlock" />
   <public type="attr" name="apduServiceBanner" />
-  <public type="attr" name="provideAssistData" />
 
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index aa04bf6..18ac09d 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -831,7 +831,7 @@
     <string name="permlab_getTopActivityInfo">get current app info</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_getTopActivityInfo">Allows the holder to retrieve private information
-        about the current application and services in the foreground of the screen.</string>
+        about the current application in the foreground of the screen.</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_runSetActivityWatcher">monitor and control all app launching</string>
diff --git a/data/fonts/fallback_fonts.xml b/data/fonts/fallback_fonts.xml
index d9170c9..1198aba 100644
--- a/data/fonts/fallback_fonts.xml
+++ b/data/fonts/fallback_fonts.xml
@@ -175,6 +175,12 @@
     </family>
     <family>
         <fileset>
+            <file>Padauk-book.ttf</file>
+            <file>Padauk-bookbold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
             <file>NotoSansSymbols-Regular.ttf</file>
         </fileset>
     </family>
diff --git a/docs/html/guide/topics/ui/how-android-draws.jd b/docs/html/guide/topics/ui/how-android-draws.jd
index 6a8cd86..168f77b 100644
--- a/docs/html/guide/topics/ui/how-android-draws.jd
+++ b/docs/html/guide/topics/ui/how-android-draws.jd
@@ -4,15 +4,19 @@
 @jd:body
 
 
-<p>When an Activity receives focus, it will be requested to draw its layout.
-The Android framework will handle the procedure for drawing, but the Activity must provide
+<p>When an {@link android.app.Activity} receives focus, it will be requested to 
+draw its layout.
+The Android framework will handle the procedure for drawing, but the 
+{@link android.app.Activity} must provide
 the root node of its layout hierarchy.</p>
 
 <p>Drawing begins with the root node of the layout. It is requested to measure and 
-draw the layout tree. Drawing is handled by walking the tree and rendering each View that
-   intersects the invalid region. In turn, each View group is responsible for requesting
-each of its children to be drawn (with the <code>{@link android.view.View#draw(Canvas) draw()}</code> method) 
-and each View is responsible for drawing itself.
+draw the layout tree. Drawing is handled by walking the tree and rendering each 
+{@link android.view.View} that intersects the invalid region. In turn, each 
+{@link android.view.ViewGroup} is responsible for requesting
+each of its children to be drawn 
+(with the {@link android.view.View#draw(Canvas) draw()} method) 
+and each {@link android.view.View} is responsible for drawing itself.
  Because the tree is traversed in-order,
    this means that parents will be drawn before (i.e., behind) their children, with
    siblings drawn in the order they appear in the tree.
@@ -20,76 +24,107 @@
 
 <div class="sidebox-wrapper">
 <div class="sidebox">
-  <p>The framework will not draw Views that are not in the invalid region, and also 
-   will take care of drawing the Views background for you.</p>
-   <p>You can force a View to draw, by calling <code>{@link android.view.View#invalidate()}</code>.
+  <p>The framework will not draw {@link android.view.View} objects that are not 
+in the invalid region, and also 
+   will take care of drawing the {@link android.view.View} background for you.</p>
+   <p>You can force a {@link android.view.View} to draw, by calling 
+{@link android.view.View#invalidate()}.
    </p>
 </div>
 </div>
 
 <p>
-   Drawing the layout is a two pass process: a measure pass and a layout pass. The measuring
-   pass is implemented in <code>{@link android.view.View#measure(int, int)}</code> and is a top-down traversal
-   of the View tree. Each View pushes dimension specifications down the tree
-   during the recursion. At the end of the measure pass, every View has stored
+   Drawing the layout is a two pass process: a measure pass and a layout pass. 
+The measuring pass is implemented in {@link android.view.View#measure(int, int)} 
+and is a top-down traversal of the {@link android.view.View} tree. Each {@link android.view.View} 
+pushes dimension specifications down the tree
+   during the recursion. At the end of the measure pass, every 
+{@link android.view.View} has stored
    its measurements. The second pass happens in
-   <code>{@link android.view.View#layout(int,int,int,int)}</code> and is also top-down. During
+   {@link android.view.View#layout(int,int,int,int)} and is also top-down. During
    this pass each parent is responsible for positioning all of its children
    using the sizes computed in the measure pass.
    </p>
    
    <p>
-   When a View's <code>measure()</code> method returns, its <code>{@link android.view.View#getMeasuredWidth()}</code> and
-   <code>{@link android.view.View#getMeasuredHeight()}</code> values must be set, along with those for all of
-   that View's descendants. A View's measured width and measured height values
-   must respect the constraints imposed by the View's parents. This guarantees
+   When a {@link android.view.View} object's 
+{@link android.view.View#measure(int, int) measure()} method 
+returns, its {@link android.view.View#getMeasuredWidth()} and
+   {@link android.view.View#getMeasuredHeight()} values must be set, along 
+   with those for all of that {@link android.view.View} object's descendants. 
+A {@link android.view.View} object's measured width and 
+measured height values must respect the constraints imposed by the 
+{@link android.view.View} object's parents. This guarantees
    that at the end of the measure pass, all parents accept all of their
-   children's measurements. A parent View may call <code>measure()</code> more than once on
+   children's measurements. A parent {@link android.view.View} may call 
+{@link android.view.View#measure(int, int) measure()} more than once on
    its children. For example, the parent may measure each child once with
    unspecified dimensions to find out how big they want to be, then call
-   <code>measure()</code> on them again with actual numbers if the sum of all the children's
-   unconstrained sizes is too big or too small (i.e., if the children don't agree among themselves
-  as to how much space they each get, the parent will intervene and set the rules on the second pass).
+   {@link android.view.View#measure(int, int) measure()} on them again with 
+actual numbers if the sum of all the children's
+   unconstrained sizes is too big or too small (that is, if the children 
+don't agree among themselves
+  as to how much space they each get, the parent will intervene and set 
+the rules on the second pass).
    </p>
    
 <div class="sidebox-wrapper">
 <div class="sidebox"><p>
-   To initiate a layout, call <code>{@link android.view.View#requestLayout}</code>. This method is typically
-   called by a View on itself when it believes that is can no longer fit within
+   To initiate a layout, call {@link android.view.View#requestLayout}. 
+This method is typically
+   called by a {@link android.view.View} on itself 
+when it believes that is can no longer fit within
    its current bounds.</p>
 </div>
 </div>
 
    <p>
    The measure pass uses two classes to communicate dimensions. The
-   {@link android.view.ViewGroup.LayoutParams} class is used by Views to tell their parents how they
-   want to be measured and positioned. The base LayoutParams class just
-   describes how big the View wants to be for both width and height. For each
+   {@link android.view.ViewGroup.LayoutParams} class is used by 
+{@link android.view.View} objects to tell their parents how they
+   want to be measured and positioned. The base 
+{@link android.view.ViewGroup.LayoutParams}  class just
+   describes how big the {@link android.view.View} wants to be for both 
+width and height. For each
    dimension, it can specify one of:</p>
    <ul>
     <li> an exact number
-    <li><var>FILL_PARENT</var>, which means the View wants to be as big as its parent
+    <li>{@link android.view.ViewGroup.LayoutParams#MATCH_PARENT MATCH_PARENT}, 
+which means the {@link android.view.View} wants to be as big as its parent
     (minus padding)</li>
-    <li><var>WRAP_CONTENT</var>, which means that the View wants to be just big enough to
+    <li>{@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT WRAP_CONTENT}, 
+which means that the {@link android.view.View} wants to be just big enough to
     enclose its content (plus padding).</li>
    </ul>
-  <p>There are subclasses of LayoutParams for different subclasses of ViewGroup.
-   For example, RelativeLayout has its own subclass of LayoutParams, which includes
-   the ability to center child Views horizontally and vertically.
+  <p>There are subclasses of {@link android.view.ViewGroup.LayoutParams} for 
+different subclasses of {@link android.view.ViewGroup}.
+   For example, {@link android.widget.RelativeLayout} has its own subclass of 
+{@link android.view.ViewGroup.LayoutParams}, which includes
+   the ability to center child {@link android.view.View} objects 
+horizontally and vertically.
    </p>
    
    <p>
-   MeasureSpecs are used to push requirements down the tree from parent to
-   child. A MeasureSpec can be in one of three modes:</p>
+   {@link android.view.View.MeasureSpec MeasureSpec} objects are used to push 
+requirements down the tree from parent to
+   child. A {@link android.view.View.MeasureSpec MeasureSpec} can be in one of 
+three modes:</p>
    <ul>
-    <li><var>UNSPECIFIED</var>: This is used by a parent to determine the desired dimension
-    of a child View. For example, a LinearLayout may call <code>measure()</code> on its child
-    with the height set to <var>UNSPECIFIED</var> and a width of <var>EXACTLY</var> 240 to find out how
-    tall the child View wants to be given a width of 240 pixels.</li>
-    <li><var>EXACTLY</var>: This is used by the parent to impose an exact size on the
+    <li>{@link android.view.View.MeasureSpec#UNSPECIFIED UNSPECIFIED}: This is 
+used by a parent to determine the desired dimension
+    of a child {@link android.view.View}. For example, a 
+{@link android.widget.LinearLayout} may call 
+{@link android.view.View#measure(int, int) measure()} on its child
+    with the height set to {@link android.view.View.MeasureSpec#UNSPECIFIED UNSPECIFIED} 
+and a width of {@link android.view.View.MeasureSpec#EXACTLY EXACTLY} 240 to 
+find out how tall the child {@link android.view.View} wants to be given a 
+width of 240 pixels.</li>
+    <li>{@link android.view.View.MeasureSpec#EXACTLY EXACTLY}: This is used 
+by the parent to impose an exact size on the
     child. The child must use this size, and guarantee that all of its
     descendants will fit within this size.</li>
-    <li><var>AT_MOST</var>: This is used by the parent to impose a maximum size on the
+    <li>{@link android.view.View.MeasureSpec#AT_MOST AT MOST}: This is used by 
+the parent to impose a maximum size on the
     child. The child must guarantee that it and all of its descendants will fit
     within this size.</li>
    </ul>
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index e8d6f16..b910a24 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -21,6 +21,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.view.Surface;
 
 /**
  * Captures frames from an image stream as an OpenGL ES texture.
@@ -80,8 +81,12 @@
     }
 
     /**
-     * Exception thrown when a surface couldn't be created or resized
+     * Exception thrown when a SurfaceTexture couldn't be created or resized.
+     *
+     * @deprecated No longer thrown. {@link Surface.OutOfResourcesException} is used instead.
      */
+    @SuppressWarnings("serial")
+    @Deprecated
     public static class OutOfResourcesException extends Exception {
         public OutOfResourcesException() {
         }
@@ -94,6 +99,8 @@
      * Construct a new SurfaceTexture to stream images to a given OpenGL texture.
      *
      * @param texName the OpenGL texture object name (e.g. generated via glGenTextures)
+     *
+     * @throws OutOfResourcesException If the SurfaceTexture cannot be created.
      */
     public SurfaceTexture(int texName) {
         init(texName, false);
@@ -113,6 +120,8 @@
      *
      * @param texName the OpenGL texture object name (e.g. generated via glGenTextures)
      * @param singleBufferMode whether the SurfaceTexture will be in single buffered mode.
+     *
+     * @throws throws OutOfResourcesException If the SurfaceTexture cannot be created.
      */
     public SurfaceTexture(int texName, boolean singleBufferMode) {
         init(texName, singleBufferMode);
@@ -140,9 +149,9 @@
      * 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.
-     * 
+     *
      * The width and height parameters must be no greater than the minimum of
-     * GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see 
+     * GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see
      * {@link javax.microedition.khronos.opengles.GL10#glGetIntegerv glGetIntegerv}).
      * An error due to invalid dimensions might not be reported until
      * updateTexImage() is called.
@@ -267,6 +276,7 @@
         nativeRelease();
     }
 
+    @Override
     protected void finalize() throws Throwable {
         try {
             nativeFinalize();
@@ -305,7 +315,7 @@
         }
     }
 
-    private void init(int texName, boolean singleBufferMode) {
+    private void init(int texName, boolean singleBufferMode) throws Surface.OutOfResourcesException {
         Looper looper;
         if ((looper = Looper.myLooper()) != null) {
             mEventHandler = new EventHandler(looper);
@@ -317,7 +327,8 @@
         nativeInit(texName, singleBufferMode, new WeakReference<SurfaceTexture>(this));
     }
 
-    private native void nativeInit(int texName, boolean singleBufferMode, Object weakSelf);
+    private native void nativeInit(int texName, boolean singleBufferMode, Object weakSelf)
+            throws Surface.OutOfResourcesException;
     private native void nativeFinalize();
     private native void nativeGetTransformMatrix(float[] mtx);
     private native long nativeGetTimestamp();
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index e8456af..7e99a5f 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -732,7 +732,7 @@
 
         if (mRs == 0) {
             mRs = new RSC::RS();
-            if (!mRs->init(RSC::RS_INIT_LOW_LATENCY & RSC::RS_INIT_SYNCHRONOUS)) {
+            if (!mRs->init(RSC::RS_INIT_LOW_LATENCY | RSC::RS_INIT_SYNCHRONOUS)) {
                 ALOGE("blur RS failed to init");
             }
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 238d9a4..2066f69 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -471,12 +471,14 @@
     info.height = getSnapshot()->height;
     getSnapshot()->transform->copyTo(&info.transform[0]);
 
+    bool dirtyClip = mDirtyClip;
     // setup GL state for functor
     if (mDirtyClip) {
-        setScissorFromClip();
         setStencilFromClip(); // can issue draws, so must precede enableScissor()/interrupt()
     }
-    mCaches.enableScissor();
+    if (mCaches.enableScissor() || dirtyClip) {
+        setScissorFromClip();
+    }
     interrupt();
 
     // call functor immediately after GL state setup
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 1dcf0e9..d1f7156 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -551,10 +551,10 @@
         IAudioService service = getService();
         try {
             if (mUseMasterVolume) {
-                service.adjustMasterVolume(direction, flags, mContext.getBasePackageName());
+                service.adjustMasterVolume(direction, flags, mContext.getOpPackageName());
             } else {
                 service.adjustStreamVolume(streamType, direction, flags,
-                        mContext.getBasePackageName());
+                        mContext.getOpPackageName());
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Dead object in adjustStreamVolume", e);
@@ -582,9 +582,9 @@
         IAudioService service = getService();
         try {
             if (mUseMasterVolume) {
-                service.adjustMasterVolume(direction, flags, mContext.getBasePackageName());
+                service.adjustMasterVolume(direction, flags, mContext.getOpPackageName());
             } else {
-                service.adjustVolume(direction, flags, mContext.getBasePackageName());
+                service.adjustVolume(direction, flags, mContext.getOpPackageName());
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Dead object in adjustVolume", e);
@@ -612,10 +612,10 @@
         IAudioService service = getService();
         try {
             if (mUseMasterVolume) {
-                service.adjustMasterVolume(direction, flags, mContext.getBasePackageName());
+                service.adjustMasterVolume(direction, flags, mContext.getOpPackageName());
             } else {
                 service.adjustSuggestedStreamVolume(direction, suggestedStreamType, flags,
-                        mContext.getBasePackageName());
+                        mContext.getOpPackageName());
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Dead object in adjustSuggestedStreamVolume", e);
@@ -634,7 +634,7 @@
     public void adjustMasterVolume(int steps, int flags) {
         IAudioService service = getService();
         try {
-            service.adjustMasterVolume(steps, flags, mContext.getBasePackageName());
+            service.adjustMasterVolume(steps, flags, mContext.getOpPackageName());
         } catch (RemoteException e) {
             Log.e(TAG, "Dead object in adjustMasterVolume", e);
         }
@@ -786,9 +786,9 @@
         IAudioService service = getService();
         try {
             if (mUseMasterVolume) {
-                service.setMasterVolume(index, flags, mContext.getBasePackageName());
+                service.setMasterVolume(index, flags, mContext.getOpPackageName());
             } else {
-                service.setStreamVolume(streamType, index, flags, mContext.getBasePackageName());
+                service.setStreamVolume(streamType, index, flags, mContext.getOpPackageName());
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Dead object in setStreamVolume", e);
@@ -854,7 +854,7 @@
     public void setMasterVolume(int index, int flags) {
         IAudioService service = getService();
         try {
-            service.setMasterVolume(index, flags, mContext.getBasePackageName());
+            service.setMasterVolume(index, flags, mContext.getOpPackageName());
         } catch (RemoteException e) {
             Log.e(TAG, "Dead object in setMasterVolume", e);
         }
@@ -1569,7 +1569,7 @@
         IAudioService service = getService();
         try {
             service.adjustLocalOrRemoteStreamVolume(streamType, direction,
-                    mContext.getBasePackageName());
+                    mContext.getOpPackageName());
         } catch (RemoteException e) {
             Log.e(TAG, "Dead object in adjustLocalOrRemoteStreamVolume", e);
         }
@@ -1996,7 +1996,7 @@
         try {
             status = service.requestAudioFocus(streamType, durationHint, mICallBack,
                     mAudioFocusDispatcher, getIdForAudioFocusListener(l),
-                    mContext.getBasePackageName() /* package name */);
+                    mContext.getOpPackageName() /* package name */);
         } catch (RemoteException e) {
             Log.e(TAG, "Can't call requestAudioFocus() on AudioService due to "+e);
         }
@@ -2018,7 +2018,7 @@
         try {
             service.requestAudioFocus(streamType, durationHint, mICallBack, null,
                     MediaFocusControl.IN_VOICE_COMM_FOCUS_ID,
-                    mContext.getBasePackageName());
+                    mContext.getOpPackageName());
         } catch (RemoteException e) {
             Log.e(TAG, "Can't call requestAudioFocusForCall() on AudioService due to "+e);
         }
diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java
index 774964e..65a9308 100644
--- a/media/java/android/media/MediaMuxer.java
+++ b/media/java/android/media/MediaMuxer.java
@@ -92,6 +92,7 @@
             Object[] values);
     private static native void nativeSetOrientationHint(int nativeObject,
             int degrees);
+    private static native void nativeSetLocation(int nativeObject, int latitude, int longitude);
     private static native void nativeWriteSampleData(int nativeObject,
             int trackIndex, ByteBuffer byteBuf,
             int offset, int size, long presentationTimeUs, int flags);
@@ -165,6 +166,41 @@
     }
 
     /**
+     * Set and store the geodata (latitude and longitude) in the output file.
+     * This method should be called before {@link #start}. The geodata is stored
+     * in udta box if the output format is
+     * {@link OutputFormat#MUXER_OUTPUT_MPEG_4}, and is ignored for other output
+     * formats. The geodata is stored according to ISO-6709 standard.
+     *
+     * @param latitude Latitude in degrees. Its value must be in the range [-90,
+     * 90].
+     * @param longitude Longitude in degrees. Its value must be in the range
+     * [-180, 180].
+     * @throws IllegalArgumentException If the given latitude or longitude is out
+     * of range.
+     * @throws IllegalStateException If this method is called after {@link #start}.
+     */
+    public void setLocation(float latitude, float longitude) {
+        int latitudex10000  = (int) (latitude * 10000 + 0.5);
+        int longitudex10000 = (int) (longitude * 10000 + 0.5);
+
+        if (latitudex10000 > 900000 || latitudex10000 < -900000) {
+            String msg = "Latitude: " + latitude + " out of range.";
+            throw new IllegalArgumentException(msg);
+        }
+        if (longitudex10000 > 1800000 || longitudex10000 < -1800000) {
+            String msg = "Longitude: " + longitude + " out of range";
+            throw new IllegalArgumentException(msg);
+        }
+
+        if (mState == MUXER_STATE_INITIALIZED && mNativeObject != 0) {
+            nativeSetLocation(mNativeObject, latitudex10000, longitudex10000);
+        } else {
+            throw new IllegalStateException("Can't set location due to wrong state.");
+        }
+    }
+
+    /**
      * Starts the muxer.
      * <p>Make sure this is called after {@link #addTrack} and before
      * {@link #writeSampleData}.</p>
diff --git a/media/jni/android_media_MediaMuxer.cpp b/media/jni/android_media_MediaMuxer.cpp
index 7517e85..457b956 100644
--- a/media/jni/android_media_MediaMuxer.cpp
+++ b/media/jni/android_media_MediaMuxer.cpp
@@ -164,6 +164,18 @@
 
 }
 
+static void android_media_MediaMuxer_setLocation(
+        JNIEnv *env, jclass clazz, jint nativeObject, jint latitude, jint longitude) {
+    MediaMuxer* muxer = reinterpret_cast<MediaMuxer *>(nativeObject);
+
+    status_t res = muxer->setLocation(latitude, longitude);
+    if (res != OK) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                          "Failed to set location");
+        return;
+    }
+}
+
 static void android_media_MediaMuxer_start(JNIEnv *env, jclass clazz,
                                            jint nativeObject) {
     sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject));
@@ -216,6 +228,9 @@
     { "nativeSetOrientationHint", "(II)V",
         (void *)android_media_MediaMuxer_setOrientationHint},
 
+    { "nativeSetLocation", "(III)V",
+        (void *)android_media_MediaMuxer_setLocation},
+
     { "nativeStart", "(I)V", (void *)android_media_MediaMuxer_start},
 
     { "nativeWriteSampleData", "(IILjava/nio/ByteBuffer;IIJI)V",
diff --git a/packages/DocumentsUI/res/layout/fragment_directory.xml b/packages/DocumentsUI/res/layout/fragment_directory.xml
index 881349b..f0ab0d1 100644
--- a/packages/DocumentsUI/res/layout/fragment_directory.xml
+++ b/packages/DocumentsUI/res/layout/fragment_directory.xml
@@ -24,8 +24,8 @@
         android:layout_height="match_parent"
         android:gravity="center"
         android:text="@string/empty"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:visibility="gone" />
+        android:visibility="gone"
+        style="@style/TextAppearance.Medium" />
 
     <ListView
         android:id="@+id/list"
diff --git a/packages/DocumentsUI/res/layout/item_doc_grid.xml b/packages/DocumentsUI/res/layout/item_doc_grid.xml
index 8d1fc9a..eea90b5 100644
--- a/packages/DocumentsUI/res/layout/item_doc_grid.xml
+++ b/packages/DocumentsUI/res/layout/item_doc_grid.xml
@@ -32,12 +32,26 @@
             android:layout_weight="1"
             android:background="#fff">
 
-            <ImageView
+            <FrameLayout
                 android:id="@android:id/icon"
                 android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:scaleType="centerInside"
-                android:contentDescription="@null" />
+                android:layout_height="match_parent">
+
+                <ImageView
+                    android:id="@+id/icon_mime"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:scaleType="centerInside"
+                    android:contentDescription="@null" />
+
+                <ImageView
+                    android:id="@+id/icon_thumb"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:scaleType="centerCrop"
+                    android:contentDescription="@null" />
+
+            </FrameLayout>
 
             <ImageView
                 android:layout_width="match_parent"
@@ -63,8 +77,8 @@
                 android:layout_weight="1"
                 android:singleLine="true"
                 android:ellipsize="marquee"
-                android:textAppearance="?android:attr/textAppearanceMedium"
-                android:textAlignment="viewStart" />
+                android:textAlignment="viewStart"
+                style="@style/TextAppearance.Medium" />
 
             <ImageView
                 android:id="@android:id/icon1"
@@ -93,7 +107,7 @@
                 android:singleLine="true"
                 android:ellipsize="marquee"
                 android:textAlignment="viewStart"
-                android:textAppearance="?android:attr/textAppearanceSmall" />
+                style="@style/TextAppearance.Small" />
 
             <TextView
                 android:id="@+id/size"
@@ -105,7 +119,7 @@
                 android:singleLine="true"
                 android:ellipsize="marquee"
                 android:textAlignment="viewStart"
-                android:textAppearance="?android:attr/textAppearanceSmall" />
+                style="@style/TextAppearance.Small" />
 
             <TextView
                 android:id="@android:id/summary"
@@ -117,7 +131,7 @@
                 android:singleLine="true"
                 android:ellipsize="marquee"
                 android:textAlignment="viewStart"
-                android:textAppearance="?android:attr/textAppearanceSmall" />
+                style="@style/TextAppearance.Small" />
 
         </LinearLayout>
 
diff --git a/packages/DocumentsUI/res/layout/item_doc_list.xml b/packages/DocumentsUI/res/layout/item_doc_list.xml
index 8372eed..84fda9d 100644
--- a/packages/DocumentsUI/res/layout/item_doc_list.xml
+++ b/packages/DocumentsUI/res/layout/item_doc_list.xml
@@ -25,15 +25,29 @@
     android:paddingBottom="8dip"
     android:orientation="horizontal">
 
-    <ImageView
+    <FrameLayout
         android:id="@android:id/icon"
         android:layout_width="@dimen/icon_size"
         android:layout_height="@dimen/icon_size"
         android:layout_marginStart="12dp"
         android:layout_marginEnd="20dp"
-        android:layout_gravity="center_vertical"
-        android:scaleType="centerInside"
-        android:contentDescription="@null" />
+        android:layout_gravity="center_vertical">
+
+        <ImageView
+            android:id="@+id/icon_mime"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:scaleType="centerInside"
+            android:contentDescription="@null" />
+
+        <ImageView
+            android:id="@+id/icon_thumb"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:scaleType="centerCrop"
+            android:contentDescription="@null" />
+
+    </FrameLayout>
 
     <LinearLayout
         android:layout_width="0dip"
@@ -54,8 +68,8 @@
                 android:layout_weight="1"
                 android:singleLine="true"
                 android:ellipsize="marquee"
-                android:textAppearance="?android:attr/textAppearanceMedium"
-                android:textAlignment="viewStart" />
+                android:textAlignment="viewStart"
+                style="@style/TextAppearance.Medium" />
 
             <ImageView
                 android:id="@android:id/icon1"
@@ -82,7 +96,7 @@
                 android:singleLine="true"
                 android:ellipsize="marquee"
                 android:textAlignment="viewStart"
-                android:textAppearance="?android:attr/textAppearanceSmall" />
+                style="@style/TextAppearance.Small" />
 
             <TextView
                 android:id="@+id/size"
@@ -94,7 +108,7 @@
                 android:singleLine="true"
                 android:ellipsize="marquee"
                 android:textAlignment="viewStart"
-                android:textAppearance="?android:attr/textAppearanceSmall" />
+                style="@style/TextAppearance.Small" />
 
             <TextView
                 android:id="@android:id/summary"
@@ -106,7 +120,7 @@
                 android:singleLine="true"
                 android:ellipsize="marquee"
                 android:textAlignment="viewStart"
-                android:textAppearance="?android:attr/textAppearanceSmall" />
+                style="@style/TextAppearance.Small" />
 
         </LinearLayout>
 
diff --git a/packages/DocumentsUI/res/layout/item_loading_grid.xml b/packages/DocumentsUI/res/layout/item_loading_grid.xml
new file mode 100644
index 0000000..21be137
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/item_loading_grid.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/grid_height"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:paddingTop="8dip"
+    android:paddingBottom="8dip"
+    android:orientation="horizontal">
+
+    <ProgressBar
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:indeterminate="true"
+        style="?android:attr/progressBarStyle" />
+
+</FrameLayout>
diff --git a/packages/DocumentsUI/res/layout/item_loading.xml b/packages/DocumentsUI/res/layout/item_loading_list.xml
similarity index 100%
rename from packages/DocumentsUI/res/layout/item_loading.xml
rename to packages/DocumentsUI/res/layout/item_loading_list.xml
diff --git a/packages/DocumentsUI/res/layout/item_message_grid.xml b/packages/DocumentsUI/res/layout/item_message_grid.xml
index 941340e..b3bdd28 100644
--- a/packages/DocumentsUI/res/layout/item_message_grid.xml
+++ b/packages/DocumentsUI/res/layout/item_message_grid.xml
@@ -16,44 +16,36 @@
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="180dip"
+    android:layout_height="@dimen/grid_height"
+    android:paddingTop="?android:attr/listPreferredItemPaddingStart"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
     android:paddingBottom="?android:attr/listPreferredItemPaddingEnd"
-    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+    android:foreground="@drawable/item_background">
 
-    <FrameLayout
+    <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:background="@color/chip"
-        android:foreground="@drawable/item_background"
-        android:duplicateParentState="true">
+        android:orientation="vertical"
+        android:gravity="center">
 
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:paddingBottom="6dp"
-            android:orientation="vertical"
-            android:gravity="center">
+        <ImageView
+            android:id="@android:id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:contentDescription="@null" />
 
-            <ImageView
-                android:id="@android:id/icon"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:contentDescription="@null" />
+        <TextView
+            android:id="@android:id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:maxLines="4"
+            android:ellipsize="end"
+            android:paddingTop="6dp"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textAlignment="viewStart" />
 
-            <TextView
-                android:id="@android:id/title"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:singleLine="true"
-                android:ellipsize="marquee"
-                android:paddingTop="6dp"
-                android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-                android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-                android:textAppearance="?android:attr/textAppearanceSmall"
-                android:textAlignment="viewStart" />
-
-        </LinearLayout>
-
-    </FrameLayout>
+    </LinearLayout>
 
 </FrameLayout>
diff --git a/packages/DocumentsUI/res/layout/item_message_list.xml b/packages/DocumentsUI/res/layout/item_message_list.xml
index dda3c80..ffda98c 100644
--- a/packages/DocumentsUI/res/layout/item_message_list.xml
+++ b/packages/DocumentsUI/res/layout/item_message_list.xml
@@ -39,9 +39,9 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
-        android:singleLine="true"
-        android:ellipsize="marquee"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:textAlignment="viewStart" />
+        android:maxLines="2"
+        android:ellipsize="end"
+        android:textAlignment="viewStart"
+        android:textAppearance="?android:attr/textAppearanceSmall" />
 
 </LinearLayout>
diff --git a/packages/DocumentsUI/res/layout/item_root.xml b/packages/DocumentsUI/res/layout/item_root.xml
index ce97b57..98d78da 100644
--- a/packages/DocumentsUI/res/layout/item_root.xml
+++ b/packages/DocumentsUI/res/layout/item_root.xml
@@ -43,8 +43,8 @@
             android:layout_height="wrap_content"
             android:singleLine="true"
             android:ellipsize="marquee"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textAlignment="viewStart" />
+            android:textAlignment="viewStart"
+            style="@style/TextAppearance.Medium" />
 
         <TextView
             android:id="@android:id/summary"
@@ -52,8 +52,8 @@
             android:layout_height="wrap_content"
             android:singleLine="true"
             android:ellipsize="marquee"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:textAlignment="viewStart" />
+            android:textAlignment="viewStart"
+            style="@style/TextAppearance.Small" />
 
     </LinearLayout>
 
diff --git a/packages/DocumentsUI/res/layout/item_root_header.xml b/packages/DocumentsUI/res/layout/item_root_header.xml
index 127b254..6b9857d 100644
--- a/packages/DocumentsUI/res/layout/item_root_header.xml
+++ b/packages/DocumentsUI/res/layout/item_root_header.xml
@@ -14,6 +14,14 @@
      limitations under the License.
 -->
 
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@android:id/title"
-    style="?android:attr/listSeparatorTextViewStyle" />
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingTop="12dp">
+
+    <TextView
+        android:id="@android:id/title"
+        android:textColor="?android:attr/textColorTertiary"
+        style="?android:attr/listSeparatorTextViewStyle" />
+
+</FrameLayout>
diff --git a/packages/DocumentsUI/res/layout/item_title.xml b/packages/DocumentsUI/res/layout/item_title.xml
index 9594e4e..7eb100a 100644
--- a/packages/DocumentsUI/res/layout/item_title.xml
+++ b/packages/DocumentsUI/res/layout/item_title.xml
@@ -38,7 +38,7 @@
         android:layout_height="wrap_content"
         android:singleLine="true"
         android:ellipsize="marquee"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:textAlignment="viewStart" />
+        android:textAlignment="viewStart"
+        style="@style/TextAppearance.Medium" />
 
 </LinearLayout>
diff --git a/packages/DocumentsUI/res/menu/mode_directory.xml b/packages/DocumentsUI/res/menu/mode_directory.xml
index 624e0247..0a3645f 100644
--- a/packages/DocumentsUI/res/menu/mode_directory.xml
+++ b/packages/DocumentsUI/res/menu/mode_directory.xml
@@ -21,12 +21,12 @@
         android:showAsAction="always" />
     <item
         android:id="@+id/menu_share"
-        android:icon="@android:drawable/ic_menu_share"
+        android:icon="@drawable/ic_menu_share"
         android:title="@string/menu_share"
         android:showAsAction="always" />
     <item
         android:id="@+id/menu_delete"
-        android:icon="@android:drawable/ic_menu_delete"
+        android:icon="@drawable/ic_menu_delete"
         android:title="@string/menu_delete"
         android:showAsAction="always" />
 </menu>
diff --git a/packages/DocumentsUI/res/values/strings.xml b/packages/DocumentsUI/res/values/strings.xml
index f4a822d..682ae4a 100644
--- a/packages/DocumentsUI/res/values/strings.xml
+++ b/packages/DocumentsUI/res/values/strings.xml
@@ -15,54 +15,83 @@
 -->
 
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Title of the documents application [CHAR LIMIT=32] -->
     <string name="app_label">Documents</string>
 
+    <!-- Action bar title prompting user to choose a location to open a document from [CHAR LIMIT=32] -->
     <string name="title_open">Open from</string>
+    <!-- Action bar title prompting user to choose a location to save a document to [CHAR LIMIT=32] -->
     <string name="title_save">Save to</string>
 
+    <!-- Menu item that creates a new directory/folder at the current location [CHAR LIMIT=24] -->
     <string name="menu_create_dir">Create folder</string>
+    <!-- Menu item that switches view to show documents as a large-format grid of thumbnails [CHAR LIMIT=24] -->
     <string name="menu_grid">Grid view</string>
+    <!-- Menu item that switches view to show documents as a list [CHAR LIMIT=24] -->
     <string name="menu_list">List view</string>
+    <!-- Menu item that switches the criteria with which documents are sorted [CHAR LIMIT=24] -->
     <string name="menu_sort">Sort by</string>
+    <!-- Menu item that enters a mode to search for documents [CHAR LIMIT=24] -->
     <string name="menu_search">Search</string>
+    <!-- Menu item that enters activity to change settings [CHAR LIMIT=24] -->
     <string name="menu_settings">Settings</string>
 
+    <!-- Menu item title that opens the selected documents [CHAR LIMIT=24] -->
     <string name="menu_open">Open</string>
+    <!-- Menu item title that saves the current document [CHAR LIMIT=24] -->
     <string name="menu_save">Save</string>
+    <!-- Menu item title that shares the selected documents [CHAR LIMIT=24] -->
     <string name="menu_share">Share</string>
+    <!-- Menu item title that deletes the selected documents [CHAR LIMIT=24] -->
     <string name="menu_delete">Delete</string>
 
+    <!-- Action mode title summarizing the number of documents selected [CHAR LIMIT=32] -->
     <string name="mode_selected_count"><xliff:g id="count" example="3">%1$d</xliff:g> selected</string>
 
+    <!-- Mode that sorts documents by their display name alphabetically [CHAR LIMIT=24] -->
     <string name="sort_name">By name</string>
+    <!-- Mode that sorts documents by their last modified time in descending order; most recent first [CHAR LIMIT=24] -->
     <string name="sort_date">By date modified</string>
+    <!-- Mode that sorts documents by their file size in descending order; largest first [CHAR LIMIT=24] -->
     <string name="sort_size">By size</string>
 
+    <!-- Accessibility title to open the drawer showing all roots where documents can be stored [CHAR LIMIT=32] -->
     <string name="drawer_open">Show roots</string>
+    <!-- Accessibility title to close the drawer showing all roots where documents can be stored [CHAR LIMIT=32] -->
     <string name="drawer_close">Hide roots</string>
 
+    <!-- Toast shown when saving a document failed with an error [CHAR LIMIT=48] -->
     <string name="save_error">Failed to save document</string>
 
+    <!-- Title of storage root location that contains recently modified or used documents [CHAR LIMIT=24] -->
     <string name="root_recent">Recent</string>
+    <!-- Subtitle of storage root indicating the total free space available, in bytes [CHAR LIMIT=24] -->
     <string name="root_available_bytes"><xliff:g id="size" example="3GB">%1$s</xliff:g> free</string>
 
-    <string name="root_type_service">Services</string>
+    <!-- Header title for list of storage roots that contains cloud services [CHAR LIMIT=24] -->
+    <string name="root_type_service">Storage services</string>
+    <!-- Header title for list of storage roots that contains shortcuts to documents that may be available elsewhere [CHAR LIMIT=24] -->
     <string name="root_type_shortcut">Shortcuts</string>
+    <!-- Header title for list of storage roots that contains physical devices [CHAR LIMIT=24] -->
     <string name="root_type_device">Devices</string>
+    <!-- Header title for list of additional apps that can provide documents [CHAR LIMIT=24] -->
     <string name="root_type_apps">More apps</string>
 
+    <!-- Title for setting that will show all advanced storage devices [CHAR LIMIT=32] -->
     <string name="pref_advanced_devices">Display advanced devices</string>
+    <!-- Title for setting that will show file sizes for all documents [CHAR LIMIT=32] -->
     <string name="pref_file_size">Display file size</string>
     <string name="pref_device_size">Display device size</string>
 
+    <!-- Text shown when a directory of documents is empty [CHAR LIMIT=24] -->
     <string name="empty">No items</string>
 
+    <!-- Toast shown when no app can be found to open the selected document [CHAR LIMIT=48] -->
     <string name="toast_no_application">Can\'t open file</string>
+    <!-- Toast shown when some of the selected documents failed to be deleted [CHAR LIMIT=48] -->
     <string name="toast_failed_delete">Unable to delete some documents</string>
 
-    <string name="more">More</string>
-    <string name="loading">Loading\u2026</string>
-
+    <!-- Title of dialog when prompting user to select an app to share documents with [CHAR LIMIT=32] -->
     <string name="share_via">Share via</string>
 
 </resources>
diff --git a/packages/DocumentsUI/res/values/styles.xml b/packages/DocumentsUI/res/values/styles.xml
new file mode 100644
index 0000000..59fbd6f
--- /dev/null
+++ b/packages/DocumentsUI/res/values/styles.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+
+<resources>
+    <style name="TextAppearance" />
+
+    <style name="TextAppearance.Medium">
+        <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
+        <item name="android:textColor">?android:attr/textColorSecondary</item>
+    </style>
+
+    <style name="TextAppearance.Small">
+        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
+        <item name="android:textColor">?android:attr/textColorTertiary</item>
+    </style>
+</resources>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index 45f028d..ba5a511 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -38,9 +38,11 @@
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.Point;
+import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.os.CancellationSignal;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
 import android.text.format.DateUtils;
@@ -56,6 +58,7 @@
 import android.view.ViewGroup;
 import android.widget.AbsListView;
 import android.widget.AbsListView.MultiChoiceModeListener;
+import android.widget.AbsListView.RecyclerListener;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.BaseAdapter;
@@ -97,6 +100,7 @@
 
     private int mLastMode = MODE_UNKNOWN;
     private int mLastSortOrder = SORT_ORDER_UNKNOWN;
+    private boolean mLastShowSize = false;
 
     private Point mThumbSize;
 
@@ -162,10 +166,12 @@
         mListView = (ListView) view.findViewById(R.id.list);
         mListView.setOnItemClickListener(mItemListener);
         mListView.setMultiChoiceModeListener(mMultiListener);
+        mListView.setRecyclerListener(mRecycleListener);
 
         mGridView = (GridView) view.findViewById(R.id.grid);
         mGridView.setOnItemClickListener(mItemListener);
         mGridView.setMultiChoiceModeListener(mMultiListener);
+        mGridView.setRecyclerListener(mRecycleListener);
 
         return view;
     }
@@ -192,13 +198,19 @@
                     case TYPE_NORMAL:
                         contentsUri = DocumentsContract.buildChildDocumentsUri(
                                 doc.authority, doc.documentId);
+                        if (state.action == ACTION_MANAGE) {
+                            contentsUri = DocumentsContract.setManageMode(contentsUri);
+                        }
                         return new DirectoryLoader(
-                                context, root, doc, contentsUri, state.userSortOrder);
+                                context, mType, root, doc, contentsUri, state.userSortOrder);
                     case TYPE_SEARCH:
                         contentsUri = DocumentsContract.buildSearchDocumentsUri(
                                 doc.authority, doc.documentId, query);
+                        if (state.action == ACTION_MANAGE) {
+                            contentsUri = DocumentsContract.setManageMode(contentsUri);
+                        }
                         return new DirectoryLoader(
-                                context, root, doc, contentsUri, state.userSortOrder);
+                                context, mType, root, doc, contentsUri, state.userSortOrder);
                     case TYPE_RECENT_OPEN:
                         final RootsCache roots = DocumentsApplication.getRootsCache(context);
                         final List<RootInfo> matchingRoots = roots.getMatchingRoots(state);
@@ -286,8 +298,9 @@
 
         mFilter = new MimePredicate(state.acceptMimes);
 
-        if (mLastMode == state.derivedMode) return;
+        if (mLastMode == state.derivedMode && mLastShowSize == state.showSize) return;
         mLastMode = state.derivedMode;
+        mLastShowSize = state.showSize;
 
         mListView.setVisibility(state.derivedMode == MODE_LIST ? View.VISIBLE : View.GONE);
         mGridView.setVisibility(state.derivedMode == MODE_GRID ? View.VISIBLE : View.GONE);
@@ -425,6 +438,20 @@
         }
     };
 
+    private RecyclerListener mRecycleListener = new RecyclerListener() {
+        @Override
+        public void onMovedToScrapHeap(View view) {
+            final ImageView iconThumb = (ImageView) view.findViewById(R.id.icon_thumb);
+            if (iconThumb != null) {
+                final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) iconThumb.getTag();
+                if (oldTask != null) {
+                    oldTask.reallyCancel();
+                    iconThumb.setTag(null);
+                }
+            }
+        }
+    };
+
     private void onShareDocuments(List<DocumentInfo> docs) {
         Intent intent;
         if (docs.size() == 1) {
@@ -500,7 +527,7 @@
         }
     }
 
-    private static class LoadingFooter extends Footer {
+    private class LoadingFooter extends Footer {
         public LoadingFooter() {
             super(1);
         }
@@ -508,10 +535,19 @@
         @Override
         public View getView(View convertView, ViewGroup parent) {
             final Context context = parent.getContext();
+            final State state = getDisplayState(DirectoryFragment.this);
+
             if (convertView == null) {
                 final LayoutInflater inflater = LayoutInflater.from(context);
-                convertView = inflater.inflate(R.layout.item_loading, parent, false);
+                if (state.derivedMode == MODE_LIST) {
+                    convertView = inflater.inflate(R.layout.item_loading_list, parent, false);
+                } else if (state.derivedMode == MODE_GRID) {
+                    convertView = inflater.inflate(R.layout.item_loading_grid, parent, false);
+                } else {
+                    throw new IllegalStateException();
+                }
             }
+
             return convertView;
         }
     }
@@ -632,7 +668,9 @@
             final String docSummary = getCursorString(cursor, Document.COLUMN_SUMMARY);
             final long docSize = getCursorLong(cursor, Document.COLUMN_SIZE);
 
-            final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
+            final View icon = convertView.findViewById(android.R.id.icon);
+            final ImageView iconMime = (ImageView) convertView.findViewById(R.id.icon_mime);
+            final ImageView iconThumb = (ImageView) convertView.findViewById(R.id.icon_thumb);
             final TextView title = (TextView) convertView.findViewById(android.R.id.title);
             final View line2 = convertView.findViewById(R.id.line2);
             final ImageView icon1 = (ImageView) convertView.findViewById(android.R.id.icon1);
@@ -640,30 +678,49 @@
             final TextView date = (TextView) convertView.findViewById(R.id.date);
             final TextView size = (TextView) convertView.findViewById(R.id.size);
 
-            final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) icon.getTag();
+            final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) iconThumb.getTag();
             if (oldTask != null) {
-                oldTask.cancel(false);
+                oldTask.reallyCancel();
+                iconThumb.setTag(null);
             }
 
+            iconMime.animate().cancel();
+            iconThumb.animate().cancel();
+
             final boolean supportsThumbnail = (docFlags & Document.FLAG_SUPPORTS_THUMBNAIL) != 0;
             final boolean allowThumbnail = (state.derivedMode == MODE_GRID)
                     || MimePredicate.mimeMatches(LIST_THUMBNAIL_MIMES, docMimeType);
 
+            boolean cacheHit = false;
             if (supportsThumbnail && allowThumbnail) {
                 final Uri uri = DocumentsContract.buildDocumentUri(docAuthority, docId);
                 final Bitmap cachedResult = thumbs.get(uri);
                 if (cachedResult != null) {
-                    icon.setImageBitmap(cachedResult);
+                    iconThumb.setImageBitmap(cachedResult);
+                    cacheHit = true;
                 } else {
-                    final ThumbnailAsyncTask task = new ThumbnailAsyncTask(icon, mThumbSize);
-                    icon.setImageBitmap(null);
-                    icon.setTag(task);
-                    task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, uri);
+                    iconThumb.setImageDrawable(null);
+                    final ThumbnailAsyncTask task = new ThumbnailAsyncTask(
+                            uri, iconMime, iconThumb, mThumbSize);
+                    iconThumb.setTag(task);
+                    task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
                 }
-            } else if (docIcon != 0) {
-                icon.setImageDrawable(IconUtils.loadPackageIcon(context, docAuthority, docIcon));
+            }
+
+            // Always throw MIME icon into place, even when a thumbnail is being
+            // loaded in background.
+            if (cacheHit) {
+                iconMime.setAlpha(0f);
+                iconThumb.setAlpha(1f);
             } else {
-                icon.setImageDrawable(IconUtils.loadMimeIcon(context, docMimeType));
+                iconMime.setAlpha(1f);
+                iconThumb.setAlpha(0f);
+                if (docIcon != 0) {
+                    iconMime.setImageDrawable(
+                            IconUtils.loadPackageIcon(context, docAuthority, docIcon));
+                } else {
+                    iconMime.setImageDrawable(IconUtils.loadMimeIcon(context, docMimeType));
+                }
             }
 
             title.setText(docDisplayName);
@@ -672,12 +729,19 @@
 
             if (mType == TYPE_RECENT_OPEN) {
                 final RootInfo root = roots.getRoot(docAuthority, docRootId);
+                final Drawable iconDrawable = root.loadIcon(context);
                 icon1.setVisibility(View.VISIBLE);
-                icon1.setImageDrawable(root.loadIcon(context));
-                summary.setText(root.getDirectoryString());
-                summary.setVisibility(View.VISIBLE);
-                summary.setTextAlignment(TextView.TEXT_ALIGNMENT_TEXT_END);
-                hasLine2 = true;
+                icon1.setImageDrawable(iconDrawable);
+
+                if (iconDrawable != null && roots.isIconUnique(root)) {
+                    // No summary needed if icon speaks for itself
+                    summary.setVisibility(View.INVISIBLE);
+                } else {
+                    summary.setText(root.getDirectoryString());
+                    summary.setVisibility(View.VISIBLE);
+                    summary.setTextAlignment(TextView.TEXT_ALIGNMENT_TEXT_END);
+                    hasLine2 = true;
+                }
             } else {
                 icon1.setVisibility(View.GONE);
                 if (docSummary != null) {
@@ -762,32 +826,39 @@
     }
 
     private static class ThumbnailAsyncTask extends AsyncTask<Uri, Void, Bitmap> {
-        private final ImageView mTarget;
+        private final Uri mUri;
+        private final ImageView mIconMime;
+        private final ImageView mIconThumb;
         private final Point mThumbSize;
+        private final CancellationSignal mSignal;
 
-        public ThumbnailAsyncTask(ImageView target, Point thumbSize) {
-            mTarget = target;
+        public ThumbnailAsyncTask(
+                Uri uri, ImageView iconMime, ImageView iconThumb, Point thumbSize) {
+            mUri = uri;
+            mIconMime = iconMime;
+            mIconThumb = iconThumb;
             mThumbSize = thumbSize;
+            mSignal = new CancellationSignal();
         }
 
-        @Override
-        protected void onPreExecute() {
-            mTarget.setTag(this);
+        public void reallyCancel() {
+            cancel(false);
+            mSignal.cancel();
         }
 
         @Override
         protected Bitmap doInBackground(Uri... params) {
-            final Context context = mTarget.getContext();
-            final Uri uri = params[0];
+            final Context context = mIconThumb.getContext();
 
             Bitmap result = null;
             try {
+                // TODO: switch to using unstable provider
                 result = DocumentsContract.getDocumentThumbnail(
-                        context.getContentResolver(), uri, mThumbSize, null);
+                        context.getContentResolver(), mUri, mThumbSize, mSignal);
                 if (result != null) {
                     final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache(
                             context, mThumbSize);
-                    thumbs.put(uri, result);
+                    thumbs.put(mUri, result);
                 }
             } catch (Exception e) {
                 Log.w(TAG, "Failed to load thumbnail: " + e);
@@ -797,9 +868,14 @@
 
         @Override
         protected void onPostExecute(Bitmap result) {
-            if (mTarget.getTag() == this) {
-                mTarget.setImageBitmap(result);
-                mTarget.setTag(null);
+            if (mIconThumb.getTag() == this && result != null) {
+                mIconThumb.setTag(null);
+                mIconThumb.setImageBitmap(result);
+
+                mIconMime.setAlpha(1f);
+                mIconMime.animate().alpha(0f).start();
+                mIconThumb.setAlpha(0f);
+                mIconThumb.animate().alpha(1f).start();
             }
         }
     }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
index 1471836..334e262 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
@@ -62,6 +62,7 @@
 public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {
     private final ForceLoadContentObserver mObserver = new ForceLoadContentObserver();
 
+    private final int mType;
     private final RootInfo mRoot;
     private final DocumentInfo mDoc;
     private final Uri mUri;
@@ -70,9 +71,10 @@
     private CancellationSignal mSignal;
     private DirectoryResult mResult;
 
-    public DirectoryLoader(
-            Context context, RootInfo root, DocumentInfo doc, Uri uri, int userSortOrder) {
+    public DirectoryLoader(Context context, int type, RootInfo root, DocumentInfo doc, Uri uri,
+            int userSortOrder) {
         super(context);
+        mType = type;
         mRoot = root;
         mDoc = doc;
         mUri = uri;
@@ -128,6 +130,11 @@
             }
         }
 
+        // Search always uses ranking from provider
+        if (mType == DirectoryFragment.TYPE_SEARCH) {
+            result.sortOrder = State.SORT_ORDER_UNKNOWN;
+        }
+
         Log.d(TAG, "userMode=" + userMode + ", userSortOrder=" + mUserSortOrder + " --> mode="
                 + result.mode + ", sortOrder=" + result.sortOrder);
 
@@ -137,11 +144,18 @@
                     mUri, null, null, null, getQuerySortOrder(result.sortOrder), mSignal);
             cursor.registerContentObserver(mObserver);
 
-            final Cursor withRoot = new RootCursorWrapper(
-                    mUri.getAuthority(), mRoot.rootId, cursor, -1);
-            final Cursor sorted = new SortingCursorWrapper(withRoot, result.sortOrder);
+            cursor = new RootCursorWrapper(mUri.getAuthority(), mRoot.rootId, cursor, -1);
 
-            result.cursor = sorted;
+            if (mType == DirectoryFragment.TYPE_SEARCH) {
+                // Filter directories out of search results, for now
+                cursor = new FilteringCursorWrapper(cursor, null, new String[] {
+                        Document.MIME_TYPE_DIR });
+            } else {
+                // Normal directories should have sorting applied
+                cursor = new SortingCursorWrapper(cursor, result.sortOrder);
+            }
+
+            result.cursor = cursor;
         } catch (Exception e) {
             Log.d(TAG, "Failed to query", e);
             result.exception = e;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index 79d2443..e89d388 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -50,6 +50,7 @@
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
+import android.view.MenuItem.OnActionExpandListener;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.BaseAdapter;
@@ -87,6 +88,7 @@
     private static final String EXTRA_STATE = "state";
 
     private boolean mIgnoreNextNavigation;
+    private boolean mIgnoreNextCollapse;
 
     private RootsCache mRoots;
     private State mState;
@@ -234,12 +236,14 @@
         public void onDrawerOpened(View drawerView) {
             mDrawerToggle.onDrawerOpened(drawerView);
             updateActionBar();
+            invalidateOptionsMenu();
         }
 
         @Override
         public void onDrawerClosed(View drawerView) {
             mDrawerToggle.onDrawerClosed(drawerView);
             updateActionBar();
+            invalidateOptionsMenu();
         }
 
         @Override
@@ -305,7 +309,6 @@
             public boolean onQueryTextSubmit(String query) {
                 mState.currentSearch = query;
                 onCurrentDirectoryChanged();
-                mSearchView.setIconified(true);
                 return true;
             }
 
@@ -315,12 +318,22 @@
             }
         });
 
-        mSearchView.setOnCloseListener(new OnCloseListener() {
+        searchMenu.setOnActionExpandListener(new OnActionExpandListener() {
             @Override
-            public boolean onClose() {
+            public boolean onMenuItemActionExpand(MenuItem item) {
+                return true;
+            }
+
+            @Override
+            public boolean onMenuItemActionCollapse(MenuItem item) {
+                if (mIgnoreNextCollapse) {
+                    mIgnoreNextCollapse = false;
+                    return true;
+                }
+
                 mState.currentSearch = null;
                 onCurrentDirectoryChanged();
-                return false;
+                return true;
             }
         });
 
@@ -342,6 +355,18 @@
         final MenuItem list = menu.findItem(R.id.menu_list);
         final MenuItem settings = menu.findItem(R.id.menu_settings);
 
+        // Open drawer means we hide most actions
+        if (mDrawerLayout.isDrawerOpen(mRootsContainer)) {
+            createDir.setVisible(false);
+            search.setVisible(false);
+            sort.setVisible(false);
+            grid.setVisible(false);
+            list.setVisible(false);
+            mIgnoreNextCollapse = true;
+            search.collapseActionView();
+            return true;
+        }
+
         if (cwd != null) {
             sort.setVisible(true);
             grid.setVisible(mState.derivedMode != MODE_GRID);
@@ -352,6 +377,17 @@
             list.setVisible(false);
         }
 
+        if (mState.currentSearch != null) {
+            // Search uses backend ranking; no sorting
+            sort.setVisible(false);
+
+            search.expandActionView();
+            mSearchView.setQuery(mState.currentSearch, false);
+        } else {
+            mIgnoreNextCollapse = true;
+            search.collapseActionView();
+        }
+
         // Only sort by size when visible
         sortSize.setVisible(mState.showSize);
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java
index 0a6cbc0..180ddef 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java
@@ -56,7 +56,11 @@
         packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
         packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
         packageFilter.addDataScheme("package");
-        registerReceiver(mPackageReceiver, packageFilter);
+        registerReceiver(mCacheReceiver, packageFilter);
+
+        final IntentFilter localeFilter = new IntentFilter();
+        localeFilter.addAction(Intent.ACTION_LOCALE_CHANGED);
+        registerReceiver(mCacheReceiver, localeFilter);
     }
 
     @Override
@@ -70,7 +74,7 @@
         }
     }
 
-    private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
+    private BroadcastReceiver mCacheReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             // TODO: narrow changed/removed to only packages that have backends
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilteringCursorWrapper.java b/packages/DocumentsUI/src/com/android/documentsui/FilteringCursorWrapper.java
index 60f0103..5f56963 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilteringCursorWrapper.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilteringCursorWrapper.java
@@ -34,6 +34,10 @@
     private int mCount;
 
     public FilteringCursorWrapper(Cursor cursor, String[] acceptMimes) {
+        this(cursor, acceptMimes, null);
+    }
+
+    public FilteringCursorWrapper(Cursor cursor, String[] acceptMimes, String[] rejectMimes) {
         mCursor = cursor;
 
         final int count = cursor.getCount();
@@ -43,6 +47,9 @@
         while (cursor.moveToNext()) {
             final String mimeType = cursor.getString(
                     cursor.getColumnIndex(Document.COLUMN_MIME_TYPE));
+            if (rejectMimes != null && MimePredicate.mimeMatches(rejectMimes, mimeType)) {
+                continue;
+            }
             if (MimePredicate.mimeMatches(acceptMimes, mimeType)) {
                 mPosition[mCount++] = cursor.getPosition();
             }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
index 3642478..140373b 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
@@ -183,12 +183,12 @@
                 convertView = inflater.inflate(R.layout.item_doc_list, parent, false);
             }
 
-            final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
+            final ImageView iconMime = (ImageView) convertView.findViewById(R.id.icon_mime);
             final TextView title = (TextView) convertView.findViewById(android.R.id.title);
             final View line2 = convertView.findViewById(R.id.line2);
 
             final DocumentStack stack = getItem(position);
-            icon.setImageDrawable(stack.root.loadIcon(context));
+            iconMime.setImageDrawable(stack.root.loadIcon(context));
 
             final Drawable crumb = context.getResources()
                     .getDrawable(R.drawable.ic_breadcrumb_arrow);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentsProvider.java b/packages/DocumentsUI/src/com/android/documentsui/RecentsProvider.java
index 1fe5d54..af79c93 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RecentsProvider.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentsProvider.java
@@ -151,18 +151,18 @@
             case URI_RECENT:
                 final long cutoff = System.currentTimeMillis() - MAX_HISTORY_IN_MILLIS;
                 return db.query(TABLE_RECENT, projection, RecentColumns.TIMESTAMP + ">" + cutoff,
-                        null, null, null, null);
+                        null, null, null, sortOrder);
             case URI_STATE:
                 final String authority = uri.getPathSegments().get(1);
                 final String rootId = uri.getPathSegments().get(2);
                 final String documentId = uri.getPathSegments().get(3);
                 return db.query(TABLE_STATE, projection, StateColumns.AUTHORITY + "=? AND "
                         + StateColumns.ROOT_ID + "=? AND " + StateColumns.DOCUMENT_ID + "=?",
-                        new String[] { authority, rootId, documentId }, null, null, null);
+                        new String[] { authority, rootId, documentId }, null, null, sortOrder);
             case URI_RESUME:
                 final String packageName = uri.getPathSegments().get(1);
                 return db.query(TABLE_RESUME, projection, ResumeColumns.PACKAGE_NAME + "=?",
-                        new String[] { packageName }, null, null, null);
+                        new String[] { packageName }, null, null, sortOrder);
             default:
                 throw new UnsupportedOperationException("Unsupported Uri " + uri);
         }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
index adf4701..b48674cf 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
@@ -109,6 +109,8 @@
                 }
             }
         }
+
+        Log.d(TAG, "Update found " + mRoots.size() + " roots");
     }
 
     @Deprecated
@@ -134,6 +136,21 @@
     }
 
     @GuardedBy("ActivityThread")
+    public boolean isIconUnique(RootInfo root) {
+        for (RootInfo test : mRoots) {
+            if (Objects.equal(test.authority, root.authority)) {
+                if (Objects.equal(test.rootId, root.rootId)) {
+                    continue;
+                }
+                if (test.icon == root.icon) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @GuardedBy("ActivityThread")
     public RootInfo getRecentsRoot() {
         return mRecentsRoot;
     }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
index efb972d..f3a21c6 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
@@ -25,6 +25,7 @@
 import android.content.pm.ResolveInfo;
 import android.os.Bundle;
 import android.provider.DocumentsContract.Root;
+import android.text.TextUtils;
 import android.text.format.Formatter;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -168,7 +169,7 @@
             }
 
             summary.setText(summaryText);
-            summary.setVisibility(summaryText != null ? View.VISIBLE : View.GONE);
+            summary.setVisibility(TextUtils.isEmpty(summaryText) ? View.GONE : View.VISIBLE);
 
             return convertView;
         }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
index e0e8acf..b5a198c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
@@ -26,6 +26,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.provider.DocumentsContract.Root;
+import android.text.TextUtils;
 
 import com.android.documentsui.IconUtils;
 import com.android.documentsui.R;
@@ -203,6 +204,6 @@
     }
 
     public String getDirectoryString() {
-        return (summary != null) ? summary : title;
+        return !TextUtils.isEmpty(summary) ? summary : title;
     }
 }
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 2326ec2..ada3ad7 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -267,16 +267,15 @@
 
         final LinkedList<File> pending = new LinkedList<File>();
         pending.add(parent);
-        while (!pending.isEmpty() && result.getCount() < 20) {
+        while (!pending.isEmpty() && result.getCount() < 24) {
             final File file = pending.removeFirst();
             if (file.isDirectory()) {
                 for (File child : file.listFiles()) {
                     pending.add(child);
                 }
-            } else {
-                if (file.getName().toLowerCase().contains(query)) {
-                    includeFile(result, null, file);
-                }
+            }
+            if (file.getName().toLowerCase().contains(query)) {
+                includeFile(result, null, file);
             }
         }
         return result;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 3f04470..344446f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -738,10 +738,12 @@
                 }
             }
 
+            // Intercept the keys and see if they need special handling
+            value = mSettingsHelper.onBackupValue(key, value);
+
             if (value == null) {
                 continue;
             }
-
             // Write the key and value in the intermediary array.
             byte[] keyBytes = key.getBytes();
             totalSize += INTEGER_BYTE_COUNT + keyBytes.length;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index a446e40..dd7a828 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -23,6 +23,8 @@
 import android.content.res.Configuration;
 import android.location.LocationManager;
 import android.media.AudioManager;
+import android.media.RingtoneManager;
+import android.net.Uri;
 import android.os.IPowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -33,6 +35,7 @@
 import java.util.Locale;
 
 public class SettingsHelper {
+    private static final String SILENT_RINGTONE = "_silent";
     private Context mContext;
     private AudioManager mAudioManager;
 
@@ -63,10 +66,60 @@
             setAutoRestore(Integer.parseInt(value) == 1);
         } else if (isAlreadyConfiguredCriticalAccessibilitySetting(name)) {
             return false;
+        } else if (Settings.System.RINGTONE.equals(name)
+                || Settings.System.NOTIFICATION_SOUND.equals(name)) {
+            setRingtone(name, value);
+            return false;
         }
         return true;
     }
 
+    public String onBackupValue(String name, String value) {
+        // Special processing for backing up ringtones
+        if (Settings.System.RINGTONE.equals(name)
+                || Settings.System.NOTIFICATION_SOUND.equals(name)) {
+            if (value == null) {
+                // Silent ringtone
+                return SILENT_RINGTONE;
+            } else {
+                return getCanonicalRingtoneValue(value);
+            }
+        }
+        // Return the original value
+        return value;
+    }
+
+    /**
+     * Sets the ringtone of type specified by the name.
+     *
+     * @param name should be Settings.System.RINGTONE or Settings.System.NOTIFICATION_SOUND.
+     * @param value can be a canonicalized uri or "_silent" to indicate a silent (null) ringtone.
+     */
+    private void setRingtone(String name, String value) {
+        // If it's null, don't change the default
+        if (value == null) return;
+        Uri ringtoneUri = null;
+        if (SILENT_RINGTONE.equals(value)) {
+            ringtoneUri = null;
+        } else {
+            Uri canonicalUri = Uri.parse(value);
+            ringtoneUri = mContext.getContentResolver().uncanonicalize(canonicalUri);
+            if (ringtoneUri == null) {
+                // Unrecognized or invalid Uri, don't restore
+                return;
+            }
+        }
+        final int ringtoneType = Settings.System.RINGTONE.equals(name)
+                ? RingtoneManager.TYPE_RINGTONE : RingtoneManager.TYPE_NOTIFICATION;
+        RingtoneManager.setActualDefaultRingtoneUri(mContext, ringtoneType, ringtoneUri);
+    }
+
+    private String getCanonicalRingtoneValue(String value) {
+        final Uri ringtoneUri = Uri.parse(value);
+        final Uri canonicalUri = mContext.getContentResolver().canonicalize(ringtoneUri);
+        return canonicalUri == null ? null : canonicalUri.toString();
+    }
+
     private boolean isAlreadyConfiguredCriticalAccessibilitySetting(String name) {
         // These are the critical accessibility settings that are required for a
         // blind user to be able to interact with the device. If these settings are
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_1.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_1.png
index 645ee4a..b226694 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_1.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_2.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_2.png
index 24d26c3..1e9fbfd 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_2.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_3.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_3.png
index b1cd0e3..0676919 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_3.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_4.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_4.png
index def0e23..3ad9e76 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_4.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_in.png
new file mode 100644
index 0000000..6ff215b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_inout.png
new file mode 100644
index 0000000..cf5e825
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_out.png
new file mode 100644
index 0000000..5d8fd07
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_1.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_1.png
index ac66075..c500691 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_1.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_2.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_2.png
index 0a49702..ae87896 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_2.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_3.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_3.png
index 380b1eb..e47ef7a 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_3.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_4.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_4.png
index 756ff1f..9fd1ae6 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_4.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_in.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_in.png
new file mode 100644
index 0000000..ebd2001
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_inout.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_inout.png
new file mode 100644
index 0000000..cf5e825
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_out.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_out.png
new file mode 100644
index 0000000..5d8fd07
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_15.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_15.png
index c779e7e..c971443 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_15.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1.png
index cf07aae..717711f 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2.png
index 50aa77f..cdf35b6 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3.png
index 045182c..ce90eb4 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4.png
index 5232169..39a109c 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1.png
index 2b0da2c..22f18a0 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2.png
index 24755d9..f7f0159 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3.png
index 3f30896..86b250c 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4.png
index 87da72b..f706343 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
index eeee60f..42c773d 100644
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_in.png
new file mode 100644
index 0000000..e6a2f17
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_inout.png
new file mode 100644
index 0000000..fd40015
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_out.png
new file mode 100644
index 0000000..0a6d20a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_1.png
index 395adad..79d3145 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_1.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_2.png
index 4ded9239..d83696f 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_2.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_3.png
index 568c296..b6b84a1 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_3.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_4.png
index 000f93d..35de22d 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_4.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_in.png
new file mode 100644
index 0000000..9c8f3e7c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_inout.png
new file mode 100644
index 0000000..7e773f0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_out.png
new file mode 100644
index 0000000..2ecfd0b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_1.png
index 33a35d0..e432210 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_1.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_2.png
index 71e396e..fc4dbb0 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_2.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_3.png
index b61b1e0..410e8f3 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_3.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_4.png
index 7121abb..e222ffd 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_4.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_in.png
new file mode 100644
index 0000000..f3245a0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_inout.png
new file mode 100644
index 0000000..9f02b9d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_out.png
new file mode 100644
index 0000000..8452087
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_1.png
index ef91328..584a73a 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_1.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_2.png
index ffb3b55..b90b421 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_2.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_3.png
index 85eef22..5fdf8348 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_3.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_4.png
index 5aeb913..ada740a 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_4.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_in.png
new file mode 100644
index 0000000..61b0df9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_inout.png
new file mode 100644
index 0000000..e450506
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_out.png
new file mode 100644
index 0000000..f8b63cb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_1.png
index dc4a01e..8103f4d 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_1.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_2.png
index bb6fd30..22d7a1c 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_2.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_3.png
index b77c833..29d3ab0 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_3.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_4.png
index 448d79b..6aa4854 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_4.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_1.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_1.png
index ae51eca..2994632 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_1.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_2.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_2.png
index 77dcdce..b111939 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_2.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_3.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_3.png
index aff279c..98c8e25 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_3.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_4.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_4.png
index e64d314..625dbd9 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_4.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_in.png
new file mode 100644
index 0000000..da4ffa2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_inout.png
new file mode 100644
index 0000000..e1c7972
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_out.png
new file mode 100644
index 0000000..b8c8b4e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_1.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_1.png
index cafb93d..60e38ad 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_1.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_2.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_2.png
index 55eccf0..8983380 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_2.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_3.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_3.png
index 989427b..ff652df 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_3.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_4.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_4.png
index f2d7963..8dd9c43 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_4.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_in.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_in.png
new file mode 100644
index 0000000..5d0ad7c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_inout.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_inout.png
new file mode 100644
index 0000000..e1c7972
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_out.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_out.png
new file mode 100644
index 0000000..b8c8b4e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_15.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_15.png
index 62807cd..b1b675b 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_15.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1.png
index c3c6b93..f3232a2 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2.png
index bb2e9ba..8dbee4b 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3.png
index 6583922..bef1f18 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4.png
index 9b1cbcc..163c740 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1.png
index 3fb4427..33ee9a6 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2.png
index abcc317..0b7cbde 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3.png
index a3b2678..a2aa045 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4.png
index b4278f2..de79d19 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png
index c73ff35..20c8785 100644
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_1.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_1.png
index 3bbfb4e..abc9358 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_1.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_2.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_2.png
index 7fc9bd4..0419144 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_2.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_3.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_3.png
index 56a9a13..515ffe7 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_3.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_4.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_4.png
index ad06e62..118de2d 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_4.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_in.png
new file mode 100644
index 0000000..46fd826
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_inout.png
new file mode 100644
index 0000000..c824b97
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_out.png
new file mode 100644
index 0000000..fb9ecd0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_1.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_1.png
index 94666a1..715e60a 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_1.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_2.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_2.png
index 8e19afd..ed7f5b9 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_2.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_3.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_3.png
index 62933b0..8f1464b 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_3.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_4.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_4.png
index e93292b..b32c676 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_4.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_in.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_in.png
new file mode 100644
index 0000000..6cf0a4b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_inout.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_inout.png
new file mode 100644
index 0000000..c824b97
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_out.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_out.png
new file mode 100644
index 0000000..fb9ecd0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_15.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_15.png
index 1e68ac7..94605c9 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_15.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_1.png
index 23288de..ac18139 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_1.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_2.png
index 32e05fe..587d93c 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_2.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_3.png
index f2f88a1..656d6d0 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_3.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_4.png
index 7a38994..e8033c8 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_4.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_1.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_1.png
index a93e3a8..1253a41 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_1.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_2.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_2.png
index 24b47b2..bcb20af 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_2.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_3.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_3.png
index b4b3f02..ca70a29 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_3.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_4.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_4.png
index 758ebe7..8ce2ae93 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_4.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png
index e931314..b4e129c 100644
--- a/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png
+++ b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_1.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_1.png
index 4a243ca..746b9ea 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_1.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_2.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_2.png
index 37841af..55ba5ab 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_2.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_3.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_3.png
index 39be463..547f875 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_3.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_4.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_4.png
index 5b9b7af..1f65ad5 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_4.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_in.png
new file mode 100644
index 0000000..1094bc3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_inout.png
new file mode 100644
index 0000000..1037b02
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_out.png
new file mode 100644
index 0000000..f5595e3b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_1.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_1.png
index 10818ba..01274a6 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_1.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_2.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_2.png
index 752fee1..a02832d 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_2.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_3.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_3.png
index 684372a..7e55bbb 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_3.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_4.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_4.png
index 9b4b8c7..eeb8989 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_4.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_in.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_in.png
new file mode 100644
index 0000000..7183a07
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_inout.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_inout.png
new file mode 100644
index 0000000..3746328
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_out.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_out.png
new file mode 100644
index 0000000..dbf54ce
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_15.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_15.png
index d026936..a2bab6d 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_15.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_1.png
index afacef5..ee20130 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_1.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_2.png
index 1b1c863..362d06d 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_2.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_3.png
index 99094e3..b1fd413 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_3.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_4.png
index 8aff999..1a1862a 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_4.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_1.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_1.png
index 3fe77d0..57a4228 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_1.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_2.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_2.png
index dec522d..c536e7b 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_2.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_3.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_3.png
index 9e679c2..01ff1b9 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_3.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_4.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_4.png
index f4c7250..f828068 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_4.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/layout/quick_settings_tile_rssi.xml b/packages/SystemUI/res/layout/quick_settings_tile_rssi.xml
index 34506b1..cabfaa5 100644
--- a/packages/SystemUI/res/layout/quick_settings_tile_rssi.xml
+++ b/packages/SystemUI/res/layout/quick_settings_tile_rssi.xml
@@ -13,32 +13,49 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<LinearLayout
+<RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:layout_gravity="top"
-    android:orientation="vertical">
+    android:layout_gravity="top">
     <FrameLayout
+        android:id="@+id/rssi_images"
         android:layout_marginTop="@dimen/qs_tile_margin_above_icon"
         android:layout_marginBottom="@dimen/qs_tile_margin_below_icon"
         android:layout_width="@dimen/qs_tile_icon_size"
         android:layout_height="@dimen/qs_tile_icon_size"
         android:layout_gravity="top|center_horizontal"
+        android:layout_centerHorizontal="true"
         >
         <ImageView
             android:id="@+id/rssi_image"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_gravity="center"
+            android:layout_centerInParent="true"
             />
         <ImageView
             android:id="@+id/rssi_overlay_image"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_gravity="center"
+            android:layout_centerInParent="true"
             />
     </FrameLayout>
+    <ImageView
+            android:id="@+id/activity_in"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_qs_signal_in"
+            android:layout_toRightOf="@id/rssi_images"
+            android:layout_alignBottom="@id/rssi_images"
+            />
+    <ImageView
+            android:id="@+id/activity_out"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_qs_signal_out"
+            android:layout_toRightOf="@id/rssi_images"
+            android:layout_alignBottom="@id/rssi_images"
+            />
     <TextView
         style="@style/TextAppearance.QuickSettings.TileView"
         android:id="@+id/rssi_textview"
@@ -47,5 +64,7 @@
         android:layout_gravity="top|center_horizontal"
         android:gravity="top|center_horizontal"
         android:text="@string/quick_settings_rssi_label"
+        android:layout_centerHorizontal="true"
+        android:layout_below="@id/rssi_images"
         />
-</LinearLayout>
\ No newline at end of file
+</RelativeLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/quick_settings_tile_wifi.xml b/packages/SystemUI/res/layout/quick_settings_tile_wifi.xml
new file mode 100644
index 0000000..e61c595
--- /dev/null
+++ b/packages/SystemUI/res/layout/quick_settings_tile_wifi.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_gravity="top">
+    <ImageView
+        android:id="@+id/image"
+        android:layout_marginTop="@dimen/qs_tile_margin_above_icon"
+        android:layout_marginBottom="@dimen/qs_tile_margin_below_icon"
+        android:layout_width="@dimen/qs_tile_icon_size"
+        android:layout_height="@dimen/qs_tile_icon_size"
+        android:layout_gravity="top|center_horizontal"
+        android:layout_centerHorizontal="true"
+        android:scaleType="centerInside"
+        />
+    <ImageView
+            android:id="@+id/activity_in"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_qs_wifi_in"
+            android:layout_toRightOf="@id/image"
+            android:layout_alignBottom="@id/image"
+            />
+    <ImageView
+            android:id="@+id/activity_out"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_qs_wifi_out"
+            android:layout_toRightOf="@id/image"
+            android:layout_alignBottom="@id/image"
+            />
+    <TextView
+        style="@style/TextAppearance.QuickSettings.TileView"
+        android:id="@+id/text"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top|center_horizontal"
+        android:gravity="top|center_horizontal"
+        android:layout_centerHorizontal="true"
+        android:layout_below="@id/image" 
+        />
+</RelativeLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/arrays.xml b/packages/SystemUI/res/values/arrays.xml
index b2c8aee..69f4b4fbe 100644
--- a/packages/SystemUI/res/values/arrays.xml
+++ b/packages/SystemUI/res/values/arrays.xml
@@ -47,8 +47,8 @@
         <item>100</item>
     </array>
     <array name="batterymeter_color_values">
-        <item>#FFFF3300</item>
-        <item>#FFFF3300</item>
+        <item>#FFF75D00</item>
+        <item>#FFF75D00</item>
         <item>#FFFFFFFF</item>
     </array>
     <array name="batterymeter_bolt_points">
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 9db2805..814f5db 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1349,8 +1349,7 @@
     };
 
     boolean panelsEnabled() {
-        return ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0
-                && mStatusBarWindowState != StatusBarManager.WINDOW_STATE_HIDING);
+        return (mDisabled & StatusBarManager.DISABLE_EXPAND) == 0;
     }
 
     void makeExpandedVisible() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index 0d591ba..68ee2b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.animation.ValueAnimator;
 import android.app.ActivityManagerNative;
 import android.app.AlertDialog;
 import android.app.Dialog;
@@ -62,6 +63,7 @@
 import android.widget.TextView;
 
 import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsModel.ActivityState;
 import com.android.systemui.statusbar.phone.QuickSettingsModel.BluetoothState;
 import com.android.systemui.statusbar.phone.QuickSettingsModel.RSSIState;
 import com.android.systemui.statusbar.phone.QuickSettingsModel.State;
@@ -401,8 +403,9 @@
 
     private void addSystemTiles(ViewGroup parent, LayoutInflater inflater) {
         // Wi-fi
-        final QuickSettingsBasicTile wifiTile
-                = new QuickSettingsBasicTile(mContext);
+        final QuickSettingsTileView wifiTile = (QuickSettingsTileView)
+                inflater.inflate(R.layout.quick_settings_tile, parent, false);
+        wifiTile.setContent(R.layout.quick_settings_tile_wifi, inflater);
         wifiTile.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
@@ -433,12 +436,15 @@
                     return true;
                 }} );
         }
-        mModel.addWifiTile(wifiTile, new QuickSettingsModel.RefreshCallback() {
+        mModel.addWifiTile(wifiTile, new NetworkActivityCallback() {
             @Override
-            public void refreshView(QuickSettingsTileView unused, State state) {
+            public void refreshView(QuickSettingsTileView view, State state) {
                 WifiState wifiState = (WifiState) state;
-                wifiTile.setImageResource(wifiState.iconId);
-                wifiTile.setText(wifiState.label);
+                ImageView iv = (ImageView) view.findViewById(R.id.image);
+                iv.setImageResource(wifiState.iconId);
+                setActivity(view, wifiState);
+                TextView tv = (TextView) view.findViewById(R.id.text);
+                tv.setText(wifiState.label);
                 wifiTile.setContentDescription(mContext.getString(
                         R.string.accessibility_quick_settings_wifi,
                         wifiState.signalContentDescription,
@@ -462,7 +468,7 @@
                     startSettingsActivity(intent);
                 }
             });
-            mModel.addRSSITile(rssiTile, new QuickSettingsModel.RefreshCallback() {
+            mModel.addRSSITile(rssiTile, new NetworkActivityCallback() {
                 @Override
                 public void refreshView(QuickSettingsTileView view, State state) {
                     RSSIState rssiState = (RSSIState) state;
@@ -478,6 +484,8 @@
                     } else {
                         iov.setImageDrawable(null);
                     }
+                    setActivity(view, rssiState);
+
                     tv.setText(state.label);
                     view.setContentDescription(mContext.getResources().getString(
                             R.string.accessibility_quick_settings_mobile,
@@ -942,4 +950,25 @@
 
         }
     };
+
+    private abstract static class NetworkActivityCallback
+            implements QuickSettingsModel.RefreshCallback {
+        private final long mDefaultDuration = new ValueAnimator().getDuration();
+        private final long mShortDuration = mDefaultDuration / 3;
+
+        public void setActivity(View view, ActivityState state) {
+            setVisibility(view.findViewById(R.id.activity_in), state.activityIn);
+            setVisibility(view.findViewById(R.id.activity_out), state.activityOut);
+        }
+
+        private void setVisibility(View view, boolean visible) {
+            final float newAlpha = visible ? 1 : 0;
+            if (view.getAlpha() != newAlpha) {
+                view.animate()
+                    .setDuration(visible ? mShortDuration : mDefaultDuration)
+                    .alpha(newAlpha)
+                    .start();
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
index b9e3059..9d0418d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
@@ -70,13 +70,17 @@
         int batteryLevel;
         boolean pluggedIn;
     }
-    static class RSSIState extends State {
+    static class ActivityState extends State {
+        boolean activityIn;
+        boolean activityOut;
+    }
+    static class RSSIState extends ActivityState {
         int signalIconId;
         String signalContentDescription;
         int dataTypeIconId;
         String dataContentDescription;
     }
-    static class WifiState extends State {
+    static class WifiState extends ActivityState {
         String signalContentDescription;
         boolean connected;
     }
@@ -430,6 +434,7 @@
     // NetworkSignalChanged callback
     @Override
     public void onWifiSignalChanged(boolean enabled, int wifiSignalIconId,
+            boolean activityIn, boolean activityOut,
             String wifiSignalContentDescription, String enabledDesc) {
         // TODO: If view is in awaiting state, disable
         Resources r = mContext.getResources();
@@ -438,6 +443,8 @@
         boolean wifiNotConnected = (wifiSignalIconId > 0) && (enabledDesc == null);
         mWifiState.enabled = enabled;
         mWifiState.connected = wifiConnected;
+        mWifiState.activityIn = enabled && activityIn;
+        mWifiState.activityOut = enabled && activityOut;
         if (wifiConnected) {
             mWifiState.iconId = wifiSignalIconId;
             mWifiState.label = removeDoubleQuotes(enabledDesc);
@@ -468,7 +475,8 @@
     @Override
     public void onMobileDataSignalChanged(
             boolean enabled, int mobileSignalIconId, String signalContentDescription,
-            int dataTypeIconId, String dataContentDescription, String enabledDesc) {
+            int dataTypeIconId, boolean activityIn, boolean activityOut,
+            String dataContentDescription,String enabledDesc) {
         if (deviceHasMobileData()) {
             // TODO: If view is in awaiting state, disable
             Resources r = mContext.getResources();
@@ -481,6 +489,8 @@
             mRSSIState.dataTypeIconId = enabled && (dataTypeIconId > 0) && !mWifiState.enabled
                     ? dataTypeIconId
                     : 0;
+            mRSSIState.activityIn = enabled && activityIn;
+            mRSSIState.activityOut = enabled && activityOut;
             mRSSIState.dataContentDescription = enabled && (dataTypeIconId > 0) && !mWifiState.enabled
                     ? dataContentDescription
                     : r.getString(R.string.accessibility_no_data);
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 1e7e692..a715450 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -165,9 +165,11 @@
 
     public interface NetworkSignalChangedCallback {
         void onWifiSignalChanged(boolean enabled, int wifiSignalIconId,
-                String wifitSignalContentDescriptionId, String description);
+                boolean activityIn, boolean activityOut,
+                String wifiSignalContentDescriptionId, String description);
         void onMobileDataSignalChanged(boolean enabled, int mobileSignalIconId,
                 String mobileSignalContentDescriptionId, int dataTypeIconId,
+                boolean activityIn, boolean activityOut,
                 String dataTypeContentDescriptionId, String description);
         void onAirplaneModeChanged(boolean enabled);
     }
@@ -313,22 +315,33 @@
         boolean wifiEnabled = mWifiEnabled && (mWifiConnected || !mHasMobileDataFeature);
         String wifiDesc = wifiEnabled ?
                 mWifiSsid : null;
-        cb.onWifiSignalChanged(wifiEnabled, mQSWifiIconId, mContentDescriptionWifi, wifiDesc);
+        boolean wifiIn = wifiEnabled && mWifiSsid != null
+                && (mWifiActivity == WifiManager.DATA_ACTIVITY_INOUT
+                || mWifiActivity == WifiManager.DATA_ACTIVITY_IN);
+        boolean wifiOut = wifiEnabled && mWifiSsid != null
+                && (mWifiActivity == WifiManager.DATA_ACTIVITY_INOUT
+                || mWifiActivity == WifiManager.DATA_ACTIVITY_OUT);
+        cb.onWifiSignalChanged(wifiEnabled, mQSWifiIconId, wifiIn, wifiOut,
+                mContentDescriptionWifi, wifiDesc);
 
+        boolean mobileIn = mDataConnected && (mDataActivity == TelephonyManager.DATA_ACTIVITY_INOUT
+                || mDataActivity == TelephonyManager.DATA_ACTIVITY_IN);
+        boolean mobileOut = mDataConnected && (mDataActivity == TelephonyManager.DATA_ACTIVITY_INOUT
+                || mDataActivity == TelephonyManager.DATA_ACTIVITY_OUT);
         if (isEmergencyOnly()) {
             cb.onMobileDataSignalChanged(false, mQSPhoneSignalIconId,
-                    mContentDescriptionPhoneSignal, mQSDataTypeIconId, mContentDescriptionDataType,
-                    null);
+                    mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
+                    mContentDescriptionDataType, null);
         } else {
             if (mIsWimaxEnabled && mWimaxConnected) {
                 // Wimax is special
                 cb.onMobileDataSignalChanged(true, mQSPhoneSignalIconId,
-                        mContentDescriptionPhoneSignal, mQSDataTypeIconId,
+                        mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
                         mContentDescriptionDataType, mNetworkName);
             } else {
                 // Normal mobile data
                 cb.onMobileDataSignalChanged(mHasMobileDataFeature, mQSPhoneSignalIconId,
-                        mContentDescriptionPhoneSignal, mQSDataTypeIconId,
+                        mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
                         mContentDescriptionDataType, mNetworkName);
             }
         }
@@ -1125,6 +1138,11 @@
                     + " mBluetoothTetherIconId=0x" + Integer.toHexString(mBluetoothTetherIconId));
         }
 
+        // update QS
+        for (NetworkSignalChangedCallback cb : mSignalsChangedCallbacks) {
+            notifySignalsChangedCallbacks(cb);
+        }
+
         if (mLastPhoneSignalIconId          != mPhoneSignalIconId
          || mLastWifiIconId                 != mWifiIconId
          || mLastWimaxIconId                != mWimaxIconId
@@ -1136,9 +1154,6 @@
             for (SignalCluster cluster : mSignalClusters) {
                 refreshSignalCluster(cluster);
             }
-            for (NetworkSignalChangedCallback cb : mSignalsChangedCallbacks) {
-                notifySignalsChangedCallbacks(cb);
-            }
         }
 
         if (mLastAirplaneMode != mAirplaneMode) {
diff --git a/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java b/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java
index 7e76025..c6b76f1 100644
--- a/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java
+++ b/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java
@@ -25,6 +25,9 @@
 
 import com.android.net.IProxyService;
 
+import java.net.MalformedURLException;
+import java.net.URL;
+
 public class PacService extends Service {
     private static final String TAG = "PacService";
 
@@ -68,7 +71,18 @@
 
         @Override
         public String resolvePacFile(String host, String url) throws RemoteException {
-            return mPacNative.makeProxyRequest(url, host);
+            try {
+                // Check for characters that could be used for an injection attack.
+                new URL(url);
+                for (char c : host.toCharArray()) {
+                    if (!Character.isLetterOrDigit(c) && (c != '.') && (c != '-')) {
+                        throw new RemoteException("Invalid host was passed");
+                    }
+                }
+                return mPacNative.makeProxyRequest(url, host);
+            } catch (MalformedURLException e) {
+                throw new RemoteException("Invalid URL was passed");
+            }
         }
 
         @Override
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 27bf38cc..8a285e3 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -3637,7 +3637,7 @@
                             ? AudioManager.ADJUST_RAISE
                             : AudioManager.ADJUST_LOWER,
                     0,
-                    mContext.getBasePackageName());
+                    mContext.getOpPackageName());
         } catch (RemoteException e) {
             Log.w(TAG, "IAudioService.adjustStreamVolume() threw RemoteException " + e);
         } finally {
@@ -4964,7 +4964,7 @@
             owningPackage = win.getOwningPackage();
         } else {
             owningUid = android.os.Process.myUid();
-            owningPackage = mContext.getBasePackageName();
+            owningPackage = mContext.getOpPackageName();
         }
         if (pattern.length == 1) {
             // One-shot vibration
diff --git a/preloaded-classes b/preloaded-classes
index 064ca3a..cb2ace3 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -663,8 +663,8 @@
 android.net.wifi.WifiManager
 android.net.wifi.WifiManager$ServiceHandler
 android.net.wifi.WifiNative
-android.nfc.INdefPushCallback
-android.nfc.INdefPushCallback$Stub
+android.nfc.IAppCallback
+android.nfc.IAppCallback$Stub
 android.nfc.INfcAdapter
 android.nfc.INfcAdapter$Stub
 android.nfc.INfcAdapter$Stub$Proxy
@@ -1209,13 +1209,9 @@
 android.webkit.BrowserFrame$ConfigCallback
 android.webkit.CallbackProxy
 android.webkit.CookieManager
-android.webkit.CookieManagerClassic
 android.webkit.CookieSyncManager
 android.webkit.DeviceMotionAndOrientationManager
 android.webkit.GeolocationPermissions
-android.webkit.GeolocationPermissionsClassic
-android.webkit.GeolocationPermissionsClassic$1
-android.webkit.GeolocationPermissionsClassic$2
 android.webkit.HTML5Audio
 android.webkit.HTML5VideoViewProxy
 android.webkit.JWebCoreJavaBridge
@@ -1231,42 +1227,19 @@
 android.webkit.ViewManager$3
 android.webkit.ViewStateSerializer
 android.webkit.WebBackForwardList
-android.webkit.WebBackForwardListClassic
 android.webkit.WebCoreThreadWatchdog
 android.webkit.WebHistoryItem
-android.webkit.WebHistoryItemClassic
 android.webkit.WebIconDatabase
-android.webkit.WebIconDatabaseClassic
-android.webkit.WebIconDatabaseClassic$EventHandler
-android.webkit.WebIconDatabaseClassic$EventHandler$1
 android.webkit.WebSettings
 android.webkit.WebSettings$LayoutAlgorithm
 android.webkit.WebSettings$PluginState
 android.webkit.WebSettings$RenderPriority
 android.webkit.WebSettings$ZoomDensity
-android.webkit.WebSettingsClassic
-android.webkit.WebSettingsClassic$AutoFillProfile
-android.webkit.WebSettingsClassic$EventHandler
-android.webkit.WebSettingsClassic$EventHandler$1
 android.webkit.WebStorage
-android.webkit.WebStorageClassic
-android.webkit.WebStorageClassic$1
-android.webkit.WebStorageClassic$2
 android.webkit.WebSyncManager
 android.webkit.WebSyncManager$SyncHandler
 android.webkit.WebView
 android.webkit.WebView$PrivateAccess
-android.webkit.WebViewClassic
-android.webkit.WebViewClassic$Factory
-android.webkit.WebViewClassic$OnTrimMemoryListener
-android.webkit.WebViewClassic$PackageListener
-android.webkit.WebViewClassic$PageSwapDelegate
-android.webkit.WebViewClassic$PrivateHandler
-android.webkit.WebViewClassic$ProxyReceiver
-android.webkit.WebViewClassic$SelectionHandleAlpha
-android.webkit.WebViewClassic$TitleBarDelegate
-android.webkit.WebViewClassic$TrustStorageListener
-android.webkit.WebViewClassic$ViewSizeData
 android.webkit.WebViewClient
 android.webkit.WebViewCore$AutoFillData
 android.webkit.WebViewCore$DrawData
@@ -1278,8 +1251,6 @@
 android.webkit.WebViewCore$WebCoreThread
 android.webkit.WebViewCore$WebCoreThread$1
 android.webkit.WebViewDatabase
-android.webkit.WebViewDatabaseClassic
-android.webkit.WebViewDatabaseClassic$1
 android.webkit.WebViewFactory
 android.webkit.WebViewFactory$Preloader
 android.webkit.WebViewFactoryProvider
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 795ab47..9e7a15d 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -3405,6 +3405,7 @@
             & InputDispatcher::doNotifyANRLockedInterruptible);
     commandEntry->inputApplicationHandle = applicationHandle;
     commandEntry->inputWindowHandle = windowHandle;
+    commandEntry->reason = reason;
 }
 
 void InputDispatcher::doNotifyConfigurationChangedInterruptible(
@@ -3434,7 +3435,8 @@
     mLock.unlock();
 
     nsecs_t newTimeout = mPolicy->notifyANR(
-            commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle);
+            commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle,
+            commandEntry->reason);
 
     mLock.lock();
 
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 0273dc4..190e7b2 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -202,7 +202,8 @@
     /* Notifies the system that an application is not responding.
      * Returns a new timeout to continue waiting, or 0 to abort dispatch. */
     virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
-            const sp<InputWindowHandle>& inputWindowHandle) = 0;
+            const sp<InputWindowHandle>& inputWindowHandle,
+            const String8& reason) = 0;
 
     /* Notifies the system that an input channel is unrecoverably broken. */
     virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) = 0;
@@ -596,6 +597,7 @@
         KeyEntry* keyEntry;
         sp<InputApplicationHandle> inputApplicationHandle;
         sp<InputWindowHandle> inputWindowHandle;
+        String8 reason;
         int32_t userActivityEventType;
         uint32_t seq;
         bool handled;
diff --git a/services/input/tests/InputDispatcher_test.cpp b/services/input/tests/InputDispatcher_test.cpp
index ed2b4a5..26b4fab 100644
--- a/services/input/tests/InputDispatcher_test.cpp
+++ b/services/input/tests/InputDispatcher_test.cpp
@@ -50,7 +50,8 @@
     }
 
     virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
-            const sp<InputWindowHandle>& inputWindowHandle) {
+            const sp<InputWindowHandle>& inputWindowHandle,
+            const String8& reason) {
         return 0;
     }
 
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 02a78de..1af7cc8 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -4681,6 +4681,21 @@
         setProvNotificationVisible(visible, networkType, extraInfo, url);
     }
 
+    @Override
+    public void setAirplaneMode(boolean enable) {
+        enforceConnectivityInternalPermission();
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            final ContentResolver cr = mContext.getContentResolver();
+            Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, enable ? 1 : 0);
+            Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+            intent.putExtra("state", enable);
+            mContext.sendBroadcast(intent);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
     private void onUserStart(int userId) {
         synchronized(mVpns) {
             Vpn userVpn = mVpns.get(userId);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 1e3fb40..96b7030 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -187,7 +187,6 @@
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
@@ -314,10 +313,6 @@
     // to respond with the result.
     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
 
-    // Index for assist context bundle pertaining to the top activity. Non-negative indices
-    // correspond to assist context bundles from foreground services.
-    static final int TOP_ACTIVITY_ASSIST_EXTRAS_INDEX = -1;
-
     static final int MY_PID = Process.myPid();
 
     static final String[] EMPTY_STRING_ARRAY = new String[0];
@@ -394,30 +389,16 @@
 
     public class PendingAssistExtras extends Binder implements Runnable {
         public final ActivityRecord activity;
-        public final List<ServiceRecord> services;
-        public int numPending;
-        public int numRespondedServices = 0;
-        public Bundle activityExtras = null;
-        public Bundle[] servicesExtras;
-        public PendingAssistExtras(ActivityRecord _activity, List<ServiceRecord> _services) {
+        public boolean haveResult = false;
+        public Bundle result = null;
+        public PendingAssistExtras(ActivityRecord _activity) {
             activity = _activity;
-            services = _services;
-            numPending = services.size() + 1;
         }
         @Override
         public void run() {
-            if (activityExtras == null) {
-                Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from activtity "
-                        + activity);
-            }
-            for (int i = 0; i < services.size(); i++) {
-                if (servicesExtras[i] == null) {
-                    Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from service "
-                            + i + " " + services.get(i));
-                }
-            }
+            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
             synchronized (this) {
-                numPending = 0;
+                haveResult = true;
                 notifyAll();
             }
         }
@@ -7970,8 +7951,8 @@
         return KEY_DISPATCHING_TIMEOUT;
     }
 
-
-    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem) {
+    @Override
+    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires permission "
@@ -7986,7 +7967,7 @@
             timeout = getInputDispatchingTimeoutLocked(proc);
         }
 
-        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem)) {
+        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
             return -1;
         }
 
@@ -7999,13 +7980,20 @@
      */
     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
             final ActivityRecord activity, final ActivityRecord parent,
-            final boolean aboveSystem) {
+            final boolean aboveSystem, String reason) {
         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires permission "
                     + android.Manifest.permission.FILTER_EVENTS);
         }
 
+        final String annotation;
+        if (reason == null) {
+            annotation = "Input dispatching timed out";
+        } else {
+            annotation = "Input dispatching timed out (" + reason + ")";
+        }
+
         if (proc != null) {
             synchronized (this) {
                 if (proc.debugging) {
@@ -8021,7 +8009,7 @@
                 if (proc.instrumentationClass != null) {
                     Bundle info = new Bundle();
                     info.putString("shortMsg", "keyDispatchingTimedOut");
-                    info.putString("longMsg", "Timed out while dispatching key event");
+                    info.putString("longMsg", annotation);
                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
                     return true;
                 }
@@ -8029,7 +8017,7 @@
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    appNotResponding(proc, activity, parent, aboveSystem, "keyDispatchingTimedOut");
+                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
                 }
             });
         }
@@ -8042,81 +8030,41 @@
                 "getAssistContextExtras()");
         PendingAssistExtras pae;
         Bundle extras = new Bundle();
-        List<ServiceRecord> foregroundServices;
         synchronized (this) {
-            Collection<ServiceRecord> allServices = mServices.mServiceMap.getAllServices(
-                    Binder.getCallingUid());
-            foregroundServices = new ArrayList<ServiceRecord>();
-            for (ServiceRecord record : allServices) {
-                if ((record.serviceInfo.flags & ServiceInfo.FLAG_PROVIDE_ASSIST_DATA) > 0 &&
-                        record.isForeground) {
-                    if (record.app == null || record.app.thread == null) {
-                        Slog.w(TAG, "getAssistContextExtras error: no process for " + record);
-                        continue;
-                    }
-                    if (record.app.pid == Binder.getCallingPid()) {
-                        Slog.w(TAG, "getAssistContextExtras error: request process same as " +
-                                record);
-                        continue;
-                    }
-                    foregroundServices.add(record);
-                }
-            }
-
             ActivityRecord activity = getFocusedStack().mResumedActivity;
-            boolean validActivity = true;
             if (activity == null) {
-                Slog.w(TAG, "getAssistContextExtras error: no resumed activity");
-                validActivity = false;
-            } else if (activity.app == null || activity.app.thread == null) {
-                Slog.w(TAG, "getAssistContextExtras error: no process for " + activity);
-                validActivity = false;
-            } else if (activity.app.pid == Binder.getCallingPid()) {
-                Slog.w(TAG, "getAssistContextExtras error: request process same as " + activity);
-                validActivity = false;
+                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
+                return null;
             }
-
-            pae = new PendingAssistExtras(activity, foregroundServices);
+            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
+            if (activity.app == null || activity.app.thread == null) {
+                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
+                return extras;
+            }
+            if (activity.app.pid == Binder.getCallingPid()) {
+                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
+                return extras;
+            }
+            pae = new PendingAssistExtras(activity);
             try {
-                if (validActivity) {
-                    activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
-                            requestType, -1);
-                }
-                for (int i = 0; i < foregroundServices.size(); i++) {
-                    ServiceRecord record = foregroundServices.get(i);
-                    record.app.thread.requestAssistContextExtras(record, pae, requestType, i);
-                }
+                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
+                        requestType);
                 mPendingAssistExtras.add(pae);
                 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
             } catch (RemoteException e) {
-                Slog.w(TAG, "getAssistContextExtras failed: crash fetching extras.", e);
+                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
+                return extras;
             }
         }
         synchronized (pae) {
-            while (pae.numPending > 0) {
+            while (!pae.haveResult) {
                 try {
                     pae.wait();
                 } catch (InterruptedException e) {
                 }
             }
-            if (pae.activityExtras != null) {
-                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.activityExtras);
-                extras.putString(Intent.EXTRA_ASSIST_PACKAGE, pae.activity.packageName);
-            }
-            if (pae.numRespondedServices > 0) {
-                Bundle[] servicesExtras = new Bundle[pae.numRespondedServices];
-                String[] servicesPackages = new String[pae.numRespondedServices];
-                int extrasIndex = 0;
-                for (int i = 0; i < foregroundServices.size(); i++) {
-                    if (pae.servicesExtras[i] != null) {
-                        servicesExtras[extrasIndex] = pae.servicesExtras[i];
-                        ServiceRecord record = foregroundServices.get(i);
-                        servicesPackages[extrasIndex] = record.packageName;
-                        extrasIndex++;
-                    }
-                }
-                extras.putParcelableArray(Intent.EXTRA_ASSIST_SERVICES_CONTEXTS, servicesExtras);
-                extras.putStringArray(Intent.EXTRA_ASSIST_SERVICES_PACKAGES, servicesPackages);
+            if (pae.result != null) {
+                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
             }
         }
         synchronized (this) {
@@ -8126,19 +8074,12 @@
         return extras;
     }
 
-    public void reportAssistContextExtras(IBinder token, Bundle extras, int index) {
+    public void reportAssistContextExtras(IBinder token, Bundle extras) {
         PendingAssistExtras pae = (PendingAssistExtras)token;
         synchronized (pae) {
-            if (index == TOP_ACTIVITY_ASSIST_EXTRAS_INDEX) {
-                pae.activityExtras = extras;
-            } else {
-                pae.servicesExtras[index] = extras;
-                pae.numRespondedServices++;
-            }
-            pae.numPending--;
-            if (pae.numPending == 0) {
-                pae.notifyAll();
-            }
+            pae.result = extras;
+            pae.haveResult = true;
+            pae.notifyAll();
         }
     }
 
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index bf3713b..6e50808 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -305,9 +305,9 @@
             }
         }
 
-        @Override public boolean keyDispatchingTimedOut() {
+        @Override public boolean keyDispatchingTimedOut(String reason) {
             ActivityRecord activity = weakActivity.get();
-            return activity != null && activity.keyDispatchingTimedOut();
+            return activity != null && activity.keyDispatchingTimedOut(reason);
         }
 
         @Override public long getKeyDispatchingTimeout() {
@@ -960,14 +960,14 @@
         return r;
     }
 
-    public boolean keyDispatchingTimedOut() {
+    public boolean keyDispatchingTimedOut(String reason) {
         ActivityRecord r;
         ProcessRecord anrApp;
         synchronized(service) {
             r = getWaitingHistoryRecordLocked();
             anrApp = r != null ? r.app : null;
         }
-        return service.inputDispatchingTimedOut(anrApp, r, this, false);
+        return service.inputDispatchingTimedOut(anrApp, r, this, false, reason);
     }
 
     /** Returns the key dispatching timeout for this application token. */
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 2b76e71..e994c23 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -620,7 +620,13 @@
     }
 
     void clearLaunchTime(ActivityRecord r) {
-        r.displayStartTime = r.fullyDrawnStartTime = 0;
+        // Make sure that there is no activity waiting for this to launch.
+        if (mStackSupervisor.mWaitingActivityLaunched.isEmpty()) {
+            r.displayStartTime = r.fullyDrawnStartTime = 0;
+        } else {
+            mStackSupervisor.removeTimeoutsForActivityLocked(r);
+            mStackSupervisor.scheduleIdleTimeoutLocked(r);
+        }
     }
 
     void awakeFromSleepingLocked() {
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
index 7b4c077..d749e6c 100644
--- a/services/java/com/android/server/input/InputManagerService.java
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -1292,8 +1292,9 @@
 
     // Native callback.
     private long notifyANR(InputApplicationHandle inputApplicationHandle,
-            InputWindowHandle inputWindowHandle) {
-        return mWindowManagerCallbacks.notifyANR(inputApplicationHandle, inputWindowHandle);
+            InputWindowHandle inputWindowHandle, String reason) {
+        return mWindowManagerCallbacks.notifyANR(
+                inputApplicationHandle, inputWindowHandle, reason);
     }
 
     // Native callback.
@@ -1477,7 +1478,7 @@
         public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle);
 
         public long notifyANR(InputApplicationHandle inputApplicationHandle,
-                InputWindowHandle inputWindowHandle);
+                InputWindowHandle inputWindowHandle, String reason);
 
         public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn);
 
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index 415cda1..92026b2 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -1395,9 +1395,8 @@
                     final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
                     final int[] gids = pkg.getGids();
 
-                    // Avoid any application that has a space in its path
-                    // or that is handled by the system.
-                    if (dataPath.indexOf(" ") >= 0 || ai.uid < Process.FIRST_APPLICATION_UID)
+                    // Avoid any application that has a space in its path.
+                    if (dataPath.indexOf(" ") >= 0)
                         continue;
 
                     // we store on each line the following information for now:
diff --git a/services/java/com/android/server/power/ElectronBeam.java b/services/java/com/android/server/power/ElectronBeam.java
index 0d92f66..729bd16 100644
--- a/services/java/com/android/server/power/ElectronBeam.java
+++ b/services/java/com/android/server/power/ElectronBeam.java
@@ -35,6 +35,7 @@
 import android.util.Slog;
 import android.view.Display;
 import android.view.DisplayInfo;
+import android.view.Surface.OutOfResourcesException;
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
@@ -94,7 +95,7 @@
     // Texture names.  We only use one texture, which contains the screenshot.
     private final int[] mTexNames = new int[1];
     private boolean mTexNamesGenerated;
-    private float mTexMatrix[] = new float[16];
+    private final float mTexMatrix[] = new float[16];
 
     // Vertex and corresponding texture coordinates.
     // We have 4 2D vertices, so 8 elements.  The vertices form a quad.
@@ -515,7 +516,7 @@
                     mSurfaceControl = new SurfaceControl(mSurfaceSession,
                             "ElectronBeam", mDisplayWidth, mDisplayHeight,
                             PixelFormat.OPAQUE, flags);
-                } catch (SurfaceControl.OutOfResourcesException ex) {
+                } catch (OutOfResourcesException ex) {
                     Slog.e(TAG, "Unable to create surface.", ex);
                     return false;
                 }
@@ -525,7 +526,7 @@
             mSurfaceControl.setSize(mDisplayWidth, mDisplayHeight);
             mSurface = new Surface();
             mSurface.copyFrom(mSurfaceControl);
-            
+
             mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManager, mSurfaceControl);
             mSurfaceLayout.onDisplayTransaction();
         } finally {
diff --git a/services/java/com/android/server/power/WirelessChargerDetector.java b/services/java/com/android/server/power/WirelessChargerDetector.java
index ac6dc3e..35920f7 100644
--- a/services/java/com/android/server/power/WirelessChargerDetector.java
+++ b/services/java/com/android/server/power/WirelessChargerDetector.java
@@ -21,6 +21,7 @@
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
 import android.os.BatteryManager;
+import android.os.SystemClock;
 import android.util.Slog;
 
 import java.io.PrintWriter;
@@ -130,6 +131,10 @@
     private long mFirstSampleTime;
     private float mFirstSampleX, mFirstSampleY, mFirstSampleZ;
 
+    // The time and value of the last sample that was collected (for debugging only).
+    private long mLastSampleTime;
+    private float mLastSampleX, mLastSampleY, mLastSampleZ;
+
     public WirelessChargerDetector(SensorManager sensorManager,
             SuspendBlocker suspendBlocker) {
         mSensorManager = sensorManager;
@@ -153,6 +158,9 @@
             pw.println("  mFirstSampleTime=" + mFirstSampleTime);
             pw.println("  mFirstSampleX=" + mFirstSampleX
                     + ", mFirstSampleY=" + mFirstSampleY + ", mFirstSampleZ=" + mFirstSampleZ);
+            pw.println("  mLastSampleTime=" + mLastSampleTime);
+            pw.println("  mLastSampleX=" + mLastSampleX
+                    + ", mLastSampleY=" + mLastSampleY + ", mLastSampleZ=" + mLastSampleZ);
         }
     }
 
@@ -224,6 +232,11 @@
                 return;
             }
 
+            mLastSampleTime = timeNanos;
+            mLastSampleX = x;
+            mLastSampleY = y;
+            mLastSampleZ = z;
+
             mTotalSamples += 1;
             if (mTotalSamples == 1) {
                 // Save information about the first sample collected.
@@ -310,7 +323,10 @@
     private final SensorEventListener mListener = new SensorEventListener() {
         @Override
         public void onSensorChanged(SensorEvent event) {
-            processSample(event.timestamp, event.values[0], event.values[1], event.values[2]);
+            // We use SystemClock.elapsedRealtimeNanos() instead of event.timestamp because
+            // on some devices the sensor HAL may produce timestamps that are not monotonic.
+            processSample(SystemClock.elapsedRealtimeNanos(),
+                    event.values[0], event.values[1], event.values[2]);
         }
 
         @Override
diff --git a/services/java/com/android/server/wm/BlackFrame.java b/services/java/com/android/server/wm/BlackFrame.java
index 737d854..5aa266d 100644
--- a/services/java/com/android/server/wm/BlackFrame.java
+++ b/services/java/com/android/server/wm/BlackFrame.java
@@ -22,6 +22,7 @@
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.util.Slog;
+import android.view.Surface.OutOfResourcesException;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 
@@ -36,7 +37,7 @@
         final SurfaceControl surface;
 
         BlackSurface(SurfaceSession session, int layer, int l, int t, int r, int b, int layerStack)
-                throws SurfaceControl.OutOfResourcesException {
+                throws OutOfResourcesException {
             left = l;
             top = t;
             this.layer = layer;
@@ -112,7 +113,7 @@
     }
 
     public BlackFrame(SurfaceSession session, Rect outer, Rect inner, int layer, int layerStack,
-            boolean forceDefaultOrientation) throws SurfaceControl.OutOfResourcesException {
+            boolean forceDefaultOrientation) throws OutOfResourcesException {
         boolean success = false;
 
         mForceDefaultOrientation = forceDefaultOrientation;
diff --git a/services/java/com/android/server/wm/DisplayMagnifier.java b/services/java/com/android/server/wm/DisplayMagnifier.java
index 0f51028..382d7b4 100644
--- a/services/java/com/android/server/wm/DisplayMagnifier.java
+++ b/services/java/com/android/server/wm/DisplayMagnifier.java
@@ -496,7 +496,7 @@
                     mWindowManager.getDefaultDisplay().getRealSize(mTempPoint);
                     surfaceControl = new SurfaceControl(mWindowManagerService.mFxSession, SURFACE_TITLE,
                             mTempPoint.x, mTempPoint.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
-                } catch (SurfaceControl.OutOfResourcesException oore) {
+                } catch (OutOfResourcesException oore) {
                     /* ignore */
                 }
                 mSurfaceControl = surfaceControl;
@@ -629,7 +629,7 @@
                         }
                     } catch (IllegalArgumentException iae) {
                         /* ignore */
-                    } catch (OutOfResourcesException oore) {
+                    } catch (Surface.OutOfResourcesException oore) {
                         /* ignore */
                     }
                     if (canvas == null) {
@@ -644,7 +644,7 @@
                     canvas.drawPath(path, mPaint);
 
                     mSurface.unlockCanvasAndPost(canvas);
-                    
+
                     if (mAlpha > 0) {
                         mSurfaceControl.show();
                     } else {
diff --git a/services/java/com/android/server/wm/FocusedStackFrame.java b/services/java/com/android/server/wm/FocusedStackFrame.java
index 9c18331..365b277 100644
--- a/services/java/com/android/server/wm/FocusedStackFrame.java
+++ b/services/java/com/android/server/wm/FocusedStackFrame.java
@@ -26,6 +26,7 @@
 import android.graphics.Region;
 import android.util.Slog;
 import android.view.Display;
+import android.view.Surface.OutOfResourcesException;
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
@@ -39,9 +40,9 @@
 
     private final SurfaceControl mSurfaceControl;
     private final Surface mSurface = new Surface();
-    private Rect mLastBounds = new Rect();
-    private Rect mBounds = new Rect();
-    private Rect mTmpDrawRect = new Rect();
+    private final Rect mLastBounds = new Rect();
+    private final Rect mBounds = new Rect();
+    private final Rect mTmpDrawRect = new Rect();
 
     public FocusedStackFrame(Display display, SurfaceSession session) {
         SurfaceControl ctrl = null;
@@ -56,7 +57,7 @@
             ctrl.setLayerStack(display.getLayerStack());
             ctrl.setAlpha(ALPHA);
             mSurface.copyFrom(ctrl);
-        } catch (SurfaceControl.OutOfResourcesException e) {
+        } catch (OutOfResourcesException e) {
         }
         mSurfaceControl = ctrl;
     }
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index 9620612..ea3af26 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -88,7 +88,7 @@
      */
     @Override
     public long notifyANR(InputApplicationHandle inputApplicationHandle,
-            InputWindowHandle inputWindowHandle) {
+            InputWindowHandle inputWindowHandle, String reason) {
         AppWindowToken appWindowToken = null;
         WindowState windowState = null;
         boolean aboveSystem = false;
@@ -105,7 +105,8 @@
 
             if (windowState != null) {
                 Slog.i(WindowManagerService.TAG, "Input event dispatching timed out "
-                        + "sending to " + windowState.mAttrs.getTitle());
+                        + "sending to " + windowState.mAttrs.getTitle()
+                        + ".  Reason: " + reason);
                 // Figure out whether this window is layered above system windows.
                 // We need to do this here to help the activity manager know how to
                 // layer its ANR dialog.
@@ -114,19 +115,21 @@
                 aboveSystem = windowState.mBaseLayer > systemAlertLayer;
             } else if (appWindowToken != null) {
                 Slog.i(WindowManagerService.TAG, "Input event dispatching timed out "
-                        + "sending to application " + appWindowToken.stringName);
+                        + "sending to application " + appWindowToken.stringName
+                        + ".  Reason: " + reason);
             } else {
-                Slog.i(WindowManagerService.TAG, "Input event dispatching timed out.");
+                Slog.i(WindowManagerService.TAG, "Input event dispatching timed out "
+                        + ".  Reason: " + reason);
             }
 
-            mService.saveANRStateLocked(appWindowToken, windowState);
+            mService.saveANRStateLocked(appWindowToken, windowState, reason);
         }
 
         if (appWindowToken != null && appWindowToken.appToken != null) {
             try {
                 // Notify the activity manager about the timeout and let it decide whether
                 // to abort dispatching or keep waiting.
-                boolean abort = appWindowToken.appToken.keyDispatchingTimedOut();
+                boolean abort = appWindowToken.appToken.keyDispatchingTimedOut(reason);
                 if (! abort) {
                     // The activity manager declined to abort dispatching.
                     // Wait a bit longer and timeout again later.
@@ -139,7 +142,7 @@
                 // Notify the activity manager about the timeout and let it decide whether
                 // to abort dispatching or keep waiting.
                 long timeout = ActivityManagerNative.getDefault().inputDispatchingTimedOut(
-                        windowState.mSession.mPid, aboveSystem);
+                        windowState.mSession.mPid, aboveSystem, reason);
                 if (timeout >= 0) {
                     // The activity manager declined to abort dispatching.
                     // Wait a bit longer and timeout again later.
diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java
index 7d90858..e630737 100644
--- a/services/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -27,6 +27,7 @@
 import android.util.Slog;
 import android.view.Display;
 import android.view.DisplayInfo;
+import android.view.Surface.OutOfResourcesException;
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
@@ -262,7 +263,7 @@
                 mSurfaceControl.setAlpha(0);
                 mSurfaceControl.show();
                 sur.destroy();
-            } catch (SurfaceControl.OutOfResourcesException e) {
+            } catch (OutOfResourcesException e) {
                 Slog.w(TAG, "Unable to allocate freeze surface", e);
             }
 
@@ -547,7 +548,7 @@
                 mCustomBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 3,
                         layerStack, false);
                 mCustomBlackFrame.setMatrix(mFrameInitialMatrix);
-            } catch (SurfaceControl.OutOfResourcesException e) {
+            } catch (OutOfResourcesException e) {
                 Slog.w(TAG, "Unable to allocate black surface", e);
             } finally {
                 SurfaceControl.closeTransaction();
@@ -587,7 +588,7 @@
                 mExitingBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 2,
                         layerStack, mForceDefaultOrientation);
                 mExitingBlackFrame.setMatrix(mFrameInitialMatrix);
-            } catch (SurfaceControl.OutOfResourcesException e) {
+            } catch (OutOfResourcesException e) {
                 Slog.w(TAG, "Unable to allocate black surface", e);
             } finally {
                 SurfaceControl.closeTransaction();
@@ -609,7 +610,7 @@
                 Rect inner = new Rect(0, 0, finalWidth, finalHeight);
                 mEnteringBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER,
                         layerStack, false);
-            } catch (SurfaceControl.OutOfResourcesException e) {
+            } catch (OutOfResourcesException e) {
                 Slog.w(TAG, "Unable to allocate black surface", e);
             } finally {
                 SurfaceControl.closeTransaction();
@@ -894,7 +895,7 @@
                     && (mMoreStartEnter || mMoreStartExit || mMoreFinishEnter || mMoreFinishExit))
                 || (USE_CUSTOM_BLACK_FRAME
                         && (mMoreStartFrame || mMoreRotateFrame || mMoreFinishFrame))
-                || mMoreRotateEnter || mMoreRotateExit 
+                || mMoreRotateEnter || mMoreRotateExit
                 || !mFinishAnimReady;
 
         mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
diff --git a/services/java/com/android/server/wm/StrictModeFlash.java b/services/java/com/android/server/wm/StrictModeFlash.java
index 31628e3..fb5876b 100644
--- a/services/java/com/android/server/wm/StrictModeFlash.java
+++ b/services/java/com/android/server/wm/StrictModeFlash.java
@@ -23,6 +23,7 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.view.Display;
+import android.view.Surface.OutOfResourcesException;
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
@@ -47,7 +48,7 @@
             ctrl.setPosition(0, 0);
             ctrl.show();
             mSurface.copyFrom(ctrl);
-        } catch (SurfaceControl.OutOfResourcesException e) {
+        } catch (OutOfResourcesException e) {
         }
         mSurfaceControl = ctrl;
         mDrawNeeded = true;
diff --git a/services/java/com/android/server/wm/Watermark.java b/services/java/com/android/server/wm/Watermark.java
index fedd314..e226e3d 100644
--- a/services/java/com/android/server/wm/Watermark.java
+++ b/services/java/com/android/server/wm/Watermark.java
@@ -27,10 +27,10 @@
 import android.util.Log;
 import android.util.TypedValue;
 import android.view.Display;
+import android.view.Surface.OutOfResourcesException;
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
-import android.view.Surface.OutOfResourcesException;
 
 /**
  * Displays a watermark on top of the window manager's windows.
@@ -119,7 +119,7 @@
             ctrl.setPosition(0, 0);
             ctrl.show();
             mSurface.copyFrom(ctrl);
-        } catch (SurfaceControl.OutOfResourcesException e) {
+        } catch (OutOfResourcesException e) {
         }
         mSurfaceControl = ctrl;
     }
@@ -144,11 +144,11 @@
             try {
                 c = mSurface.lockCanvas(dirty);
             } catch (IllegalArgumentException e) {
-            } catch (OutOfResourcesException e) {
+            } catch (Surface.OutOfResourcesException e) {
             }
             if (c != null) {
                 c.drawColor(0, PorterDuff.Mode.CLEAR);
-                
+
                 int deltaX = mDeltaX;
                 int deltaY = mDeltaY;
 
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 34d8973..f5e0531 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -116,6 +116,7 @@
 import android.view.KeyEvent;
 import android.view.MagnificationSpec;
 import android.view.MotionEvent;
+import android.view.Surface.OutOfResourcesException;
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
@@ -461,7 +462,7 @@
     // This is held as long as we have the screen frozen, to give us time to
     // perform a rotation animation when turning off shows the lock screen which
     // changes the orientation.
-    private PowerManager.WakeLock mScreenFrozenLock;
+    private final PowerManager.WakeLock mScreenFrozenLock;
 
     final AppTransition mAppTransition;
     boolean mStartingIconInTransition = false;
@@ -664,7 +665,7 @@
     boolean mInTouchMode = true;
 
     private ViewServer mViewServer;
-    private ArrayList<WindowChangeListener> mWindowChangeListeners =
+    private final ArrayList<WindowChangeListener> mWindowChangeListeners =
         new ArrayList<WindowChangeListener>();
     private boolean mWindowsChanged = false;
 
@@ -6812,7 +6813,7 @@
                     } else {
                         Slog.w(TAG, "Drag already in progress");
                     }
-                } catch (SurfaceControl.OutOfResourcesException e) {
+                } catch (OutOfResourcesException e) {
                     Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
                     if (mDragState != null) {
                         mDragState.reset();
@@ -8580,12 +8581,8 @@
                     mAppTransition.getStartingPoint(p);
                     appAnimator.thumbnailX = p.x;
                     appAnimator.thumbnailY = p.y;
-                } catch (SurfaceControl.OutOfResourcesException e) {
-                    Slog.e(TAG, "Can't allocate thumbnail surface w=" + dirty.width()
-                            + " h=" + dirty.height(), e);
-                    appAnimator.clearThumbnail();
-                } catch (Surface.OutOfResourcesException e) {
-                    Slog.e(TAG, "Can't allocate Canvas surface w=" + dirty.width()
+                } catch (OutOfResourcesException e) {
+                    Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w=" + dirty.width()
                             + " h=" + dirty.height(), e);
                     appAnimator.clearThumbnail();
                 }
@@ -10541,8 +10538,10 @@
      *
      * @param appWindowToken The application that ANR'd, may be null.
      * @param windowState The window that ANR'd, may be null.
+     * @param reason The reason for the ANR, may be null.
      */
-    public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState) {
+    public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState,
+            String reason) {
         StringWriter sw = new StringWriter();
         PrintWriter pw = new FastPrintWriter(sw, false, 1024);
         pw.println("  ANR time: " + DateFormat.getInstance().format(new Date()));
@@ -10552,6 +10551,9 @@
         if (windowState != null) {
             pw.println("  Window at fault: " + windowState.mAttrs.getTitle());
         }
+        if (reason != null) {
+            pw.println("  Reason: " + reason);
+        }
         pw.println();
         dumpWindowsNoHeaderLocked(pw, true, null);
         pw.close();
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 73325cb..9245542 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -29,6 +29,7 @@
 import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.MagnificationSpec;
+import android.view.Surface.OutOfResourcesException;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 import android.view.WindowManager;
@@ -480,7 +481,7 @@
         private final Rect mWindowCrop = new Rect();
         private boolean mShown = false;
         private int mLayerStack;
-        private String mName;
+        private final String mName;
 
         public SurfaceTrace(SurfaceSession s,
                        String name, int w, int h, int format, int flags)
@@ -694,7 +695,7 @@
                         + attrs.format + " flags=0x"
                         + Integer.toHexString(flags)
                         + " / " + this);
-            } catch (SurfaceControl.OutOfResourcesException e) {
+            } catch (OutOfResourcesException e) {
                 mWin.mHasSurface = false;
                 Slog.w(TAG, "OutOfResourcesException creating surface");
                 mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp
index 09e5be4..d8b8b94 100644
--- a/services/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/jni/com_android_server_input_InputManagerService.cpp
@@ -191,7 +191,8 @@
             uint32_t policyFlags);
     virtual void notifyConfigurationChanged(nsecs_t when);
     virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
-            const sp<InputWindowHandle>& inputWindowHandle);
+            const sp<InputWindowHandle>& inputWindowHandle,
+            const String8& reason);
     virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle);
     virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags);
     virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig);
@@ -553,7 +554,7 @@
 }
 
 nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
-        const sp<InputWindowHandle>& inputWindowHandle) {
+        const sp<InputWindowHandle>& inputWindowHandle, const String8& reason) {
 #if DEBUG_INPUT_DISPATCHER_POLICY
     ALOGD("notifyANR");
 #endif
@@ -564,15 +565,18 @@
             getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
     jobject inputWindowHandleObj =
             getInputWindowHandleObjLocalRef(env, inputWindowHandle);
+    jstring reasonObj = env->NewStringUTF(reason.string());
 
     jlong newTimeout = env->CallLongMethod(mServiceObj,
-                gServiceClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
+                gServiceClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj,
+                reasonObj);
     if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
         newTimeout = 0; // abort dispatch
     } else {
         assert(newTimeout >= 0);
     }
 
+    env->DeleteLocalRef(reasonObj);
     env->DeleteLocalRef(inputWindowHandleObj);
     env->DeleteLocalRef(inputApplicationHandleObj);
     return newTimeout;
@@ -1379,7 +1383,7 @@
 
     GET_METHOD_ID(gServiceClassInfo.notifyANR, clazz,
             "notifyANR",
-            "(Lcom/android/server/input/InputApplicationHandle;Lcom/android/server/input/InputWindowHandle;)J");
+            "(Lcom/android/server/input/InputApplicationHandle;Lcom/android/server/input/InputWindowHandle;Ljava/lang/String;)J");
 
     GET_METHOD_ID(gServiceClassInfo.filterInputEvent, clazz,
             "filterInputEvent", "(Landroid/view/InputEvent;I)Z");
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 40201ad..7d8b64f 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -309,7 +309,7 @@
      */
     public List<NeighboringCellInfo> getNeighboringCellInfo() {
         try {
-            return getITelephony().getNeighboringCellInfo(mContext.getBasePackageName());
+            return getITelephony().getNeighboringCellInfo(mContext.getOpPackageName());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index 252a14e..0d9cd18 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -112,6 +112,12 @@
         throw new UnsupportedOperationException();
     }
 
+    /** @hide */
+    @Override
+    public String getOpPackageName() {
+        throw new UnsupportedOperationException();
+    }
+
     @Override
     public ApplicationInfo getApplicationInfo() {
         throw new UnsupportedOperationException();
diff --git a/tools/layoutlib/bridge/src/android/webkit/WebView.java b/tools/layoutlib/bridge/src/android/webkit/WebView.java
index 3b66188..202f204 100644
--- a/tools/layoutlib/bridge/src/android/webkit/WebView.java
+++ b/tools/layoutlib/bridge/src/android/webkit/WebView.java
@@ -99,14 +99,6 @@
     public static void disablePlatformNotifications() {
     }
 
-    public WebBackForwardList saveState(Bundle outState) {
-        return null;
-    }
-
-    public WebBackForwardList restoreState(Bundle inState) {
-        return null;
-    }
-
     public void loadUrl(String url) {
     }
 
@@ -213,10 +205,6 @@
     public void clearSslPreferences() {
     }
 
-    public WebBackForwardList copyBackForwardList() {
-        return null;
-    }
-
     public static String findAddress(String addr) {
         return null;
     }
@@ -236,10 +224,6 @@
     public void addJavascriptInterface(Object obj, String interfaceName) {
     }
 
-    public WebSettings getSettings() {
-        return null;
-    }
-
     public View getZoomControls() {
         return null;
     }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index a1f2697..b9294ab 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -1090,6 +1090,12 @@
     }
 
     @Override
+    public String getOpPackageName() {
+        // pass
+        return null;
+    }
+
+    @Override
     public ApplicationInfo getApplicationInfo() {
         return mApplicationInfo;
     }
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 5f5d54f..2a5b4da 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -833,7 +833,7 @@
      */
     public List<BatchedScanResult> getBatchedScanResults() {
         try {
-            return mService.getBatchedScanResults(mContext.getBasePackageName());
+            return mService.getBatchedScanResults(mContext.getOpPackageName());
         } catch (RemoteException e) {
             return null;
         }
@@ -883,7 +883,7 @@
      */
     public List<ScanResult> getScanResults() {
         try {
-            return mService.getScanResults(mContext.getBasePackageName());
+            return mService.getScanResults(mContext.getOpPackageName());
         } catch (RemoteException e) {
             return null;
         }
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 83789e2..5626192 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -25,6 +25,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 
 /**
  * Native calls for bring up/shut down of the supplicant daemon and for
@@ -457,7 +458,7 @@
     }
 
     public boolean setCountryCode(String countryCode) {
-        return doBooleanCommand("DRIVER COUNTRY " + countryCode);
+        return doBooleanCommand("DRIVER COUNTRY " + countryCode.toUpperCase(Locale.ROOT));
     }
 
     public void enableBackgroundScan(boolean enable) {
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 3ccdbea..2bc22f2 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -88,7 +88,6 @@
 import java.net.Inet6Address;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Locale;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.Iterator;
@@ -1431,6 +1430,7 @@
                     countryCode);
         }
         sendMessage(CMD_SET_COUNTRY_CODE, countryCode);
+        mWifiP2pChannel.sendMessage(WifiP2pService.SET_COUNTRY_CODE, countryCode);
     }
 
     /**
@@ -2952,7 +2952,7 @@
                 case CMD_SET_COUNTRY_CODE:
                     String country = (String) message.obj;
                     if (DBG) log("set country code " + country);
-                    if (!mWifiNative.setCountryCode(country.toUpperCase(Locale.ROOT))) {
+                    if (!mWifiNative.setCountryCode(country)) {
                         loge("Failed to set country code " + country);
                     }
                     break;
@@ -4256,7 +4256,7 @@
     /**
      * arg2 on the source message has a unique id that needs to be retained in replies
      * to match the request
-     *
+
      * see WifiManager for details
      */
     private Message obtainMessageWithArg2(Message srcMsg) {
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 05196b8..625ffb8 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -174,6 +174,9 @@
     //   msg.obj  = StateMachine to send to when blocked
     public static final int BLOCK_DISCOVERY                 =   BASE + 15;
 
+    // set country code
+    public static final int SET_COUNTRY_CODE                =   BASE + 16;
+
     public static final int ENABLED                         = 1;
     public static final int DISABLED                        = 0;
 
@@ -632,6 +635,7 @@
                 case WifiP2pManager.START_LISTEN:
                 case WifiP2pManager.STOP_LISTEN:
                 case WifiP2pManager.SET_CHANNEL:
+                case SET_COUNTRY_CODE:
                     break;
                 case WifiStateMachine.CMD_ENABLE_P2P:
                     // Enable is lazy and has no response
@@ -1064,6 +1068,10 @@
                         replyToMessage(message, WifiP2pManager.SET_CHANNEL_FAILED);
                     }
                     break;
+                case SET_COUNTRY_CODE:
+                    String countryCode = (String) message.obj;
+                    mWifiNative.setCountryCode(countryCode);
+                    break;
                 default:
                    return NOT_HANDLED;
             }
@@ -2537,6 +2545,12 @@
         mServiceTransactionId = 0;
         mServiceDiscReqId = null;
 
+        String countryCode = Settings.Global.getString(mContext.getContentResolver(),
+                Settings.Global.WIFI_COUNTRY_CODE);
+        if (countryCode != null && !countryCode.isEmpty()) {
+            mP2pStateMachine.sendMessage(SET_COUNTRY_CODE, countryCode);
+        }
+
         updatePersistentNetworks(RELOAD);
     }