Merge "Add listener for changes to touch exploration state" into klp-dev
diff --git a/api/current.txt b/api/current.txt
index 9d73f5f..c1cc278 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5759,6 +5759,7 @@
     method public static java.util.List<android.content.SyncInfo> getCurrentSyncs();
     method public static int getIsSyncable(android.accounts.Account, java.lang.String);
     method public static boolean getMasterSyncAutomatically();
+    method public java.util.List<android.content.UriPermission> getOutgoingPersistedUriPermissions();
     method public static java.util.List<android.content.PeriodicSync> getPeriodicSyncs(android.accounts.Account, java.lang.String);
     method public java.util.List<android.content.UriPermission> getPersistedUriPermissions();
     method public java.lang.String[] getStreamTypes(android.net.Uri, java.lang.String);
@@ -28397,6 +28398,7 @@
     field public static final int SYSTEM_UI_FLAG_FULLSCREEN = 4; // 0x4
     field public static final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 2; // 0x2
     field public static final int SYSTEM_UI_FLAG_IMMERSIVE = 2048; // 0x800
+    field public static final int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 4096; // 0x1000
     field public static final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 1024; // 0x400
     field public static final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 512; // 0x200
     field public static final int SYSTEM_UI_FLAG_LAYOUT_STABLE = 256; // 0x100
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 961ee57..74266cc 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1160,7 +1160,10 @@
 
         case GET_PERSISTED_URI_PERMISSIONS_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
-            final ParceledListSlice<UriPermission> perms = getPersistedUriPermissions();
+            final String packageName = data.readString();
+            final boolean incoming = data.readInt() != 0;
+            final ParceledListSlice<UriPermission> perms = getPersistedUriPermissions(
+                    packageName, incoming);
             reply.writeNoException();
             perms.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
             return true;
@@ -3500,10 +3503,13 @@
     }
 
     @Override
-    public ParceledListSlice<UriPermission> getPersistedUriPermissions() throws RemoteException {
+    public ParceledListSlice<UriPermission> getPersistedUriPermissions(
+            String packageName, boolean incoming) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeString(packageName);
+        data.writeInt(incoming ? 1 : 0);
         mRemote.transact(GET_PERSISTED_URI_PERMISSIONS_TRANSACTION, data, reply, 0);
         reply.readException();
         final ParceledListSlice<UriPermission> perms = ParceledListSlice.CREATOR.createFromParcel(
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index e07b50f..df63ab3 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -95,6 +95,7 @@
 import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.Objects;
 import com.android.org.conscrypt.OpenSSLSocketImpl;
+import com.google.android.collect.Lists;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -1277,6 +1278,11 @@
                 }
             }
         }
+
+        @Override
+        public void scheduleInstallProvider(ProviderInfo provider) {
+            queueOrSendMessage(H.INSTALL_PROVIDER, provider);
+        }
     }
 
     private class H extends Handler {
@@ -1325,6 +1331,7 @@
         public static final int UNSTABLE_PROVIDER_DIED  = 142;
         public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
         public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
+        public static final int INSTALL_PROVIDER        = 145;
         String codeToString(int code) {
             if (DEBUG_MESSAGES) {
                 switch (code) {
@@ -1373,6 +1380,7 @@
                     case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
                     case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS";
                     case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE";
+                    case INSTALL_PROVIDER: return "INSTALL_PROVIDER";
                 }
             }
             return Integer.toString(code);
@@ -1590,6 +1598,9 @@
                 case TRANSLUCENT_CONVERSION_COMPLETE:
                     handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
                     break;
+                case INSTALL_PROVIDER:
+                    handleInstallProvider((ProviderInfo) msg.obj);
+                    break;
             }
             if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
         }
@@ -2330,6 +2341,10 @@
         }
     }
 
+    public void handleInstallProvider(ProviderInfo info) {
+        installContentProviders(mInitialApplication, Lists.newArrayList(info));
+    }
+
     private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
 
     /**
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index e40a04b..347d43f 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -618,6 +618,15 @@
             reply.writeNoException();
             return true;
         }
+
+        case SCHEDULE_INSTALL_PROVIDER_TRANSACTION:
+        {
+            data.enforceInterface(IApplicationThread.descriptor);
+            ProviderInfo provider = ProviderInfo.CREATOR.createFromParcel(data);
+            scheduleInstallProvider(provider);
+            reply.writeNoException();
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -1248,4 +1257,13 @@
         mRemote.transact(SET_PROCESS_STATE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
         data.recycle();
     }
+
+    @Override
+    public void scheduleInstallProvider(ProviderInfo provider) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        data.writeInterfaceToken(IApplicationThread.descriptor);
+        provider.writeToParcel(data, 0);
+        mRemote.transact(SCHEDULE_INSTALL_PROVIDER_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
+        data.recycle();
+    }
 }
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index dfea736..77c2ea0 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -215,7 +215,8 @@
             int mode) throws RemoteException;
     public void takePersistableUriPermission(Uri uri, int modeFlags) throws RemoteException;
     public void releasePersistableUriPermission(Uri uri, int modeFlags) throws RemoteException;
-    public ParceledListSlice<UriPermission> getPersistedUriPermissions() throws RemoteException;
+    public ParceledListSlice<UriPermission> getPersistedUriPermissions(
+            String packageName, boolean incoming) throws RemoteException;
 
     public void showWaitingForDebugger(IApplicationThread who, boolean waiting)
             throws RemoteException;
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 43a5fbd..d0cc1bb 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -137,6 +137,7 @@
     void scheduleTranslucentConversionComplete(IBinder token, boolean timeout)
             throws RemoteException;
     void setProcessState(int state) throws RemoteException;
+    void scheduleInstallProvider(ProviderInfo provider) throws RemoteException;
 
     String descriptor = "android.app.IApplicationThread";
 
@@ -189,4 +190,5 @@
     int REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+47;
     int SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+48;
     int SET_PROCESS_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+49;
+    int SCHEDULE_INSTALL_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+50;
 }
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 916a6cd..49dfdb5 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -1659,8 +1659,9 @@
     }
 
     /**
-     * Return list of all Uri permission grants that have been persisted for the
-     * calling app. Only persistable grants taken with
+     * Return list of all Uri permission grants that have been persisted by the
+     * calling app. That is, the returned permissions have been granted
+     * <em>to</em> the calling app. Only persistable grants taken with
      * {@link #takePersistableUriPermission(Uri, int)} are returned.
      *
      * @see #takePersistableUriPermission(Uri, int)
@@ -1668,7 +1669,23 @@
      */
     public List<UriPermission> getPersistedUriPermissions() {
         try {
-            return ActivityManagerNative.getDefault().getPersistedUriPermissions().getList();
+            return ActivityManagerNative.getDefault()
+                    .getPersistedUriPermissions(mPackageName, true).getList();
+        } catch (RemoteException e) {
+            throw new RuntimeException("Activity manager has died", e);
+        }
+    }
+
+    /**
+     * Return list of all persisted Uri permission grants that are hosted by the
+     * calling app. That is, the returned permissions have been granted
+     * <em>from</em> the calling app. Only grants taken with
+     * {@link #takePersistableUriPermission(Uri, int)} are returned.
+     */
+    public List<UriPermission> getOutgoingPersistedUriPermissions() {
+        try {
+            return ActivityManagerNative.getDefault()
+                    .getPersistedUriPermissions(mPackageName, false).getList();
         } catch (RemoteException e) {
             throw new RuntimeException("Activity manager has died", e);
         }
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index f30bcc5..898f123 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -82,6 +82,7 @@
     private CaptureRequest(CaptureRequest source) {
         mSettings = new CameraMetadataNative(source.mSettings);
         mSurfaceSet = (HashSet<Surface>) source.mSurfaceSet.clone();
+        mUserTag = source.mUserTag;
     }
 
     /**
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 9319d4a..1b7d9ea 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -687,6 +687,8 @@
         mThemeAttrs = obtainStyledAttributes(android.R.styleable.InputMethodService);
         mRootView = mInflater.inflate(
                 com.android.internal.R.layout.input_method, null);
+        mRootView.setSystemUiVisibility(
+                View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
         mWindow.setContentView(mRootView);
         mRootView.getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsComputer);
         if (Settings.Global.getInt(getContentResolver(),
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 1c14c38..c5e4f21 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -23,8 +23,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
 import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
 import android.graphics.Bitmap;
@@ -69,16 +68,15 @@
     private DocumentsContract() {
     }
 
-    /** {@hide} */
-    @Deprecated
-    public static final String META_DATA_DOCUMENT_PROVIDER = "android.content.DOCUMENT_PROVIDER";
-
     /**
      * Intent action used to identify {@link DocumentsProvider} instances.
      */
     public static final String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER";
 
     /** {@hide} */
+    public static final String EXTRA_PACKAGE_NAME = "android.content.extra.PACKAGE_NAME";
+
+    /** {@hide} */
     public static final String ACTION_MANAGE_ROOT = "android.provider.action.MANAGE_ROOT";
     /** {@hide} */
     public static final String ACTION_MANAGE_DOCUMENT = "android.provider.action.MANAGE_DOCUMENT";
@@ -565,11 +563,13 @@
             return false;
         }
 
-        final ProviderInfo info = context.getPackageManager()
-                .resolveContentProvider(uri.getAuthority(), PackageManager.GET_META_DATA);
-        if (info != null && info.metaData != null && info.metaData.containsKey(
-                DocumentsContract.META_DATA_DOCUMENT_PROVIDER)) {
-            return true;
+        final Intent intent = new Intent(PROVIDER_INTERFACE);
+        final List<ResolveInfo> infos = context.getPackageManager()
+                .queryIntentContentProviders(intent, 0);
+        for (ResolveInfo info : infos) {
+            if (uri.getAuthority().equals(info.providerInfo.authority)) {
+                return true;
+            }
         }
         return false;
     }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index c45307b..01da6b3 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2423,6 +2423,16 @@
 
     /**
      * Flag for {@link #setSystemUiVisibility(int)}: View would like to remain interactive when
+     * hiding the navigation bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.  If this flag is
+     * not set, {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} will be force cleared by the system on any
+     * user interaction.
+     * <p>Since this flag is a modifier for {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only
+     * has an effect when used in combination with that flag.</p>
+     */
+    public static final int SYSTEM_UI_FLAG_IMMERSIVE = 0x00000800;
+
+    /**
+     * Flag for {@link #setSystemUiVisibility(int)}: View would like to remain interactive when
      * hiding the status bar with {@link #SYSTEM_UI_FLAG_FULLSCREEN} and/or hiding the navigation
      * bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.  Use this flag to create an immersive
      * experience while also hiding the system bars.  If this flag is not set,
@@ -2437,7 +2447,7 @@
      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only has an effect when used in combination
      * with one or both of those flags.</p>
      */
-    public static final int SYSTEM_UI_FLAG_IMMERSIVE = 0x00000800;
+    public static final int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 0x00001000;
 
     /**
      * @deprecated Use {@link #SYSTEM_UI_FLAG_LOW_PROFILE} instead.
@@ -8885,10 +8895,10 @@
              */
             mPrivateFlags |= PFLAG_DRAWN;
 
-            if (((mViewFlags & VISIBILITY_MASK) == INVISIBLE) && hasFocus()) {
+            if (((mViewFlags & VISIBILITY_MASK) == INVISIBLE)) {
                 // root view becoming invisible shouldn't clear focus and accessibility focus
                 if (getRootView() != this) {
-                    clearFocus();
+                    if (hasFocus()) clearFocus();
                     clearAccessibilityFocus();
                 }
             }
@@ -16934,7 +16944,8 @@
      * @param visibility  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
      * {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
-     * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, and {@link #SYSTEM_UI_FLAG_IMMERSIVE}.
+     * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, {@link #SYSTEM_UI_FLAG_IMMERSIVE},
+     * and {@link #SYSTEM_UI_FLAG_IMMERSIVE_STICKY}.
      */
     public void setSystemUiVisibility(int visibility) {
         if (visibility != mSystemUiVisibility) {
@@ -16950,7 +16961,8 @@
      * @return  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
      * {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
-     * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, and {@link #SYSTEM_UI_FLAG_IMMERSIVE}.
+     * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, {@link #SYSTEM_UI_FLAG_IMMERSIVE},
+     * and {@link #SYSTEM_UI_FLAG_IMMERSIVE_STICKY}.
      */
     public int getSystemUiVisibility() {
         return mSystemUiVisibility;
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
index 6bef78e..7dd1e8a 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
@@ -86,7 +86,9 @@
                     refreshCachedNode(event.getSourceNodeId());
                 } break;
                 case AccessibilityEvent.TYPE_VIEW_SCROLLED: {
-                    clearSubTreeLocked(event.getSourceNodeId());
+                    synchronized (mLock) {
+                        clearSubTreeLocked(event.getSourceNodeId());
+                    }
                 } break;
                 case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: {
                     synchronized (mLock) {
diff --git a/core/java/com/android/internal/inputmethod/InputMethodRoot.java b/core/java/com/android/internal/inputmethod/InputMethodRoot.java
new file mode 100644
index 0000000..f070a58
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/InputMethodRoot.java
@@ -0,0 +1,61 @@
+/*
+ * 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 com.android.internal.inputmethod;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.widget.LinearLayout;
+
+public class InputMethodRoot extends LinearLayout {
+    private final Rect mGuardRect = new Rect();
+    private final Paint mGuardPaint = new Paint();
+
+    public InputMethodRoot(Context context) {
+        this(context, null);
+    }
+
+    public InputMethodRoot(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public InputMethodRoot(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs);
+        setWillNotDraw(false);
+        mGuardPaint.setColor(context.getResources()
+                .getColor(com.android.internal.R.color.input_method_navigation_guard));
+    }
+
+    @Override
+    protected boolean fitSystemWindows(Rect insets) {
+        setPadding(0, 0, 0, insets.bottom);
+        return true;
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+
+        // draw navigation bar guard
+        final int w = getMeasuredWidth();
+        final int h = getMeasuredHeight();
+        mGuardRect.set(0, h - getPaddingBottom(), w, h);
+        canvas.drawRect(mGuardRect, mGuardPaint);
+    }
+}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 04351da..73d34c3 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -322,6 +322,9 @@
                 // Restore default.
                 runtime.setTargetHeapUtilization(defaultUtilization);
 
+                // Fill in dex caches with classes, fields, and methods brought in by preloading.
+                runtime.preloadDexCaches();
+
                 Debug.stopAllocCounting();
 
                 // Bring back root. We'll need it later.
diff --git a/core/res/res/layout/input_method.xml b/core/res/res/layout/input_method.xml
index f80d628..23d7189 100644
--- a/core/res/res/layout/input_method.xml
+++ b/core/res/res/layout/input_method.xml
@@ -18,7 +18,7 @@
 */
 -->
 
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.internal.inputmethod.InputMethodRoot xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/parentPanel"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
@@ -52,4 +52,4 @@
         android:layout_height="wrap_content"
         android:visibility="gone">
     </FrameLayout>
-</LinearLayout>
+</com.android.internal.inputmethod.InputMethodRoot>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 81ee3af..28e7af7 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -78,6 +78,7 @@
 
     <drawable name="input_method_fullscreen_background">#fff9f9f9</drawable>
     <drawable name="input_method_fullscreen_background_holo">@drawable/screen_background_holo_dark</drawable>
+    <color name="input_method_navigation_guard">#ff000000</color>
 
     <!-- For date picker widget -->
     <drawable name="selected_day_background">#ff0092f4</drawable>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ad9144c..edfdcc2 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1441,6 +1441,7 @@
   <java-symbol type="bool" name="config_wimaxEnabled" />
   <java-symbol type="bool" name="show_ongoing_ime_switcher" />
   <java-symbol type="color" name="config_defaultNotificationColor" />
+  <java-symbol type="color" name="input_method_navigation_guard" />
   <java-symbol type="drawable" name="ic_notification_ime_default" />
   <java-symbol type="drawable" name="ic_notify_wifidisplay" />
   <java-symbol type="drawable" name="ic_menu_refresh" />
diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java
index 32e85d9..7865ec8 100644
--- a/media/java/android/media/RemoteController.java
+++ b/media/java/android/media/RemoteController.java
@@ -36,6 +36,8 @@
 import android.util.Log;
 import android.view.KeyEvent;
 
+import java.lang.ref.WeakReference;
+
 /**
  * The RemoteController class is used to control media playback, display and update media metadata
  * and playback status, published by applications using the {@link RemoteControlClient} class.
@@ -122,7 +124,7 @@
         }
         mOnClientUpdateListener = updateListener;
         mContext = context;
-        mRcd = new RcDisplay();
+        mRcd = new RcDisplay(this);
         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
 
         if (ActivityManager.isLowRamDeviceStatic()) {
@@ -505,34 +507,51 @@
 
     //==================================================
     // Implementation of IRemoteControlDisplay interface
-    private class RcDisplay extends IRemoteControlDisplay.Stub {
+    private static class RcDisplay extends IRemoteControlDisplay.Stub {
+        private final WeakReference<RemoteController> mController;
+
+        RcDisplay(RemoteController rc) {
+            mController = new WeakReference<RemoteController>(rc);
+        }
 
         public void setCurrentClientId(int genId, PendingIntent clientMediaIntent,
                 boolean clearing) {
+            final RemoteController rc = mController.get();
+            if (rc == null) {
+                return;
+            }
             boolean isNew = false;
             synchronized(mGenLock) {
-                if (mClientGenerationIdCurrent != genId) {
-                    mClientGenerationIdCurrent = genId;
+                if (rc.mClientGenerationIdCurrent != genId) {
+                    rc.mClientGenerationIdCurrent = genId;
                     isNew = true;
                 }
             }
             if (clientMediaIntent != null) {
-                sendMsg(mEventHandler, MSG_NEW_PENDING_INTENT, SENDMSG_REPLACE,
+                sendMsg(rc.mEventHandler, MSG_NEW_PENDING_INTENT, SENDMSG_REPLACE,
                         genId /*arg1*/, 0, clientMediaIntent /*obj*/, 0 /*delay*/);
             }
             if (isNew || clearing) {
-                sendMsg(mEventHandler, MSG_CLIENT_CHANGE, SENDMSG_REPLACE,
+                sendMsg(rc.mEventHandler, MSG_CLIENT_CHANGE, SENDMSG_REPLACE,
                         genId /*arg1*/, clearing ? 1 : 0, null /*obj*/, 0 /*delay*/);
             }
         }
 
         public void setEnabled(boolean enabled) {
-            sendMsg(mEventHandler, MSG_DISPLAY_ENABLE, SENDMSG_REPLACE,
+            final RemoteController rc = mController.get();
+            if (rc == null) {
+                return;
+            }
+            sendMsg(rc.mEventHandler, MSG_DISPLAY_ENABLE, SENDMSG_REPLACE,
                     enabled ? 1 : 0 /*arg1*/, 0, null /*obj*/, 0 /*delay*/);
         }
 
         public void setPlaybackState(int genId, int state,
                 long stateChangeTimeMs, long currentPosMs, float speed) {
+            final RemoteController rc = mController.get();
+            if (rc == null) {
+                return;
+            }
             if (DEBUG) {
                 Log.d(TAG, "> new playback state: genId="+genId
                         + " state="+ state
@@ -542,65 +561,81 @@
             }
 
             synchronized(mGenLock) {
-                if (mClientGenerationIdCurrent != genId) {
+                if (rc.mClientGenerationIdCurrent != genId) {
                     return;
                 }
             }
             final PlaybackInfo playbackInfo =
                     new PlaybackInfo(state, stateChangeTimeMs, currentPosMs, speed);
-            sendMsg(mEventHandler, MSG_NEW_PLAYBACK_INFO, SENDMSG_REPLACE,
+            sendMsg(rc.mEventHandler, MSG_NEW_PLAYBACK_INFO, SENDMSG_REPLACE,
                     genId /*arg1*/, 0, playbackInfo /*obj*/, 0 /*delay*/);
 
         }
 
         public void setTransportControlInfo(int genId, int transportControlFlags,
                 int posCapabilities) {
+            final RemoteController rc = mController.get();
+            if (rc == null) {
+                return;
+            }
             synchronized(mGenLock) {
-                if (mClientGenerationIdCurrent != genId) {
+                if (rc.mClientGenerationIdCurrent != genId) {
                     return;
                 }
             }
-            sendMsg(mEventHandler, MSG_NEW_TRANSPORT_INFO, SENDMSG_REPLACE,
+            sendMsg(rc.mEventHandler, MSG_NEW_TRANSPORT_INFO, SENDMSG_REPLACE,
                     genId /*arg1*/, transportControlFlags /*arg2*/,
                     null /*obj*/, 0 /*delay*/);
         }
 
         public void setMetadata(int genId, Bundle metadata) {
+            final RemoteController rc = mController.get();
+            if (rc == null) {
+                return;
+            }
             if (DEBUG) { Log.e(TAG, "setMetadata("+genId+")"); }
             if (metadata == null) {
                 return;
             }
             synchronized(mGenLock) {
-                if (mClientGenerationIdCurrent != genId) {
+                if (rc.mClientGenerationIdCurrent != genId) {
                     return;
                 }
             }
-            sendMsg(mEventHandler, MSG_NEW_METADATA, SENDMSG_QUEUE,
+            sendMsg(rc.mEventHandler, MSG_NEW_METADATA, SENDMSG_QUEUE,
                     genId /*arg1*/, 0 /*arg2*/,
                     metadata /*obj*/, 0 /*delay*/);
         }
 
         public void setArtwork(int genId, Bitmap artwork) {
+            final RemoteController rc = mController.get();
+            if (rc == null) {
+                return;
+            }
             if (DEBUG) { Log.v(TAG, "setArtwork("+genId+")"); }
             synchronized(mGenLock) {
-                if (mClientGenerationIdCurrent != genId) {
+                if (rc.mClientGenerationIdCurrent != genId) {
                     return;
                 }
             }
             Bundle metadata = new Bundle(1);
             metadata.putParcelable(String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK), artwork);
-            sendMsg(mEventHandler, MSG_NEW_METADATA, SENDMSG_QUEUE,
+            sendMsg(rc.mEventHandler, MSG_NEW_METADATA, SENDMSG_QUEUE,
                     genId /*arg1*/, 0 /*arg2*/,
                     metadata /*obj*/, 0 /*delay*/);
         }
 
         public void setAllMetadata(int genId, Bundle metadata, Bitmap artwork) {
+            final RemoteController rc = mController.get();
+            if (rc == null) {
+                return;
+            }
             if (DEBUG) { Log.e(TAG, "setAllMetadata("+genId+")"); }
             if ((metadata == null) && (artwork == null)) {
                 return;
             }
             synchronized(mGenLock) {
-                if (mClientGenerationIdCurrent != genId) {
+                if (rc.mClientGenerationIdCurrent != genId) {
                     return;
                 }
             }
@@ -611,7 +646,7 @@
                 metadata.putParcelable(String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK),
                         artwork);
             }
-            sendMsg(mEventHandler, MSG_NEW_METADATA, SENDMSG_QUEUE,
+            sendMsg(rc.mEventHandler, MSG_NEW_METADATA, SENDMSG_QUEUE,
                     genId /*arg1*/, 0 /*arg2*/,
                     metadata /*obj*/, 0 /*delay*/);
         }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
index 22dd6e4..90be197 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
@@ -73,7 +73,7 @@
                 final DocumentsActivity activity = (DocumentsActivity) getActivity();
                 final DocumentInfo cwd = activity.getCurrentDirectory();
 
-                new CreateDirectoryTask(displayName).executeOnExecutor(
+                new CreateDirectoryTask(activity, cwd, displayName).executeOnExecutor(
                         ProviderExecutor.forAuthority(cwd.authority));
             }
         });
@@ -83,25 +83,26 @@
     }
 
     private class CreateDirectoryTask extends AsyncTask<Void, Void, DocumentInfo> {
+        private final DocumentsActivity mActivity;
+        private final DocumentInfo mCwd;
         private final String mDisplayName;
 
-        public CreateDirectoryTask(String displayName) {
+        public CreateDirectoryTask(
+                DocumentsActivity activity, DocumentInfo cwd, String displayName) {
+            mActivity = activity;
+            mCwd = cwd;
             mDisplayName = displayName;
         }
 
         @Override
         protected DocumentInfo doInBackground(Void... params) {
-            final DocumentsActivity activity = (DocumentsActivity) getActivity();
-            final ContentResolver resolver = activity.getContentResolver();
-
-            final DocumentInfo cwd = activity.getCurrentDirectory();
-
+            final ContentResolver resolver = mActivity.getContentResolver();
             ContentProviderClient client = null;
             try {
                 client = DocumentsApplication.acquireUnstableProviderOrThrow(
-                        resolver, cwd.derivedUri.getAuthority());
+                        resolver, mCwd.derivedUri.getAuthority());
                 final Uri childUri = DocumentsContract.createDocument(
-                        client, cwd.derivedUri, Document.MIME_TYPE_DIR, mDisplayName);
+                        client, mCwd.derivedUri, Document.MIME_TYPE_DIR, mDisplayName);
                 return DocumentInfo.fromUri(resolver, childUri);
             } catch (Exception e) {
                 Log.w(TAG, "Failed to create directory", e);
@@ -113,12 +114,11 @@
 
         @Override
         protected void onPostExecute(DocumentInfo result) {
-            final DocumentsActivity activity = (DocumentsActivity) getActivity();
             if (result != null) {
                 // Navigate into newly created child
-                activity.onDocumentPicked(result);
+                mActivity.onDocumentPicked(result);
             } else {
-                Toast.makeText(activity, R.string.create_error, Toast.LENGTH_SHORT).show();
+                Toast.makeText(mActivity, R.string.create_error, Toast.LENGTH_SHORT).show();
             }
         }
     }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index 7660779..d675e8d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -292,7 +292,7 @@
         @Override
         protected Void doInBackground(Void... params) {
             // Restore last stack for calling package
-            final String packageName = getCallingPackage();
+            final String packageName = getCallingPackageMaybeExtra();
             final Cursor cursor = getContentResolver()
                     .query(RecentsProvider.buildResume(packageName), null, null, null, null);
             try {
@@ -783,6 +783,11 @@
         return mState.stack.peek();
     }
 
+    private String getCallingPackageMaybeExtra() {
+        final String extra = getIntent().getStringExtra(DocumentsContract.EXTRA_PACKAGE_NAME);
+        return (extra != null) ? extra : getCallingPackage();
+    }
+
     public Executor getCurrentExecutor() {
         final DocumentInfo cwd = getCurrentDirectory();
         if (cwd != null && cwd.authority != null) {
@@ -921,7 +926,7 @@
         if (requestCode == CODE_FORWARD && resultCode != RESULT_CANCELED) {
 
             // Remember that we last picked via external app
-            final String packageName = getCallingPackage();
+            final String packageName = getCallingPackageMaybeExtra();
             final ContentValues values = new ContentValues();
             values.put(ResumeColumns.EXTERNAL, 1);
             getContentResolver().insert(RecentsProvider.buildResume(packageName), values);
@@ -1002,7 +1007,7 @@
         }
 
         // Remember location for next app launch
-        final String packageName = getCallingPackage();
+        final String packageName = getCallingPackageMaybeExtra();
         values.clear();
         values.put(ResumeColumns.STACK, rawStack);
         values.put(ResumeColumns.EXTERNAL, 0);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
index eb56765..b98e1ee 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
@@ -194,16 +194,6 @@
                 handleDocumentsProvider(info.providerInfo);
             }
 
-            // Pick up legacy providers
-            final List<ProviderInfo> legacyProviders = pm.queryContentProviders(
-                    null, -1, PackageManager.GET_META_DATA);
-            for (ProviderInfo info : legacyProviders) {
-                if (info.metaData != null && info.metaData.containsKey(
-                        DocumentsContract.META_DATA_DOCUMENT_PROVIDER)) {
-                    handleDocumentsProvider(info);
-                }
-            }
-
             final long delta = SystemClock.elapsedRealtime() - start;
             Log.d(TAG, "Update found " + mTaskRoots.size() + " roots in " + delta + "ms");
             synchronized (mLock) {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
index 6584180..58ca0b0 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
@@ -420,6 +420,7 @@
     public synchronized void onScreenTurnedOn(final IKeyguardShowCallback callback) {
         if (DEBUG) Log.d(TAG, "onScreenTurnedOn()");
         mScreenOn = true;
+        final IBinder token = mKeyguardHost == null ? null : mKeyguardHost.getWindowToken();
         if (mKeyguardView != null) {
             mKeyguardView.onScreenTurnedOn();
 
@@ -432,10 +433,6 @@
                     mKeyguardHost.post(new Runnable() {
                         @Override
                         public void run() {
-                            IBinder token = null;
-                            if (mKeyguardHost.getVisibility() == View.VISIBLE) {
-                                token = mKeyguardHost.getWindowToken();
-                            }
                             try {
                                 callback.onShown(token);
                             } catch (RemoteException e) {
@@ -445,7 +442,7 @@
                     });
                 } else {
                     try {
-                        callback.onShown(null);
+                        callback.onShown(token);
                     } catch (RemoteException e) {
                         Slog.w(TAG, "Exception calling onShown():", e);
                     }
@@ -453,7 +450,7 @@
             }
         } else if (callback != null) {
             try {
-                callback.onShown(null);
+                callback.onShown(token);
             } catch (RemoteException e) {
                 Slog.w(TAG, "Exception calling onShown():", e);
             }
diff --git a/packages/SystemUI/res/drawable-hdpi/bottom_divider_glow.png b/packages/SystemUI/res/drawable-hdpi/bottom_divider_glow.png
index e8cfc0f..d1948d6 100644
--- a/packages/SystemUI/res/drawable-hdpi/bottom_divider_glow.png
+++ b/packages/SystemUI/res/drawable-hdpi/bottom_divider_glow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/top_divider_glow.png b/packages/SystemUI/res/drawable-hdpi/top_divider_glow.png
index 89cd10e..a540efb1 100644
--- a/packages/SystemUI/res/drawable-hdpi/top_divider_glow.png
+++ b/packages/SystemUI/res/drawable-hdpi/top_divider_glow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/bottom_divider_glow.png b/packages/SystemUI/res/drawable-mdpi/bottom_divider_glow.png
index 7d7868d..ba25f65 100644
--- a/packages/SystemUI/res/drawable-mdpi/bottom_divider_glow.png
+++ b/packages/SystemUI/res/drawable-mdpi/bottom_divider_glow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/top_divider_glow.png b/packages/SystemUI/res/drawable-mdpi/top_divider_glow.png
index f93da09..53d85de 100644
--- a/packages/SystemUI/res/drawable-mdpi/top_divider_glow.png
+++ b/packages/SystemUI/res/drawable-mdpi/top_divider_glow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/bottom_divider_glow.png b/packages/SystemUI/res/drawable-xhdpi/bottom_divider_glow.png
index bbcea9e..0b012b4 100644
--- a/packages/SystemUI/res/drawable-xhdpi/bottom_divider_glow.png
+++ b/packages/SystemUI/res/drawable-xhdpi/bottom_divider_glow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/top_divider_glow.png b/packages/SystemUI/res/drawable-xhdpi/top_divider_glow.png
index 56b63d0..d4526c0 100644
--- a/packages/SystemUI/res/drawable-xhdpi/top_divider_glow.png
+++ b/packages/SystemUI/res/drawable-xhdpi/top_divider_glow.png
Binary files differ
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 c02a99b..04ca4d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1923,10 +1923,8 @@
     }
 
     private void checkBarMode(int mode, int windowState, BarTransitions transitions) {
-        final boolean imeVisible = (mNavigationIconHints & NAVIGATION_HINT_BACK_ALT) != 0;
-        final int finalMode = imeVisible ? MODE_OPAQUE : mode;
         final boolean anim = (mScreenOn == null || mScreenOn) && windowState != WINDOW_STATE_HIDDEN;
-        transitions.transitionTo(finalMode, anim);
+        transitions.transitionTo(mode, anim);
     }
 
     private final Runnable mCheckBarModes = new Runnable() {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index adbada7..e9e3b27 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -2991,8 +2991,10 @@
             pf.left = df.left = of.left = cf.left = vf.left = mDockLeft;
             pf.top = df.top = of.top = cf.top = vf.top = mDockTop;
             pf.right = df.right = of.right = cf.right = vf.right = mDockRight;
-            // IM dock windows always go above the nav bar.
-            pf.bottom = df.bottom = of.bottom = cf.bottom = vf.bottom = mStableBottom;
+            // IM dock windows layout below the nav bar...
+            pf.bottom = df.bottom = of.bottom = mRestrictedScreenTop + mRestrictedScreenHeight;
+            // ...with content insets above the nav bar
+            cf.bottom = vf.bottom = mStableBottom;
             // IM dock windows always go to the bottom of the screen.
             attrs.gravity = Gravity.BOTTOM;
             mDockLayer = win.getSurfaceLayer();
@@ -4282,12 +4284,14 @@
                 })) {
                     return;
                 }
+                Slog.i(TAG, "No lock screen! waitForWindowDrawn false");
+
             } catch (RemoteException ex) {
                 // Can't happen in system process.
             }
         }
 
-        Slog.i(TAG, "No lock screen!");
+        Slog.i(TAG, "No lock screen! windowToken=" + windowToken);
         finishScreenTurningOn(screenOnListener);
     }
 
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 59b559e..5695ee5 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -4247,6 +4247,9 @@
                                 addrTried ++) {
 
                             // Choose the address at random but make sure its type is supported
+                            // TODO: This doesn't work 100% of the time, because we may end up
+                            // trying the same invalid address more than once and ignoring one
+                            // of the valid addresses.
                             InetAddress hostAddr = addresses[rand.nextInt(addresses.length)];
                             if (((hostAddr instanceof Inet4Address) && linkHasIpv4)
                                     || ((hostAddr instanceof Inet6Address) && linkHasIpv6)) {
@@ -4271,10 +4274,8 @@
                             }
 
                             // Rewrite the url to have numeric address to use the specific route.
-                            // I also set the "Connection" to "Close" as by default "Keep-Alive"
-                            // is used which is useless in this case.
-                            URL newUrl = new URL(orgUri.getScheme() + "://"
-                                    + hostAddr.getHostAddress() + orgUri.getPath());
+                            URL newUrl = new URL(orgUri.getScheme(),
+                                    hostAddr.getHostAddress(), orgUri.getPath());
                             log("isMobileOk: newUrl=" + newUrl);
 
                             HttpURLConnection urlConn = null;
@@ -4287,6 +4288,8 @@
                                 urlConn.setReadTimeout(SOCKET_TIMEOUT_MS);
                                 urlConn.setUseCaches(false);
                                 urlConn.setAllowUserInteraction(false);
+                                // Set the "Connection" to "Close" as by default "Keep-Alive"
+                                // is used which is useless in this case.
                                 urlConn.setRequestProperty("Connection", "close");
                                 int responseCode = urlConn.getResponseCode();
 
diff --git a/services/java/com/android/server/accounts/AccountManagerService.java b/services/java/com/android/server/accounts/AccountManagerService.java
index dd9ae4c..cc43a9c 100644
--- a/services/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/java/com/android/server/accounts/AccountManagerService.java
@@ -293,17 +293,16 @@
         return mUserManager;
     }
 
-    private UserAccounts initUser(int userId) {
-        synchronized (mUsers) {
-            UserAccounts accounts = mUsers.get(userId);
-            if (accounts == null) {
-                accounts = new UserAccounts(mContext, userId);
-                mUsers.append(userId, accounts);
-                purgeOldGrants(accounts);
-                validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */);
-            }
-            return accounts;
+    /* Caller should lock mUsers */
+    private UserAccounts initUserLocked(int userId) {
+        UserAccounts accounts = mUsers.get(userId);
+        if (accounts == null) {
+            accounts = new UserAccounts(mContext, userId);
+            mUsers.append(userId, accounts);
+            purgeOldGrants(accounts);
+            validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */);
         }
+        return accounts;
     }
 
     private void purgeOldGrantsAll() {
@@ -427,7 +426,7 @@
         synchronized (mUsers) {
             UserAccounts accounts = mUsers.get(userId);
             if (accounts == null) {
-                accounts = initUser(userId);
+                accounts = initUserLocked(userId);
                 mUsers.append(userId, accounts);
             }
             return accounts;
@@ -1798,16 +1797,14 @@
 
     private AccountAndUser[] getAccounts(int[] userIds) {
         final ArrayList<AccountAndUser> runningAccounts = Lists.newArrayList();
-        synchronized (mUsers) {
-            for (int userId : userIds) {
-                UserAccounts userAccounts = getUserAccounts(userId);
-                if (userAccounts == null) continue;
-                synchronized (userAccounts.cacheLock) {
-                    Account[] accounts = getAccountsFromCacheLocked(userAccounts, null,
-                            Binder.getCallingUid(), null);
-                    for (int a = 0; a < accounts.length; a++) {
-                        runningAccounts.add(new AccountAndUser(accounts[a], userId));
-                    }
+        for (int userId : userIds) {
+            UserAccounts userAccounts = getUserAccounts(userId);
+            if (userAccounts == null) continue;
+            synchronized (userAccounts.cacheLock) {
+                Account[] accounts = getAccountsFromCacheLocked(userAccounts, null,
+                        Binder.getCallingUid(), null);
+                for (int a = 0; a < accounts.length; a++) {
+                    runningAccounts.add(new AccountAndUser(accounts[a], userId));
                 }
             }
         }
@@ -2858,7 +2855,8 @@
                 || callingUid == Process.myUid()) {
             return unfiltered;
         }
-        if (mUserManager.getUserInfo(userAccounts.userId).isRestricted()) {
+        UserInfo user = mUserManager.getUserInfo(userAccounts.userId);
+        if (user != null && user.isRestricted()) {
             String[] packages = mPackageManager.getPackagesForUid(callingUid);
             // If any of the packages is a white listed package, return the full set,
             // otherwise return non-shared accounts only.
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 1987d04..6c6cc98 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -6489,26 +6489,53 @@
     }
 
     @Override
-    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions() {
+    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
+            String packageName, boolean incoming) {
         enforceNotIsolatedCaller("getPersistedUriPermissions");
+        Preconditions.checkNotNull(packageName, "packageName");
 
+        final int callingUid = Binder.getCallingUid();
+        final IPackageManager pm = AppGlobals.getPackageManager();
+        try {
+            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
+            if (packageUid != callingUid) {
+                throw new SecurityException(
+                        "Package " + packageName + " does not belong to calling UID " + callingUid);
+            }
+        } catch (RemoteException e) {
+            throw new SecurityException("Failed to verify package name ownership");
+        }
+
+        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
         synchronized (this) {
-            final int callingUid = Binder.getCallingUid();
-            final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
-            final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
-            if (perms == null) {
-                Slog.w(TAG, "No permission grants found for UID " + callingUid);
+            if (incoming) {
+                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
+                if (perms == null) {
+                    Slog.w(TAG, "No permission grants found for " + packageName);
+                } else {
+                    final int size = perms.size();
+                    for (int i = 0; i < size; i++) {
+                        final UriPermission perm = perms.valueAt(i);
+                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
+                            result.add(perm.buildPersistedPublicApiObject());
+                        }
+                    }
+                }
             } else {
-                final int size = perms.size();
+                final int size = mGrantedUriPermissions.size();
                 for (int i = 0; i < size; i++) {
-                    final UriPermission perm = perms.valueAt(i);
-                    if (perm.persistedModeFlags != 0) {
-                        result.add(perm.buildPersistedPublicApiObject());
+                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
+                    final int permsSize = perms.size();
+                    for (int j = 0; j < permsSize; j++) {
+                        final UriPermission perm = perms.valueAt(j);
+                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
+                            result.add(perm.buildPersistedPublicApiObject());
+                        }
                     }
                 }
             }
-            return new ParceledListSlice<android.content.UriPermission>(result);
         }
+        return new ParceledListSlice<android.content.UriPermission>(result);
     }
 
     @Override
@@ -6755,7 +6782,6 @@
     private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
         tr.disposeThumbnail();
         mRecentTasks.remove(tr);
-        mStackSupervisor.removeTask(tr);
         final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
         Intent baseIntent = new Intent(
                 tr.intent != null ? tr.intent : tr.affinityIntent);
@@ -7526,16 +7552,30 @@
                                     + cpr.appInfo.packageName + ": " + e);
                         }
 
-                        ProcessRecord proc = startProcessLocked(cpi.processName,
-                                cpr.appInfo, false, 0, "content provider",
-                                new ComponentName(cpi.applicationInfo.packageName,
-                                        cpi.name), false, false, false);
-                        if (proc == null) {
-                            Slog.w(TAG, "Unable to launch app "
-                                    + cpi.applicationInfo.packageName + "/"
-                                    + cpi.applicationInfo.uid + " for provider "
-                                    + name + ": process is bad");
-                            return null;
+                        // Use existing process if already started
+                        ProcessRecord proc = getProcessRecordLocked(
+                                cpi.processName, cpr.appInfo.uid, false);
+                        if (proc != null) {
+                            if (DEBUG_PROVIDER) {
+                                Slog.d(TAG, "Installing in existing process " + proc);
+                            }
+                            proc.pubProviders.put(cpi.name, cpr);
+                            try {
+                                proc.thread.scheduleInstallProvider(cpi);
+                            } catch (RemoteException e) {
+                            }
+                        } else {
+                            proc = startProcessLocked(cpi.processName,
+                                    cpr.appInfo, false, 0, "content provider",
+                                    new ComponentName(cpi.applicationInfo.packageName,
+                                            cpi.name), false, false, false);
+                            if (proc == null) {
+                                Slog.w(TAG, "Unable to launch app "
+                                        + cpi.applicationInfo.packageName + "/"
+                                        + cpi.applicationInfo.uid + " for provider "
+                                        + name + ": process is bad");
+                                return null;
+                            }
                         }
                         cpr.launchingApp = proc;
                         mLaunchingProviders.add(cpr);
diff --git a/services/java/com/android/server/am/ProcessStatsService.java b/services/java/com/android/server/am/ProcessStatsService.java
index dbc05fa..a6375e1 100644
--- a/services/java/com/android/server/am/ProcessStatsService.java
+++ b/services/java/com/android/server/am/ProcessStatsService.java
@@ -566,6 +566,15 @@
             return;
         }
 
+        long ident = Binder.clearCallingIdentity();
+        try {
+            dumpInner(fd, pw, args);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    private void dumpInner(FileDescriptor fd, PrintWriter pw, String[] args) {
         final long now = SystemClock.uptimeMillis();
 
         boolean isCheckin = false;
diff --git a/services/java/com/android/server/am/UriPermission.java b/services/java/com/android/server/am/UriPermission.java
index 5868c08..684f247 100644
--- a/services/java/com/android/server/am/UriPermission.java
+++ b/services/java/com/android/server/am/UriPermission.java
@@ -20,7 +20,6 @@
 import android.net.Uri;
 import android.os.UserHandle;
 import android.util.Log;
-import android.util.Slog;
 
 import com.android.internal.util.Preconditions;
 import com.google.android.collect.Sets;
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index e089ca6..0fc10f9 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -9473,9 +9473,8 @@
                 //Slog.i(TAG, "Waiting for drawn " + win + ": removed="
                 //        + win.mRemoved + " visible=" + win.isVisibleLw()
                 //        + " shown=" + win.mSurfaceShown);
-                if (win.mRemoved || !win.isVisibleLw()) {
-                    // Window has been removed or made invisible; no draw
-                    // will now happen, so stop waiting.
+                if (win.mRemoved) {
+                    // Window has been removed; no draw will now happen, so stop waiting.
                     Slog.w(TAG, "Aborted waiting for drawn: " + pair.first);
                     try {
                         pair.second.sendResult(null);
@@ -9510,6 +9509,7 @@
                     checkDrawnWindowsLocked();
                     return true;
                 }
+                Slog.i(TAG, "waitForWindowDrawn: win null");
             }
         }
         return false;
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index 6978551..e3c664b 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -20,6 +20,7 @@
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
+import android.location.Country;
 import android.location.CountryDetector;
 import android.net.Uri;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
@@ -561,17 +562,23 @@
      *         is in.
      */
     private static String getCurrentCountryIso(Context context, Locale locale) {
-      String countryIso;
-      CountryDetector detector = (CountryDetector) context.getSystemService(
-          Context.COUNTRY_DETECTOR);
-      if (detector != null) {
-        countryIso = detector.detectCountry().getCountryIso();
-      } else {
-        countryIso = locale.getCountry();
-        Rlog.w(TAG, "No CountryDetector; falling back to countryIso based on locale: "
-              + countryIso);
-      }
-      return countryIso;
+        String countryIso = null;
+        CountryDetector detector = (CountryDetector) context.getSystemService(
+                Context.COUNTRY_DETECTOR);
+        if (detector != null) {
+            Country country = detector.detectCountry();
+            if (country != null) {
+                countryIso = country.getCountryIso();
+            } else {
+                Rlog.e(TAG, "CountryDetector.detectCountry() returned null.");
+            }
+        }
+        if (countryIso == null) {
+            countryIso = locale.getCountry();
+            Rlog.w(TAG, "No CountryDetector; falling back to countryIso based on locale: "
+                    + countryIso);
+        }
+        return countryIso;
     }
 
     /**