Merge "Rename methods/variables on PhoneAccount for API cleanup." into lmp-dev
diff --git a/api/current.txt b/api/current.txt
index f61c528..0efa148 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8617,21 +8617,16 @@
 
   public class LauncherApps {
     method public void addCallback(android.content.pm.LauncherApps.Callback);
-    method public void addCallback(android.content.pm.LauncherApps.Callback, android.os.Handler);
-    method public void addOnAppsChangedCallback(android.content.pm.LauncherApps.OnAppsChangedCallback);
-    method public void addOnAppsChangedCallback(android.content.pm.LauncherApps.OnAppsChangedCallback, android.os.Handler);
     method public java.util.List<android.content.pm.LauncherActivityInfo> getActivityList(java.lang.String, android.os.UserHandle);
     method public boolean isActivityEnabled(android.content.ComponentName, android.os.UserHandle);
-    method public boolean isActivityEnabledForProfile(android.content.ComponentName, android.os.UserHandle);
     method public boolean isPackageEnabled(java.lang.String, android.os.UserHandle);
-    method public boolean isPackageEnabledForProfile(java.lang.String, android.os.UserHandle);
+    method public void registerCallback(android.content.pm.LauncherApps.Callback);
+    method public void registerCallback(android.content.pm.LauncherApps.Callback, android.os.Handler);
     method public void removeCallback(android.content.pm.LauncherApps.Callback);
-    method public void removeOnAppsChangedCallback(android.content.pm.LauncherApps.OnAppsChangedCallback);
     method public android.content.pm.LauncherActivityInfo resolveActivity(android.content.Intent, android.os.UserHandle);
-    method public void showAppDetailsForProfile(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle);
-    method public void startActivityForProfile(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle);
     method public void startAppDetailsActivity(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle);
     method public void startMainActivity(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle);
+    method public void unregisterCallback(android.content.pm.LauncherApps.Callback);
   }
 
   public static abstract class LauncherApps.Callback {
@@ -8643,10 +8638,6 @@
     method public abstract void onPackagesUnavailable(java.lang.String[], android.os.UserHandle, boolean);
   }
 
-  public static abstract class LauncherApps.OnAppsChangedCallback extends android.content.pm.LauncherApps.Callback {
-    ctor public LauncherApps.OnAppsChangedCallback();
-  }
-
   public class PackageInfo implements android.os.Parcelable {
     ctor public PackageInfo();
     method public int describeContents();
@@ -23704,7 +23695,6 @@
     field public static final java.lang.String DURATION = "duration";
     field public static final java.lang.String EXTRA_CALL_TYPE_FILTER = "android.provider.extra.CALL_TYPE_FILTER";
     field public static final java.lang.String FEATURES = "features";
-    field public static final int FEATURES_NONE = 0; // 0x0
     field public static final int FEATURES_VIDEO = 1; // 0x1
     field public static final java.lang.String GEOCODED_LOCATION = "geocoded_location";
     field public static final int INCOMING_TYPE = 1; // 0x1
@@ -28890,8 +28880,6 @@
     method public void downloadMultimediaMessage(java.lang.String, android.net.Uri, android.os.Bundle, android.app.PendingIntent);
     method public android.os.Bundle getCarrierConfigValues();
     method public static android.telephony.SmsManager getDefault();
-    method public static android.telephony.SmsManager getSmsManagerUsingSubId(long);
-    method public long getSubId();
     method public void injectSmsPdu(byte[], java.lang.String, android.app.PendingIntent);
     method public void sendDataMessage(java.lang.String, java.lang.String, short, byte[], android.app.PendingIntent, android.app.PendingIntent);
     method public void sendMultimediaMessage(android.net.Uri, java.lang.String, android.os.Bundle, android.app.PendingIntent);
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 5f7a17d..27a03b6 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -54,6 +54,10 @@
         int action, in Bundle arguments, int interactionId,
         IAccessibilityInteractionConnectionCallback callback, long threadId);
 
+    boolean computeClickPointInScreen(int accessibilityWindowId, long accessibilityNodeId,
+        int interactionId, IAccessibilityInteractionConnectionCallback callback,
+        long threadId);
+
     AccessibilityWindowInfo getWindow(int windowId);
 
     List<AccessibilityWindowInfo> getWindows();
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index cc5c643..91a0aed 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2121,9 +2121,7 @@
     public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
             throws NameNotFoundException {
         final boolean restricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
-        if ((packageName.equals("system") || packageName.equals("android"))
-                && user.getIdentifier() == UserHandle.getUserId(
-                        mPackageInfo.getApplicationInfo().uid)) {
+        if (packageName.equals("system") || packageName.equals("android")) {
             return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
                     user, restricted, mDisplay, mOverrideConfiguration);
         }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 1083943..c831c25 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3386,8 +3386,16 @@
      */
     public static abstract class Style {
         private CharSequence mBigContentTitle;
-        private CharSequence mSummaryText = null;
-        private boolean mSummaryTextSet = false;
+
+        /**
+         * @hide
+         */
+        protected CharSequence mSummaryText = null;
+
+        /**
+         * @hide
+         */
+        protected boolean mSummaryTextSet = false;
 
         protected Builder mBuilder;
 
@@ -3679,6 +3687,11 @@
      * @see Notification#bigContentView
      */
     public static class BigTextStyle extends Style {
+
+        private static final int MAX_LINES = 13;
+        private static final int LINES_CONSUMED_BY_ACTIONS = 3;
+        private static final int LINES_CONSUMED_BY_SUMMARY = 2;
+
         private CharSequence mBigText;
 
         public BigTextStyle() {
@@ -3745,6 +3758,7 @@
 
             contentView.setTextViewText(R.id.big_text, mBuilder.processLegacyText(mBigText));
             contentView.setViewVisibility(R.id.big_text, View.VISIBLE);
+            contentView.setInt(R.id.big_text, "setMaxLines", calculateMaxLines());
             contentView.setViewVisibility(R.id.text2, View.GONE);
 
             applyTopPadding(contentView);
@@ -3756,6 +3770,24 @@
             return contentView;
         }
 
+        private int calculateMaxLines() {
+            int lineCount = MAX_LINES;
+            boolean hasActions = mBuilder.mActions.size() > 0;
+            boolean hasSummary = (mSummaryTextSet ? mSummaryText : mBuilder.mSubText) != null;
+            if (hasActions) {
+                lineCount -= LINES_CONSUMED_BY_ACTIONS;
+            }
+            if (hasSummary) {
+                lineCount -= LINES_CONSUMED_BY_SUMMARY;
+            }
+
+            // If we have less top padding at the top, we can fit less lines.
+            if (!mBuilder.mHasThreeLines) {
+                lineCount--;
+            }
+            return lineCount;
+        }
+
         /**
          * @hide
          */
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index f9370b3..d49bc50 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -278,21 +278,21 @@
 
 
     /**
-     * Adds a callback for changes to packages in current and managed profiles.
+     * Registers a callback for changes to packages in current and managed profiles.
      *
-     * @param callback The callback to add.
+     * @param callback The callback to register.
      */
-    public void addCallback(Callback callback) {
-        addCallback(callback, null);
+    public void registerCallback(Callback callback) {
+        registerCallback(callback, null);
     }
 
     /**
-     * Adds a callback for changes to packages in current and managed profiles.
+     * Registers a callback for changes to packages in current and managed profiles.
      *
-     * @param callback The callback to add.
+     * @param callback The callback to register.
      * @param handler that should be used to post callbacks on, may be null.
      */
-    public void addCallback(Callback callback, Handler handler) {
+    public void registerCallback(Callback callback, Handler handler) {
         synchronized (this) {
             if (callback != null && !mCallbacks.contains(callback)) {
                 boolean addedFirstCallback = mCallbacks.size() == 0;
@@ -308,12 +308,12 @@
     }
 
     /**
-     * Removes a callback that was previously added.
+     * Unregisters a callback that was previously registered.
      *
-     * @param callback The callback to remove.
-     * @see #addCallback(Callback)
+     * @param callback The callback to unregister.
+     * @see #registerCallback(Callback)
      */
-    public void removeCallback(Callback callback) {
+    public void unregisterCallback(Callback callback) {
         synchronized (this) {
             removeCallbackLocked(callback);
             if (mCallbacks.size() == 0) {
@@ -500,44 +500,12 @@
         }
     }
 
-    /** Remove after unbundled apps have migrated STOP SHIP */
-    public static abstract class OnAppsChangedCallback extends Callback {
+    /** STOPSHIP remove when launcher 3 has been updated */
+    public void addCallback(Callback callback) {
+        registerCallback(callback);
     }
-
-    /** Remove after unbundled apps have migrated STOP SHIP */
-    public void addOnAppsChangedCallback(OnAppsChangedCallback callback) {
-        addCallback(callback, null);
-    }
-
-    /** Remove after unbundled apps have migrated STOP SHIP */
-    public void addOnAppsChangedCallback(OnAppsChangedCallback callback, Handler handler) {
-        addCallback(callback, handler);
-    }
-
-    /** Remove after unbundled apps have migrated STOP SHIP */
-    public void removeOnAppsChangedCallback(OnAppsChangedCallback callback) {
-        removeCallback(callback);
-    }
-
-    /** Remove after unbundled apps have migrated STOP SHIP */
-    public void startActivityForProfile(ComponentName component, UserHandle user, Rect sourceBounds,
-            Bundle opts) {
-        startMainActivity(component, user, sourceBounds, opts);
-    }
-
-    /** Remove after unbundled apps have migrated STOP SHIP */
-    public void showAppDetailsForProfile(ComponentName component, UserHandle user,
-            Rect sourceBounds, Bundle opts) {
-        startAppDetailsActivity(component, user, sourceBounds, opts);
-    }
-
-    /** Remove after unbundled apps have migrated STOP SHIP */
-    public boolean isPackageEnabledForProfile(String packageName, UserHandle user) {
-        return isPackageEnabled(packageName, user);
-    }
-
-    /** Remove after unbundled apps have migrated STOP SHIP */
-    public boolean isActivityEnabledForProfile(ComponentName component, UserHandle user) {
-        return isActivityEnabled(component, user);
+    /** STOPSHIP remove when launcher 3 has been updated */
+    public void removeCallback(Callback callback) {
+        unregisterCallback(callback);
     }
 }
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 5fa1cc9..a5e86d8 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -167,8 +167,6 @@
          */
         public static final String FEATURES = "features";
 
-        /** Call had no associated features (e.g. voice-only). */
-        public static final int FEATURES_NONE = 0x0;
         /** Call had video. */
         public static final int FEATURES_VIDEO = 0x1;
 
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index 4de5f41..8aa2689 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -468,19 +468,6 @@
     }
 
     /**
-     * FIXME: Remove once the prebuilts are updated.
-     *
-     * @hide
-     */
-    @Deprecated
-    public Intent createIntentToEnroll() {
-        if (DBG) Slog.d(TAG, "createIntentToEnroll");
-        synchronized (mLock) {
-            return getManageIntentLocked(MANAGE_ACTION_ENROLL);
-        }
-    }
-
-    /**
      * Creates an intent to start the un-enrollment for the associated keyphrase.
      * This intent must be invoked using {@link Activity#startActivityForResult(Intent, int)}.
      * Starting re-enrollment is only valid if the keyphrase is already enrolled,
@@ -502,19 +489,6 @@
     }
 
     /**
-     * FIXME: Remove once the prebuilts are updated.
-     *
-     * @hide
-     */
-    @Deprecated
-    public Intent createIntentToUnEnroll() {
-        if (DBG) Slog.d(TAG, "createIntentToUnEnroll");
-        synchronized (mLock) {
-            return getManageIntentLocked(MANAGE_ACTION_UN_ENROLL);
-        }
-    }
-
-    /**
      * Creates an intent to start the re-enrollment for the associated keyphrase.
      * This intent must be invoked using {@link Activity#startActivityForResult(Intent, int)}.
      * Starting re-enrollment is only valid if the keyphrase is already enrolled,
@@ -535,19 +509,6 @@
         }
     }
 
-    /**
-     * FIXME: Remove once the prebuilts are updated.
-     *
-     * @hide
-     */
-    @Deprecated
-    public Intent createIntentToReEnroll() {
-        if (DBG) Slog.d(TAG, "createIntentToReEnroll");
-        synchronized (mLock) {
-            return getManageIntentLocked(MANAGE_ACTION_RE_ENROLL);
-        }
-    }
-
     private Intent getManageIntentLocked(int action) {
         if (mAvailability == STATE_INVALID) {
             throw new IllegalStateException("getManageIntent called on an invalid detector");
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index a10dda3..a283b91 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -19,7 +19,6 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -101,7 +100,7 @@
             IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
             long interrogatingTid, MagnificationSpec spec) {
         Message message = mHandler.obtainMessage();
-        message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID;
+        message.what = PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID;
         message.arg1 = flags;
 
         SomeArgs args = SomeArgs.obtain();
@@ -176,7 +175,7 @@
             IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
             long interrogatingTid, MagnificationSpec spec) {
         Message message = mHandler.obtainMessage();
-        message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID;
+        message.what = PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID;
         message.arg1 = flags;
         message.arg2 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
 
@@ -261,7 +260,7 @@
             IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
             long interrogatingTid, MagnificationSpec spec) {
         Message message = mHandler.obtainMessage();
-        message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT;
+        message.what = PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT;
         message.arg1 = flags;
 
         SomeArgs args = SomeArgs.obtain();
@@ -637,6 +636,95 @@
         }
     }
 
+    public void computeClickPointInScreenClientThread(long accessibilityNodeId,
+            Region interactiveRegion, int interactionId,
+            IAccessibilityInteractionConnectionCallback callback, int interrogatingPid,
+            long interrogatingTid, MagnificationSpec spec) {
+        Message message = mHandler.obtainMessage();
+        message.what = PrivateHandler.MSG_COMPUTE_CLICK_POINT_IN_SCREEN;
+
+        SomeArgs args = SomeArgs.obtain();
+        args.argi1 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
+        args.argi2 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId);
+        args.argi3 = interactionId;
+        args.arg1 = callback;
+        args.arg2 = spec;
+        args.arg3 = interactiveRegion;
+
+        message.obj = args;
+
+        // If the interrogation is performed by the same thread as the main UI
+        // thread in this process, set the message as a static reference so
+        // after this call completes the same thread but in the interrogating
+        // client can handle the message to generate the result.
+        if (interrogatingPid == mMyProcessId && interrogatingTid == mMyLooperThreadId) {
+            AccessibilityInteractionClient.getInstanceForThread(
+                    interrogatingTid).setSameThreadMessage(message);
+        } else {
+            mHandler.sendMessage(message);
+        }
+    }
+
+    private void computeClickPointInScreenUiThread(Message message) {
+        SomeArgs args = (SomeArgs) message.obj;
+        final int accessibilityViewId = args.argi1;
+        final int virtualDescendantId = args.argi2;
+        final int interactionId = args.argi3;
+        final IAccessibilityInteractionConnectionCallback callback =
+                (IAccessibilityInteractionConnectionCallback) args.arg1;
+        final MagnificationSpec spec = (MagnificationSpec) args.arg2;
+        final Region interactiveRegion = (Region) args.arg3;
+        args.recycle();
+
+        boolean succeeded = false;
+        Point point = mTempPoint;
+        try {
+            if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
+                return;
+            }
+            View target = null;
+            if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+                target = findViewByAccessibilityId(accessibilityViewId);
+            } else {
+                target = mViewRootImpl.mView;
+            }
+            if (target != null && isShown(target)) {
+                AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
+                if (provider != null) {
+                    // For virtual views just use the center of the bounds in screen.
+                    AccessibilityNodeInfo node = null;
+                    if (virtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+                        node = provider.createAccessibilityNodeInfo(virtualDescendantId);
+                    } else {
+                        node = provider.createAccessibilityNodeInfo(
+                                AccessibilityNodeProvider.HOST_VIEW_ID);
+                    }
+                    if (node != null) {
+                        succeeded = true;
+                        Rect boundsInScreen = mTempRect;
+                        node.getBoundsInScreen(boundsInScreen);
+                        point.set(boundsInScreen.centerX(), boundsInScreen.centerY());
+                    }
+                } else if (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+                    // For a real view, ask the view to compute the click point.
+                    succeeded = target.computeClickPointInScreenForAccessibility(
+                            interactiveRegion, point);
+                }
+            }
+        } finally {
+            try {
+                Point result = null;
+                if (succeeded) {
+                    applyAppScaleAndMagnificationSpecIfNeeded(point, spec);
+                    result = point;
+                }
+                callback.setComputeClickPointInScreenActionResult(result, interactionId);
+            } catch (RemoteException re) {
+                /* ignore - the other side will time out */
+            }
+        }
+    }
+
     private View findViewByAccessibilityId(int accessibilityId) {
         View root = mViewRootImpl.mView;
         if (root == null) {
@@ -688,6 +776,26 @@
         }
     }
 
+    private void applyAppScaleAndMagnificationSpecIfNeeded(Point point,
+            MagnificationSpec spec) {
+        final float applicationScale = mViewRootImpl.mAttachInfo.mApplicationScale;
+        if (!shouldApplyAppScaleAndMagnificationSpec(applicationScale, spec)) {
+            return;
+        }
+
+        if (applicationScale != 1.0f) {
+            point.x *= applicationScale;
+            point.y *= applicationScale;
+        }
+
+        if (spec != null) {
+            point.x *= spec.scale;
+            point.y *= spec.scale;
+            point.x += (int) spec.offsetX;
+            point.y += (int) spec.offsetY;
+        }
+    }
+
     private void applyAppScaleAndMagnificationSpecIfNeeded(AccessibilityNodeInfo info,
             MagnificationSpec spec) {
         if (info == null) {
@@ -1080,11 +1188,12 @@
 
     private class PrivateHandler extends Handler {
         private final static int MSG_PERFORM_ACCESSIBILITY_ACTION = 1;
-        private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID = 2;
-        private final static int MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID = 3;
-        private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT = 4;
+        private final static int MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID = 2;
+        private final static int MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID = 3;
+        private final static int MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT = 4;
         private final static int MSG_FIND_FOCUS = 5;
         private final static int MSG_FOCUS_SEARCH = 6;
+        private final static int MSG_COMPUTE_CLICK_POINT_IN_SCREEN = 7;
 
         public PrivateHandler(Looper looper) {
             super(looper);
@@ -1096,16 +1205,18 @@
             switch (type) {
                 case MSG_PERFORM_ACCESSIBILITY_ACTION:
                     return "MSG_PERFORM_ACCESSIBILITY_ACTION";
-                case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID:
-                    return "MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID";
-                case MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID:
-                    return "MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID";
-                case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT:
-                    return "MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT";
+                case MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID:
+                    return "MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID";
+                case MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID:
+                    return "MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID";
+                case MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT:
+                    return "MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT";
                 case MSG_FIND_FOCUS:
                     return "MSG_FIND_FOCUS";
                 case MSG_FOCUS_SEARCH:
                     return "MSG_FOCUS_SEARCH";
+                case MSG_COMPUTE_CLICK_POINT_IN_SCREEN:
+                    return "MSG_COMPUTE_CLICK_POINT_IN_SCREEN";
                 default:
                     throw new IllegalArgumentException("Unknown message type: " + type);
             }
@@ -1115,16 +1226,16 @@
         public void handleMessage(Message message) {
             final int type = message.what;
             switch (type) {
-                case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID: {
+                case MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID: {
                     findAccessibilityNodeInfoByAccessibilityIdUiThread(message);
                 } break;
                 case MSG_PERFORM_ACCESSIBILITY_ACTION: {
                     perfromAccessibilityActionUiThread(message);
                 } break;
-                case MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID: {
+                case MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID: {
                     findAccessibilityNodeInfosByViewIdUiThread(message);
                 } break;
-                case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT: {
+                case MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT: {
                     findAccessibilityNodeInfosByTextUiThread(message);
                 } break;
                 case MSG_FIND_FOCUS: {
@@ -1133,6 +1244,9 @@
                 case MSG_FOCUS_SEARCH: {
                     focusSearchUiThread(message);
                 } break;
+                case MSG_COMPUTE_CLICK_POINT_IN_SCREEN: {
+                    computeClickPointInScreenUiThread(message);
+                } break;
                 default:
                     throw new IllegalArgumentException("Unknown message type: " + type);
             }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 770e78c..82c5425 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -35,6 +35,8 @@
 import android.graphics.Matrix;
 import android.graphics.Outline;
 import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PathMeasure;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
 import android.graphics.PorterDuff;
@@ -5731,6 +5733,136 @@
     }
 
     /**
+     * Computes a point on which a sequence of a down/up event can be sent to
+     * trigger clicking this view. This method is for the exclusive use by the
+     * accessibility layer to determine where to send a click event in explore
+     * by touch mode.
+     *
+     * @param interactiveRegion The interactive portion of this window.
+     * @param outPoint The point to populate.
+     * @return True of such a point exists.
+     */
+    boolean computeClickPointInScreenForAccessibility(Region interactiveRegion,
+            Point outPoint) {
+        // Since the interactive portion of the view is a region but as a view
+        // may have a transformation matrix which cannot be applied to a
+        // region we compute the view bounds rectangle and all interactive
+        // predecessor's and sibling's (siblings of predecessors included)
+        // rectangles that intersect the view bounds. At the
+        // end if the view was partially covered by another interactive
+        // view we compute the view's interactive region and pick a point
+        // on its boundary path as regions do not offer APIs to get inner
+        // points. Note that the the code is optimized to fail early and
+        // avoid unnecessary allocations plus computations.
+
+        // The current approach has edge cases that may produce false
+        // positives or false negatives. For example, a portion of the
+        // view may be covered by an interactive descendant of a
+        // predecessor, which we do not compute. Also a view may be handling
+        // raw touch events instead registering click listeners, which
+        // we cannot compute. Despite these limitations this approach will
+        // work most of the time and it is a huge improvement over just
+        // blindly sending the down and up events in the center of the
+        // view.
+
+        // Cannot click on an unattached view.
+        if (mAttachInfo == null) {
+            return false;
+        }
+
+        // Attached to an invisible window means this view is not visible.
+        if (mAttachInfo.mWindowVisibility != View.VISIBLE) {
+            return false;
+        }
+
+        RectF bounds = mAttachInfo.mTmpTransformRect;
+        bounds.set(0, 0, getWidth(), getHeight());
+        List<RectF> intersections = mAttachInfo.mTmpRectList;
+        intersections.clear();
+
+        if (mParent instanceof ViewGroup) {
+            ViewGroup parentGroup = (ViewGroup) mParent;
+            if (!parentGroup.translateBoundsAndIntersectionsInWindowCoordinates(
+                    this, bounds, intersections)) {
+                intersections.clear();
+                return false;
+            }
+        }
+
+        // Take into account the window location.
+        final int dx = mAttachInfo.mWindowLeft;
+        final int dy = mAttachInfo.mWindowTop;
+        bounds.offset(dx, dy);
+        offsetRects(intersections, dx, dy);
+
+        if (intersections.isEmpty() && interactiveRegion == null) {
+            outPoint.set((int) bounds.centerX(), (int) bounds.centerY());
+        } else {
+            // This view is partially covered by other views, then compute
+            // the not covered region and pick a point on its boundary.
+            Region region = new Region();
+            region.set((int) bounds.left, (int) bounds.top,
+                    (int) bounds.right, (int) bounds.bottom);
+
+            final int intersectionCount = intersections.size();
+            for (int i = intersectionCount - 1; i >= 0; i--) {
+                RectF intersection = intersections.remove(i);
+                region.op((int) intersection.left, (int) intersection.top,
+                        (int) intersection.right, (int) intersection.bottom,
+                        Region.Op.DIFFERENCE);
+            }
+
+            // If the view is completely covered, done.
+            if (region.isEmpty()) {
+                return false;
+            }
+
+            // Take into account the interactive portion of the window
+            // as the rest is covered by other windows. If no such a region
+            // then the whole window is interactive.
+            if (interactiveRegion != null) {
+                region.op(interactiveRegion, Region.Op.INTERSECT);
+            }
+
+            // If the view is completely covered, done.
+            if (region.isEmpty()) {
+                return false;
+            }
+
+            // Try a shortcut here.
+            if (region.isRect()) {
+                Rect regionBounds = mAttachInfo.mTmpInvalRect;
+                region.getBounds(regionBounds);
+                outPoint.set(regionBounds.centerX(), regionBounds.centerY());
+                return true;
+            }
+
+            // Get the a point on the region boundary path.
+            Path path = region.getBoundaryPath();
+            PathMeasure pathMeasure = new PathMeasure(path, false);
+            final float[] coordinates = mAttachInfo.mTmpTransformLocation;
+
+            // Without loss of generality pick a point.
+            final float point = pathMeasure.getLength() * 0.01f;
+            if (!pathMeasure.getPosTan(point, coordinates, null)) {
+                return false;
+            }
+
+            outPoint.set(Math.round(coordinates[0]), Math.round(coordinates[1]));
+        }
+
+        return true;
+    }
+
+    static void offsetRects(List<RectF> rects, float offsetX, float offsetY) {
+        final int rectCount = rects.size();
+        for (int i = 0; i < rectCount; i++) {
+            RectF intersection = rects.get(i);
+            intersection.offset(offsetX, offsetY);
+        }
+    }
+
+    /**
      * Returns the delegate for implementing accessibility support via
      * composition. For more details see {@link AccessibilityDelegate}.
      *
@@ -20154,6 +20286,16 @@
         final RectF mTmpTransformRect = new RectF();
 
         /**
+         * Temporary for use in computing hit areas with transformed views
+         */
+        final RectF mTmpTransformRect1 = new RectF();
+
+        /**
+         * Temporary list of rectanges.
+         */
+        final List<RectF> mTmpRectList = new ArrayList<>();
+
+        /**
          * Temporary for use in transforming invalidation rect
          */
         final Matrix mTmpMatrix = new Matrix();
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index c1e66de..4e1db90 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -771,6 +771,112 @@
     }
 
     /**
+     * Translates the given bounds and intersections from child coordinates to
+     * local coordinates. In case any interactive sibling of the calling child
+     * covers the latter, a new intersections is added to the intersection list.
+     * This method is for the exclusive use by the accessibility layer to compute
+     * a point where a sequence of down and up events would click on a view.
+     *
+     * @param child The child making the call.
+     * @param bounds The bounds to translate in child coordinates.
+     * @param intersections The intersections of interactive views covering the child.
+     * @return True if the bounds and intersections were computed, false otherwise.
+     */
+    boolean translateBoundsAndIntersectionsInWindowCoordinates(View child,
+            RectF bounds, List<RectF> intersections) {
+        // Not attached, done.
+        if (mAttachInfo == null) {
+            return false;
+        }
+
+        if (getAlpha() <= 0 || getTransitionAlpha() <= 0 ||
+                getVisibility() != VISIBLE) {
+            // Cannot click on a view with an invisible predecessor.
+            return false;
+        }
+
+        // Compensate for the child transformation.
+        if (!child.hasIdentityMatrix()) {
+            Matrix matrix = child.getMatrix();
+            matrix.mapRect(bounds);
+            final int intersectionCount = intersections.size();
+            for (int i = 0; i < intersectionCount; i++) {
+                RectF intersection = intersections.get(i);
+                matrix.mapRect(intersection);
+            }
+        }
+
+        // Translate the bounds from child to parent coordinates.
+        final int dx = child.mLeft - mScrollX;
+        final int dy = child.mTop - mScrollY;
+        bounds.offset(dx, dy);
+        offsetRects(intersections, dx, dy);
+
+        // If the bounds do not intersect our bounds, done.
+        if (!bounds.intersects(0, 0, getWidth(), getHeight())) {
+            return false;
+        }
+
+        // Check whether any clickable siblings cover the child
+        // view and if so keep track of the intersections. Also
+        // respect Z ordering when iterating over children.
+        ArrayList<View> orderedList = buildOrderedChildList();
+        final boolean useCustomOrder = orderedList == null
+                && isChildrenDrawingOrderEnabled();
+
+        final int childCount = mChildrenCount;
+        for (int i = childCount - 1; i >= 0; i--) {
+            final int childIndex = useCustomOrder
+                    ? getChildDrawingOrder(childCount, i) : i;
+            final View sibling = (orderedList == null)
+                    ? mChildren[childIndex] : orderedList.get(childIndex);
+
+            // We care only about siblings over the child.
+            if (sibling == child) {
+                break;
+            }
+
+            // If sibling is not interactive we do not care.
+            if (!sibling.isClickable() && !sibling.isLongClickable()) {
+                continue;
+            }
+
+            // Compute the sibling bounds in its coordinates.
+            RectF siblingBounds = mAttachInfo.mTmpTransformRect1;
+            siblingBounds.set(0, 0, sibling.getWidth(), sibling.getHeight());
+
+            // Take into account the sibling transformation matrix.
+            if (!sibling.hasIdentityMatrix()) {
+                sibling.getMatrix().mapRect(siblingBounds);
+            }
+
+            // Offset the sibling to our coordinates.
+            final int siblingDx = sibling.mLeft - mScrollX;
+            final int siblingDy = sibling.mTop - mScrollY;
+            siblingBounds.offset(siblingDx, siblingDy);
+
+            // Compute the intersection between the child and the sibling.
+            if (siblingBounds.intersect(bounds)) {
+                // If an interactive sibling completely covers the child, done.
+                if (siblingBounds.equals(bounds)) {
+                    return false;
+                }
+                // Keep track of the intersection rectangle.
+                RectF intersection = new RectF(siblingBounds);
+                intersections.add(intersection);
+            }
+        }
+
+        if (mParent instanceof ViewGroup) {
+            ViewGroup parentGroup = (ViewGroup) mParent;
+            return parentGroup.translateBoundsAndIntersectionsInWindowCoordinates(
+                    this, bounds, intersections);
+        }
+
+        return true;
+    }
+
+    /**
      * Called when a child view has changed whether or not it is tracking transient state.
      */
     public void childHasTransientStateChanged(View child, boolean childHasTransientState) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 4299e2e..80b9ade 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -6679,12 +6679,12 @@
         public void performAccessibilityAction(long accessibilityNodeId, int action,
                 Bundle arguments, int interactionId,
                 IAccessibilityInteractionConnectionCallback callback, int flags,
-                int interogatingPid, long interrogatingTid) {
+                int interrogatingPid, long interrogatingTid) {
             ViewRootImpl viewRootImpl = mViewRootImpl.get();
             if (viewRootImpl != null && viewRootImpl.mView != null) {
                 viewRootImpl.getAccessibilityInteractionController()
                     .performAccessibilityActionClientThread(accessibilityNodeId, action, arguments,
-                            interactionId, callback, flags, interogatingPid, interrogatingTid);
+                            interactionId, callback, flags, interrogatingPid, interrogatingTid);
             } else {
                 // We cannot make the call and notify the caller so it does not wait.
                 try {
@@ -6696,6 +6696,26 @@
         }
 
         @Override
+        public void computeClickPointInScreen(long accessibilityNodeId, Region interactiveRegion,
+                int interactionId, IAccessibilityInteractionConnectionCallback callback,
+                int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
+            ViewRootImpl viewRootImpl = mViewRootImpl.get();
+            if (viewRootImpl != null && viewRootImpl.mView != null) {
+                viewRootImpl.getAccessibilityInteractionController()
+                        .computeClickPointInScreenClientThread(accessibilityNodeId,
+                                interactiveRegion, interactionId, callback, interrogatingPid,
+                                interrogatingTid, spec);
+            } else {
+                // We cannot make the call and notify the caller so it does not wait.
+                try {
+                    callback.setComputeClickPointInScreenActionResult(null, interactionId);
+                } catch (RemoteException re) {
+                    /* best effort - ignore */
+                }
+            }
+        }
+
+        @Override
         public void findAccessibilityNodeInfosByViewId(long accessibilityNodeId,
                 String viewId, Region interactiveRegion, int interactionId,
                 IAccessibilityInteractionConnectionCallback callback, int flags,
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index db78ec5..374f7e0 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -17,6 +17,7 @@
 package android.view.accessibility;
 
 import android.accessibilityservice.IAccessibilityServiceConnection;
+import android.graphics.Point;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -98,6 +99,8 @@
 
     private boolean mPerformAccessibilityActionResult;
 
+    private Point mComputeClickPointResult;
+
     private Message mSameThreadMessage;
 
     private static final SparseArray<IAccessibilityServiceConnection> sConnectionCache =
@@ -519,6 +522,43 @@
         return false;
     }
 
+    /**
+     * Computes a point in screen coordinates where sending a down/up events would
+     * perform a click on an {@link AccessibilityNodeInfo}.
+     *
+     * @param connectionId The id of a connection for interacting with the system.
+     * @param accessibilityWindowId A unique window id. Use
+     *     {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID}
+     *     to query the currently active window.
+     * @param accessibilityNodeId A unique view id or virtual descendant id from
+     *     where to start the search. Use
+     *     {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID}
+     *     to start from the root.
+     * @return Point the click point of null if no such point.
+     */
+    public Point computeClickPointInScreen(int connectionId, int accessibilityWindowId,
+            long accessibilityNodeId) {
+        try {
+            IAccessibilityServiceConnection connection = getConnection(connectionId);
+            if (connection != null) {
+                final int interactionId = mInteractionIdCounter.getAndIncrement();
+                final boolean success = connection.computeClickPointInScreen(
+                        accessibilityWindowId, accessibilityNodeId,
+                        interactionId, this, Thread.currentThread().getId());
+                if (success) {
+                    return getComputeClickPointInScreenResultAndClear(interactionId);
+                }
+            } else {
+                if (DEBUG) {
+                    Log.w(LOG_TAG, "No connection for connection id: " + connectionId);
+                }
+            }
+        } catch (RemoteException re) {
+            Log.w(LOG_TAG, "Error while calling remote computeClickPointInScreen", re);
+        }
+        return null;
+    }
+
     public void clearCache() {
         sAccessibilityCache.clear();
     }
@@ -634,6 +674,34 @@
     }
 
     /**
+     * Gets the result of a request to compute a point in screen for clicking on a node.
+     *
+     * @param interactionId The interaction id to match the result with the request.
+     * @return The point or null if no such point.
+     */
+    private Point getComputeClickPointInScreenResultAndClear(int interactionId) {
+        synchronized (mInstanceLock) {
+            final boolean success = waitForResultTimedLocked(interactionId);
+            Point result = success ? mComputeClickPointResult : null;
+            clearResultLocked();
+            return result;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setComputeClickPointInScreenActionResult(Point point, int interactionId) {
+        synchronized (mInstanceLock) {
+            if (interactionId > mInteractionId) {
+                mComputeClickPointResult = point;
+                mInteractionId = interactionId;
+            }
+            mInstanceLock.notifyAll();
+        }
+    }
+
+    /**
      * Clears the result state.
      */
     private void clearResultLocked() {
@@ -641,6 +709,7 @@
         mFindAccessibilityNodeInfoResult = null;
         mFindAccessibilityNodeInfosResult = null;
         mPerformAccessibilityActionResult = false;
+        mComputeClickPointResult = null;
     }
 
     /**
diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
index faf7789..66a3f46 100644
--- a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
@@ -17,6 +17,7 @@
 package android.view.accessibility;
 
 import android.graphics.Region;
+import android.graphics.Point;
 import android.os.Bundle;
 import android.view.MagnificationSpec;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -53,4 +54,8 @@
     void performAccessibilityAction(long accessibilityNodeId, int action, in Bundle arguments,
         int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
         int interrogatingPid, long interrogatingTid);
+
+    void computeClickPointInScreen(long accessibilityNodeId, in Region bounds, int interactionId,
+        IAccessibilityInteractionConnectionCallback callback, int interrogatingPid,
+        long interrogatingTid, in MagnificationSpec spec);
 }
diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl
index c1a3ab7..f480216 100644
--- a/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl
@@ -16,6 +16,7 @@
 
 package android.view.accessibility;
 
+import android.graphics.Point;
 import android.view.accessibility.AccessibilityNodeInfo;
 import java.util.List;
 
@@ -51,4 +52,12 @@
      * @param interactionId The interaction id to match the result with the request.
      */
     void setPerformAccessibilityActionResult(boolean succeeded, int interactionId);
+
+    /**
+     * Sets the result of a request to compute a point for clicking in a view.
+     *
+     * @param point The point of null if no such point.
+     * @param interactionId The interaction id to match the result with the request.
+     */
+    void setComputeClickPointInScreenActionResult(in Point point, int interactionId);
 }
diff --git a/core/res/res/layout/notification_template_material_inbox.xml b/core/res/res/layout/notification_template_material_inbox.xml
index 2382d18..8a66c3f 100644
--- a/core/res/res/layout/notification_template_material_inbox.xml
+++ b/core/res/res/layout/notification_template_material_inbox.xml
@@ -44,6 +44,7 @@
             android:layout_width="match_parent"
             android:layout_weight="1"
             android:layout_height="0dp"
+            android:layout_marginEnd="8dp"
             android:orientation="horizontal"
             >
             <TextView android:id="@+id/inbox_text0"
@@ -60,7 +61,6 @@
                 android:layout_height="@dimen/notification_badge_size"
                 android:layout_weight="0"
                 android:layout_marginStart="4dp"
-                android:layout_marginEnd="8dp"
                 android:scaleType="fitCenter"
                 android:visibility="gone"
                 />
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 082a158..2c805bb 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -1109,9 +1109,9 @@
      * {@link #requestLocationUpdates(String, long, float, LocationListener)}.
      *
      * <p>
-     * Before API version 20, this method would throw {@link SecurityException}
-     * if the location permissions were not sufficient to use the specified
-     * provider.
+     * Before API version {@link android.os.Build.VERSION_CODES#L}, this
+     * method would throw {@link SecurityException} if the location permissions
+     * were not sufficient to use the specified provider.
      *
      * @param provider the name of the provider
      * @return true if the provider exists and is enabled
@@ -1119,7 +1119,6 @@
      * @throws IllegalArgumentException if provider is null
      */
     public boolean isProviderEnabled(String provider) {
-        // STOPSHIP: finalize API version number in javadoc
         checkProvider(provider);
 
         try {
diff --git a/packages/SystemUI/res/layout/recents_empty.xml b/packages/SystemUI/res/layout/recents_empty.xml
index 1ef9cad..4b68e77 100644
--- a/packages/SystemUI/res/layout/recents_empty.xml
+++ b/packages/SystemUI/res/layout/recents_empty.xml
@@ -23,6 +23,6 @@
     android:textSize="16sp"
     android:textColor="#ffffffff"
     android:text="@string/recents_empty_message"
-    android:fontFamily="sans-serif-light"
+    android:fontFamily="sans-serif"
     android:background="#80000000"
     android:visibility="gone" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 0e18979..c0e2b10 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -134,10 +134,13 @@
     <integer name="recents_animate_task_exit_to_home_duration">225</integer>
     <!-- The min animation duration for animating the task bar out. -->
     <integer name="recents_animate_task_bar_exit_duration">125</integer>
+    <!-- The animation delay for animating the first task in. This should roughly be the animation
+     duration of the transition in to recents from home. -->
+    <integer name="recents_animate_task_enter_from_home_delay">150</integer>
     <!-- The min animation duration for animating the task in when transitioning from home. -->
     <integer name="recents_animate_task_enter_from_home_duration">275</integer>
     <!-- The animation stagger to apply to each task animation when transitioning from home. -->
-    <integer name="recents_animate_task_enter_from_home_delay">10</integer>
+    <integer name="recents_animate_task_enter_from_home_stagger_delay">10</integer>
     <!-- The short duration when animating in/out the lock to app button. -->
     <integer name="recents_animate_lock_to_app_button_short_duration">150</integer>
     <!-- The long duration when animating in/out the lock to app button. -->
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index 5d8181c..396be3b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -74,8 +74,9 @@
     public float taskStackOverscrollPct;
 
     /** Task view animation and styles */
-    public int taskViewEnterFromHomeDuration;
     public int taskViewEnterFromHomeDelay;
+    public int taskViewEnterFromHomeDuration;
+    public int taskViewEnterFromHomeStaggerDelay;
     public int taskViewExitToHomeDuration;
     public int taskViewRemoveAnimDuration;
     public int taskViewRemoveAnimTranslationXPx;
@@ -209,10 +210,12 @@
         taskStackTopPaddingPx = res.getDimensionPixelSize(R.dimen.recents_stack_top_padding);
 
         // Task view animation and styles
-        taskViewEnterFromHomeDuration =
-                res.getInteger(R.integer.recents_animate_task_enter_from_home_duration);
         taskViewEnterFromHomeDelay =
                 res.getInteger(R.integer.recents_animate_task_enter_from_home_delay);
+        taskViewEnterFromHomeDuration =
+                res.getInteger(R.integer.recents_animate_task_enter_from_home_duration);
+        taskViewEnterFromHomeStaggerDelay =
+                res.getInteger(R.integer.recents_animate_task_enter_from_home_stagger_delay);
         taskViewExitToHomeDuration =
                 res.getInteger(R.integer.recents_animate_task_exit_to_home_duration);
         taskViewRemoveAnimDuration =
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 49aa52b..6fe86be 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -284,7 +284,7 @@
                 float scaledWindowInsetTop = (int) (taskScale * windowInsetTop);
                 float scaledTranslationY = taskRect.top + transform.translationY -
                         (scaledWindowInsetTop + scaledYOffset);
-                startDelay = mConfig.taskViewEnterFromHomeDelay;
+                startDelay = mConfig.taskViewEnterFromHomeStaggerDelay;
 
                 // Animate the top clip
                 mViewBounds.animateClipTop(windowInsetTop, duration,
@@ -410,8 +410,8 @@
         } else if (mConfig.launchedFromHome) {
             // Animate the tasks up
             int frontIndex = (ctx.currentStackViewCount - ctx.currentStackViewIndex - 1);
-            int delay = mConfig.taskBarEnterAnimDelay +
-                    frontIndex * mConfig.taskViewEnterFromHomeDelay;
+            int delay = mConfig.taskViewEnterFromHomeDelay +
+                    frontIndex * mConfig.taskViewEnterFromHomeStaggerDelay;
             if (Constants.DebugFlags.App.EnableShadows) {
                 animate().translationZ(transform.translationZ);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 1c4556f..f4587db 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -91,6 +91,7 @@
 import com.android.systemui.statusbar.phone.KeyguardTouchDelegate;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.policy.HeadsUpNotificationView;
+import com.android.systemui.statusbar.policy.PreviewInflater;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
 import java.util.ArrayList;
@@ -260,10 +261,12 @@
             final boolean isActivity = pendingIntent.isActivity();
             if (isActivity) {
                 final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
+                final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
+                        mContext, pendingIntent.getIntent(), mCurrentUserId);
                 dismissKeyguardThenExecute(new OnDismissAction() {
                     @Override
                     public boolean onDismiss() {
-                        if (keyguardShowing) {
+                        if (keyguardShowing && !afterKeyguardGone) {
                             try {
                                 ActivityManagerNative.getDefault()
                                         .keyguardWaitingForActivityDrawn();
@@ -277,7 +280,7 @@
                         }
 
                         boolean handled = superOnClickHandler(view, pendingIntent, fillInIntent);
-                        overrideActivityPendingAppTransition(keyguardShowing);
+                        overrideActivityPendingAppTransition(keyguardShowing && !afterKeyguardGone);
 
                         // close the shade if it was open
                         if (handled) {
@@ -287,7 +290,7 @@
                         // Wait for activity start.
                         return handled;
                     }
-                }, false /* afterKeyguardGone */);
+                }, afterKeyguardGone);
                 return true;
             } else {
                 return super.onClickHandler(view, pendingIntent, fillInIntent);
@@ -1440,6 +1443,9 @@
 
         public void onClick(final View v) {
             final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
+            final boolean afterKeyguardGone = mIntent.isActivity()
+                    && PreviewInflater.wouldLaunchResolverActivity(mContext, mIntent.getIntent(),
+                            mCurrentUserId);
             dismissKeyguardThenExecute(new OnDismissAction() {
                 public boolean onDismiss() {
                     if (mIsHeadsUp) {
@@ -1448,7 +1454,7 @@
                     AsyncTask.execute(new Runnable() {
                         @Override
                         public void run() {
-                            if (keyguardShowing) {
+                            if (keyguardShowing && !afterKeyguardGone) {
                                 try {
                                     ActivityManagerNative.getDefault()
                                             .keyguardWaitingForActivityDrawn();
@@ -1472,7 +1478,8 @@
                                     // TODO: Dismiss Keyguard.
                                 }
                                 if (mIntent.isActivity()) {
-                                    overrideActivityPendingAppTransition(keyguardShowing);
+                                    overrideActivityPendingAppTransition(keyguardShowing
+                                            && !afterKeyguardGone);
                                 }
                             }
 
@@ -1490,7 +1497,7 @@
 
                     return mIntent != null && mIntent.isActivity();
                 }
-            }, false /* afterKeyguardGone */);
+            }, afterKeyguardGone);
         }
     }
 
@@ -1625,7 +1632,7 @@
                 }
             }
             boolean showOnKeyguard = shouldShowOnKeyguard(entry.notification);
-            if ((isLockscreenPublicMode() && !showOnKeyguard) ||
+            if ((isLockscreenPublicMode() && !mShowLockscreenNotifications) ||
                     (onKeyguard && (visibleNotifications >= maxKeyguardNotifications
                             || !showOnKeyguard))) {
                 entry.row.setVisibility(View.GONE);
@@ -1776,7 +1783,7 @@
                 oldEntry.notification.getNotification().tickerText);
 
         final boolean shouldInterrupt = shouldInterrupt(notification);
-        final boolean alertAgain = alertAgain(oldEntry);
+        final boolean alertAgain = alertAgain(oldEntry, n);
         boolean updateSuccessful = false;
         if (contentsUnchanged && bigContentsUnchanged && headsUpContentsUnchanged
                 && publicUnchanged) {
@@ -1940,10 +1947,9 @@
         }
     }
 
-    private boolean alertAgain(Entry entry) {
-        final StatusBarNotification sbn = entry.notification;
-        return entry == null || !entry.hasInterrupted()
-                || (sbn.getNotification().flags & Notification.FLAG_ONLY_ALERT_ONCE) == 0;
+    private boolean alertAgain(Entry oldEntry, Notification newNotification) {
+        return oldEntry == null || !oldEntry.hasInterrupted()
+                || (newNotification.flags & Notification.FLAG_ONLY_ALERT_ONCE) == 0;
     }
 
     protected boolean shouldInterrupt(StatusBarNotification sbn) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java
index 9dfbb27..23810f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java
@@ -24,5 +24,5 @@
  * Keyguard.
  */
 public interface ActivityStarter {
-    public void startActivity(Intent intent, boolean dismissShade, boolean afterKeyguardGone);
+    public void startActivity(Intent intent, boolean dismissShade);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index f9da30f..e84ca52 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -315,15 +315,15 @@
     public void launchCamera() {
         mFlashlightController.killFlashlight();
         Intent intent = getCameraIntent();
-        boolean wouldLaunchResolverActivity = mPreviewInflater.wouldLaunchResolverActivity(intent);
+        boolean wouldLaunchResolverActivity = PreviewInflater.wouldLaunchResolverActivity(
+                mContext, intent, mLockPatternUtils.getCurrentUser());
         if (intent == SECURE_CAMERA_INTENT && !wouldLaunchResolverActivity) {
             mContext.startActivityAsUser(intent, UserHandle.CURRENT);
         } else {
 
             // We need to delay starting the activity because ResolverActivity finishes itself if
             // launched behind lockscreen.
-            mActivityStarter.startActivity(intent, false /* dismissShade */,
-                    wouldLaunchResolverActivity /* afterKeyguardGone */);
+            mActivityStarter.startActivity(intent, false /* dismissShade */);
         }
     }
 
@@ -337,8 +337,7 @@
                 }
             });
         } else {
-            mActivityStarter.startActivity(PHONE_INTENT, false /* dismissShade */,
-                    mPreviewInflater.wouldLaunchResolverActivity(PHONE_INTENT));
+            mActivityStarter.startActivity(PHONE_INTENT, false /* dismissShade */);
         }
     }
 
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 8497d8a..128c687 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -149,6 +149,7 @@
 import com.android.systemui.statusbar.policy.LocationControllerImpl;
 import com.android.systemui.statusbar.policy.NetworkControllerImpl;
 import com.android.systemui.statusbar.policy.NextAlarmController;
+import com.android.systemui.statusbar.policy.PreviewInflater;
 import com.android.systemui.statusbar.policy.RotationLockControllerImpl;
 import com.android.systemui.statusbar.policy.SecurityControllerImpl;
 import com.android.systemui.statusbar.policy.UserInfoController;
@@ -2070,8 +2071,8 @@
     }
 
     @Override
-    public void startActivity(Intent intent, boolean dismissShade, boolean afterKeyguardGone) {
-        startActivityDismissingKeyguard(intent, false, dismissShade, afterKeyguardGone);
+    public void startActivity(Intent intent, boolean dismissShade) {
+        startActivityDismissingKeyguard(intent, false, dismissShade);
     }
 
     public ScrimController getScrimController() {
@@ -2960,9 +2961,11 @@
     }
 
     public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
-            final boolean dismissShade, final boolean afterKeyguardGone) {
+            final boolean dismissShade) {
         if (onlyProvisioned && !isDeviceProvisioned()) return;
 
+        final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
+                mContext, intent, mCurrentUserId);
         final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
         dismissKeyguardThenExecute(new OnDismissAction() {
             @Override
@@ -3311,8 +3314,7 @@
     }
 
     private void handleStartSettingsActivity(Intent intent, boolean onlyProvisioned) {
-        startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */,
-                false /* afterKeyguardGone */);
+        startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */);
     }
 
     private static class FastColorDrawable extends Drawable {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index eeb97e3..15a7229 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -497,20 +497,19 @@
         } else if (v == mAlarmStatus && mNextAlarm != null) {
             PendingIntent showIntent = mNextAlarm.getShowIntent();
             if (showIntent != null && showIntent.isActivity()) {
-                mActivityStarter.startActivity(showIntent.getIntent(), true /* dismissShade */,
-                        false /* afterKeyguardGone */);
+                mActivityStarter.startActivity(showIntent.getIntent(), true /* dismissShade */);
             }
         }
     }
 
     private void startSettingsActivity() {
         mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS),
-                true /* dismissShade */, false /* afterKeyguardGone */);
+                true /* dismissShade */);
     }
 
     private void startBatteryActivity() {
         mActivityStarter.startActivity(new Intent(Intent.ACTION_POWER_USAGE_SUMMARY),
-                true /* dismissShade */, false /* afterKeyguardGone */);
+                true /* dismissShade */);
     }
 
     public void setQSPanel(QSPanel qsp) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 4a6f1a8..f04d6a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -928,8 +928,8 @@
                     intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
             boolean wasConnected = mWifiConnected;
             mWifiConnected = networkInfo != null && networkInfo.isConnected();
-            // If we just connected, grab the inintial signal strength and ssid
-            if (mWifiConnected && !wasConnected) {
+            // If Connected grab the signal strength and ssid
+            if (mWifiConnected) {
                 // try getting it out of the intent first
                 WifiInfo info = (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
                 if (info == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
index cdbe494..030cd6d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
@@ -20,14 +20,12 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.content.pm.UserInfo;
 import android.os.UserHandle;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 
 import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.KeyguardActivityLauncher;
 import com.android.systemui.statusbar.phone.KeyguardPreviewContainer;
 
 import java.util.List;
@@ -107,20 +105,21 @@
         return info;
     }
 
-    public boolean wouldLaunchResolverActivity(Intent intent) {
-        PackageManager packageManager = mContext.getPackageManager();
+    public static boolean wouldLaunchResolverActivity(Context ctx, Intent intent,
+            int currentUserId) {
+        PackageManager packageManager = ctx.getPackageManager();
         final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
-                intent, PackageManager.MATCH_DEFAULT_ONLY, mLockPatternUtils.getCurrentUser());
+                intent, PackageManager.MATCH_DEFAULT_ONLY, currentUserId);
         if (appList.size() == 0) {
             return false;
         }
         ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
-                PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
-                mLockPatternUtils.getCurrentUser());
+                PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA, currentUserId);
         return wouldLaunchResolverActivity(resolved, appList);
     }
 
-    private boolean wouldLaunchResolverActivity(ResolveInfo resolved, List<ResolveInfo> appList) {
+    private static boolean wouldLaunchResolverActivity(
+            ResolveInfo resolved, List<ResolveInfo> appList) {
         // If the list contains the above resolved activity, then it can't be
         // ResolverActivity itself.
         for (int i = 0; i < appList.size(); i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
index acb4827..0586a83 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
@@ -140,8 +140,7 @@
         @Override
         public void run() {
             getComponent(PhoneStatusBar.class).startActivityDismissingKeyguard(
-                    ZenModePanel.ZEN_SETTINGS, true /* onlyProvisioned */, true /* dismissShade */,
-                    false /* afterKeyguardGone */);
+                    ZenModePanel.ZEN_SETTINGS, true /* onlyProvisioned */, true /* dismissShade */);
             mPanel.postDismiss(mDismissDelay);
         }
     };
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index a43a2a6..ebe21ff 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -746,14 +746,16 @@
     }
 
     /**
-     * Gets the bounds of the accessibility focus in the active window.
+     * Gets a point within the accessibility focused node where we can send down
+     * and up events to perform a click.
      *
-     * @param outBounds The output to which to write the focus bounds.
-     * @return Whether accessibility focus was found and the bounds are populated.
+     * @param outPoint The click point to populate.
+     * @return Whether accessibility a click point was found and set.
      */
     // TODO: (multi-display) Make sure this works for multiple displays.
-    boolean getAccessibilityFocusBounds(Rect outBounds) {
-        return getInteractionBridgeLocked().getAccessibilityFocusBoundsNotLocked(outBounds);
+    boolean getAccessibilityFocusClickPointInScreen(Point outPoint) {
+        return getInteractionBridgeLocked()
+                .getAccessibilityFocusClickPointInScreenNotLocked(outPoint);
     }
 
     /**
@@ -2196,8 +2198,8 @@
             MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             try {
                 connection.findAccessibilityNodeInfosByViewId(accessibilityNodeId, viewIdResName,
-                        partialInteractiveRegion, interactionId, callback, mFetchFlags, interrogatingPid,
-                        interrogatingTid, spec);
+                        partialInteractiveRegion, interactionId, callback, mFetchFlags,
+                        interrogatingPid, interrogatingTid, spec);
                 return true;
             } catch (RemoteException re) {
                 if (DEBUG) {
@@ -2248,8 +2250,8 @@
             MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             try {
                 connection.findAccessibilityNodeInfosByText(accessibilityNodeId, text,
-                        partialInteractiveRegion, interactionId, callback, mFetchFlags, interrogatingPid,
-                        interrogatingTid, spec);
+                        partialInteractiveRegion, interactionId, callback, mFetchFlags,
+                        interrogatingPid, interrogatingTid, spec);
                 return true;
             } catch (RemoteException re) {
                 if (DEBUG) {
@@ -2352,8 +2354,9 @@
             final long identityToken = Binder.clearCallingIdentity();
             MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             try {
-                connection.findFocus(accessibilityNodeId, focusType, partialInteractiveRegion, interactionId,
-                        callback, mFetchFlags, interrogatingPid, interrogatingTid, spec);
+                connection.findFocus(accessibilityNodeId, focusType, partialInteractiveRegion,
+                        interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid,
+                        spec);
                 return true;
             } catch (RemoteException re) {
                 if (DEBUG) {
@@ -2403,8 +2406,9 @@
             final long identityToken = Binder.clearCallingIdentity();
             MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             try {
-                connection.focusSearch(accessibilityNodeId, direction, partialInteractiveRegion, interactionId,
-                        callback, mFetchFlags, interrogatingPid, interrogatingTid, spec);
+                connection.focusSearch(accessibilityNodeId, direction, partialInteractiveRegion,
+                        interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid,
+                        spec);
                 return true;
             } catch (RemoteException re) {
                 if (DEBUG) {
@@ -2460,6 +2464,7 @@
             return true;
         }
 
+        @Override
         public boolean performGlobalAction(int action) {
             synchronized (mLock) {
                 // We treat calls from a profile as if made by its parent as profiles
@@ -2501,6 +2506,57 @@
         }
 
         @Override
+        public  boolean computeClickPointInScreen(int accessibilityWindowId,
+                long accessibilityNodeId, int interactionId,
+                IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
+                throws RemoteException {
+            final int resolvedWindowId;
+            IAccessibilityInteractionConnection connection = null;
+            Region partialInteractiveRegion = mTempRegion;
+            synchronized (mLock) {
+                // We treat calls from a profile as if made by its parent as profiles
+                // share the accessibility state of the parent. The call below
+                // performs the current profile parent resolution.
+                final int resolvedUserId = mSecurityPolicy
+                        .resolveCallingUserIdEnforcingPermissionsLocked(
+                                UserHandle.getCallingUserId());
+                if (resolvedUserId != mCurrentUserId) {
+                    return false;
+                }
+                resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
+                final boolean permissionGranted =
+                        mSecurityPolicy.canRetrieveWindowContentLocked(this);
+                if (!permissionGranted) {
+                    return false;
+                } else {
+                    connection = getConnectionLocked(resolvedWindowId);
+                    if (connection == null) {
+                        return false;
+                    }
+                }
+                if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
+                        resolvedWindowId, partialInteractiveRegion)) {
+                    partialInteractiveRegion = null;
+                }
+            }
+            final int interrogatingPid = Binder.getCallingPid();
+            final long identityToken = Binder.clearCallingIdentity();
+            MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
+            try {
+                connection.computeClickPointInScreen(accessibilityNodeId, partialInteractiveRegion,
+                        interactionId, callback, interrogatingPid, interrogatingTid, spec);
+                return true;
+            } catch (RemoteException re) {
+                if (DEBUG) {
+                    Slog.e(LOG_TAG, "Error computeClickPointInScreen().");
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identityToken);
+            }
+            return false;
+        }
+
+        @Override
         public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
             mSecurityPolicy.enforceCallingPermission(Manifest.permission.DUMP, FUNCTION_DUMP);
             synchronized (mLock) {
@@ -3119,30 +3175,43 @@
             }
         }
 
-        public boolean getAccessibilityFocusBoundsNotLocked(Rect outBounds) {
+        public boolean getAccessibilityFocusClickPointInScreenNotLocked(Point outPoint) {
             AccessibilityNodeInfo focus = getAccessibilityFocusNotLocked();
             if (focus == null) {
                 return false;
             }
 
             synchronized (mLock) {
-                focus.getBoundsInScreen(outBounds);
+                Point point = mClient.computeClickPointInScreen(mConnectionId,
+                        focus.getWindowId(), focus.getSourceNodeId());
+
+                if (point == null) {
+                    return false;
+                }
 
                 MagnificationSpec spec = getCompatibleMagnificationSpecLocked(focus.getWindowId());
                 if (spec != null && !spec.isNop()) {
-                    outBounds.offset((int) -spec.offsetX, (int) -spec.offsetY);
-                    outBounds.scale(1 / spec.scale);
+                    point.offset((int) -spec.offsetX, (int) -spec.offsetY);
+                    point.x = (int) (point.x * (1 / spec.scale));
+                    point.y = (int) (point.y * (1 / spec.scale));
                 }
 
-                // Clip to the window rectangle.
+                // Make sure the point is within the window.
                 Rect windowBounds = mTempRect;
                 getActiveWindowBounds(windowBounds);
-                outBounds.intersect(windowBounds);
+                if (!windowBounds.contains(point.x, point.y)) {
+                    return false;
+                }
 
-                // Clip to the screen rectangle.
-                mDefaultDisplay.getRealSize(mTempPoint);
-                outBounds.intersect(0, 0, mTempPoint.x, mTempPoint.y);
+                // Make sure the point is within the screen.
+                Point screenSize = mTempPoint;
+                mDefaultDisplay.getRealSize(screenSize);
+                if (point.x < 0 || point.x > screenSize.x
+                        || point.y < 0 || point.y > screenSize.y) {
+                    return false;
+                }
 
+                outPoint.set(point.x, point.y);
                 return true;
             }
         }
diff --git a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
index ac0ca0a..9e63433 100644
--- a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
@@ -24,6 +24,7 @@
 import android.gesture.GestureStore;
 import android.gesture.GestureStroke;
 import android.gesture.Prediction;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Handler;
 import android.os.SystemClock;
@@ -171,6 +172,9 @@
     // Temporary rectangle to avoid instantiation.
     private final Rect mTempRect = new Rect();
 
+    // Temporary point to avoid instantiation.
+    private final Point mTempPoint = new Point();
+
     // Context in which this explorer operates.
     private final Context mContext;
 
@@ -1157,18 +1161,18 @@
                 mInjectedPointerTracker.getLastInjectedHoverEventForClick();
             if (lastExploreEvent == null) {
                 // No last touch explored event but there is accessibility focus in
-                // the active window. We click in the middle of the focus bounds.
-                Rect focusBounds = mTempRect;
-                if (mAms.getAccessibilityFocusBounds(focusBounds)) {
-                    clickLocationX = focusBounds.centerX();
-                    clickLocationY = focusBounds.centerY();
+                // the active window. We click in the focus bounds.
+                Point point = mTempPoint;
+                if (mAms.getAccessibilityFocusClickPointInScreen(point)) {
+                    clickLocationX = point.x;
+                    clickLocationY = point.y;
                 } else {
                     // Out of luck - do nothing.
                     return;
                 }
             } else {
                 // If the click is within the active window but not within the
-                // accessibility focus bounds we click in the focus center.
+                // accessibility focus bounds we click in the focus bounds.
                 final int lastExplorePointerIndex = lastExploreEvent.getActionIndex();
                 clickLocationX = (int) lastExploreEvent.getX(lastExplorePointerIndex);
                 clickLocationY = (int) lastExploreEvent.getY(lastExplorePointerIndex);
@@ -1176,12 +1180,10 @@
                 if (mLastTouchedWindowId == mAms.getActiveWindowId()) {
                     mAms.getActiveWindowBounds(activeWindowBounds);
                     if (activeWindowBounds.contains(clickLocationX, clickLocationY)) {
-                        Rect focusBounds = mTempRect;
-                        if (mAms.getAccessibilityFocusBounds(focusBounds)) {
-                            if (!focusBounds.contains(clickLocationX, clickLocationY)) {
-                                clickLocationX = focusBounds.centerX();
-                                clickLocationY = focusBounds.centerY();
-                            }
+                        Point point = mTempPoint;
+                        if (mAms.getAccessibilityFocusClickPointInScreen(point)) {
+                            clickLocationX = point.x;
+                            clickLocationY = point.y;
                         }
                     }
                 }
@@ -1330,18 +1332,18 @@
                 mInjectedPointerTracker.getLastInjectedHoverEventForClick();
             if (lastExploreEvent == null) {
                 // No last touch explored event but there is accessibility focus in
-                // the active window. We click in the middle of the focus bounds.
-                Rect focusBounds = mTempRect;
-                if (mAms.getAccessibilityFocusBounds(focusBounds)) {
-                    clickLocationX = focusBounds.centerX();
-                    clickLocationY = focusBounds.centerY();
+                // the active window. We click in the focus bounds.
+                Point point = mTempPoint;
+                if (mAms.getAccessibilityFocusClickPointInScreen(point)) {
+                    clickLocationX = point.x;
+                    clickLocationY = point.y;
                 } else {
                     // Out of luck - do nothing.
                     return;
                 }
             } else {
                 // If the click is within the active window but not within the
-                // accessibility focus bounds we click in the focus center.
+                // accessibility focus bounds we click in the focus bounds.
                 final int lastExplorePointerIndex = lastExploreEvent.getActionIndex();
                 clickLocationX = (int) lastExploreEvent.getX(lastExplorePointerIndex);
                 clickLocationY = (int) lastExploreEvent.getY(lastExplorePointerIndex);
@@ -1349,12 +1351,10 @@
                 if (mLastTouchedWindowId == mAms.getActiveWindowId()) {
                     mAms.getActiveWindowBounds(activeWindowBounds);
                     if (activeWindowBounds.contains(clickLocationX, clickLocationY)) {
-                        Rect focusBounds = mTempRect;
-                        if (mAms.getAccessibilityFocusBounds(focusBounds)) {
-                            if (!focusBounds.contains(clickLocationX, clickLocationY)) {
-                                clickLocationX = focusBounds.centerX();
-                                clickLocationY = focusBounds.centerY();
-                            }
+                        Point point = mTempPoint;
+                        if (mAms.getAccessibilityFocusClickPointInScreen(point)) {
+                            clickLocationX = point.x;
+                            clickLocationY = point.y;
                         }
                     }
                 }
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 6168546..bcf3b17 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -425,13 +425,13 @@
     }
 
     final ActivityRecord topActivity() {
-        // Iterate to find the first non-empty task stack. Note that this code can
-        // be simplified once we stop storing tasks with empty mActivities lists.
         for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
             ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
-            final int topActivityNdx = activities.size() - 1;
-            if (topActivityNdx >= 0) {
-                return activities.get(topActivityNdx);
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ActivityRecord r = activities.get(activityNdx);
+                if (!r.finishing) {
+                    return r;
+                }
             }
         }
         return null;
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index f821daf..b8261a4 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1772,7 +1772,7 @@
                 if (intentActivity != null) {
                     if (isLockTaskModeViolation(intentActivity.task)) {
                         showLockTaskToast();
-                        Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
+                        Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
                         return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
                     }
                     if (r.task == null) {
@@ -2783,9 +2783,8 @@
         }
 
         // A non-top activity is reporting a visibility change.
-        if ((visible && (top.fullscreen || top.state != ActivityState.RESUMED)) ||
-                top.app == null || top.app.thread == null) {
-            // Can't carry out this request.
+        if (visible && top.fullscreen) {
+            // Let the caller know that it can't be seen.
             if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: returning top.fullscreen="
                     + top.fullscreen + " top.state=" + top.state + " top.app=" + top.app +
                     " top.app.thread=" + top.app.thread);
@@ -2807,9 +2806,12 @@
                 mService.convertFromTranslucent(next.appToken);
             }
         }
-        try {
-            top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible);
-        } catch (RemoteException e) {
+        if (top.app != null && top.app.thread != null) {
+            // Notify the top app of the change.
+            try {
+                top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible);
+            } catch (RemoteException e) {
+            }
         }
         return true;
     }
diff --git a/services/core/java/com/android/server/notification/DowntimeConditionProvider.java b/services/core/java/com/android/server/notification/DowntimeConditionProvider.java
index 317ebef..b71bad8 100644
--- a/services/core/java/com/android/server/notification/DowntimeConditionProvider.java
+++ b/services/core/java/com/android/server/notification/DowntimeConditionProvider.java
@@ -43,6 +43,7 @@
 import java.util.Date;
 import java.util.Locale;
 import java.util.Objects;
+import java.util.TimeZone;
 
 /** Built-in zen condition provider for managing downtime */
 public class DowntimeConditionProvider extends ConditionProviderService {
@@ -275,6 +276,9 @@
                 final long schTime = intent.getLongExtra(EXTRA_TIME, 0);
                 if (DEBUG) Slog.d(TAG, String.format("%s scheduled for %s, fired at %s, delta=%s",
                         action, ts(schTime), ts(now), now - schTime));
+            } else if (Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
+                if (DEBUG) Slog.d(TAG, "timezone changed to " + TimeZone.getDefault());
+                mCalendar.setTimeZone(TimeZone.getDefault());
             } else {
                 if (DEBUG) Slog.d(TAG, action + " fired at " + now);
             }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 54f043d..a56f783 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2648,6 +2648,11 @@
             if (speedBumpIndex == -1 &&
                     // Intrusiveness trumps priority, hence ignore intrusives.
                     !record.isRecentlyIntrusive() &&
+                    // Currently, package priority is either PRIORITY_DEFAULT or PRIORITY_MAX, so
+                    // scanning for PRIORITY_MIN within the package bucket PRIORITY_DEFAULT
+                    // (or lower as a safeguard) is sufficient to find the speedbump index.
+                    // We'll have to revisit this when more package priority buckets are introduced.
+                    record.getPackagePriority() <= Notification.PRIORITY_DEFAULT &&
                     record.sbn.getNotification().priority == Notification.PRIORITY_MIN) {
                 speedBumpIndex = keys.size() - 1;
             }
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 168328f..5639dad 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -18,7 +18,6 @@
 
 import static android.media.AudioAttributes.USAGE_ALARM;
 import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
-import static android.media.AudioAttributes.USAGE_UNKNOWN;
 
 import android.app.AppOpsManager;
 import android.app.Notification;
@@ -225,11 +224,6 @@
                 muteCalls ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
                 exceptionPackages);
 
-        // restrict vibrations with no hints
-        mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, USAGE_UNKNOWN,
-                zen ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
-                exceptionPackages);
-
         // alarm restrictions
         final boolean muteAlarms = mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
         mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, USAGE_ALARM,
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index ac2a176..21f200f 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -341,6 +341,12 @@
 
     /**
      * @hide
+     * last time we connected, this configuration had no internet access
+     */
+    public boolean noInternetAccess;
+
+    /**
+     * @hide
      * Uid of app creating the configuration
      */
     @SystemApi
@@ -673,6 +679,49 @@
     @SystemApi
     public int numAssociation;
 
+    /**
+     * @hide
+     * Number of time user disabled WiFi while associated to this configuration with Low RSSI.
+     */
+    public int numUserTriggeredWifiDisableLowRSSI;
+
+    /**
+     * @hide
+     * Number of time user disabled WiFi while associated to this configuration with Bad RSSI.
+     */
+    public int numUserTriggeredWifiDisableBadRSSI;
+
+    /**
+     * @hide
+     * Number of time user disabled WiFi while associated to this configuration
+     * and RSSI was not HIGH.
+     */
+    public int numUserTriggeredWifiDisableNotHighRSSI;
+
+    /**
+     * @hide
+     * Number of ticks associated to this configuration with Low RSSI.
+     */
+    public int numTicksAtLowRSSI;
+
+    /**
+     * @hide
+     * Number of ticks associated to this configuration with Bad RSSI.
+     */
+    public int numTicksAtBadRSSI;
+
+    /**
+     * @hide
+     * Number of ticks associated to this configuration
+     * and RSSI was not HIGH.
+     */
+    public int numTicksAtNotHighRSSI;
+    /**
+     * @hide
+     * Number of time user (WifiManager) triggered association to this configuration.
+     * TODO: count this only for Wifi Settings uuid, so as to not count 3rd party apps
+     */
+    public int numUserTriggeredJoinAttempts;
 
     /**
      * @hide
@@ -725,6 +774,7 @@
         selfAdded = false;
         didSelfAdd = false;
         ephemeral = false;
+        noInternetAccess = false;
         mIpConfiguration = new IpConfiguration();
     }
 
@@ -824,8 +874,10 @@
             sbuf.append(" autoJoinStatus ").append(this.numConnectionFailures).append("\n");
         }
         if (this.didSelfAdd || this.selfAdded) {
-            if (this.didSelfAdd) sbuf.append(" didSelfAdd ");
-            if (this.selfAdded) sbuf.append(" selfAdded ");
+            if (this.didSelfAdd) sbuf.append(" didSelfAdd");
+            if (this.selfAdded) sbuf.append(" selfAdded");
+            if (this.noInternetAccess) sbuf.append(" noInternetAccess");
+
             sbuf.append("\n");
         }
         sbuf.append(" KeyMgmt:");
@@ -896,18 +948,44 @@
 
         sbuf.append(mIpConfiguration.toString());
 
-        if (selfAdded)  sbuf.append("selfAdded");
-        if (creatorUid != 0)  sbuf.append("uid=" + Integer.toString(creatorUid));
+        if (this.creatorUid != 0)  sbuf.append("uid=" + Integer.toString(creatorUid));
 
-        if (blackListTimestamp != 0) {
+        if (this.blackListTimestamp != 0) {
             long now_ms = System.currentTimeMillis();
-            long diff = now_ms - blackListTimestamp;
+            long diff = now_ms - this.blackListTimestamp;
             if (diff <= 0) {
                 sbuf.append("blackListed since <incorrect>");
             } else {
                 sbuf.append("blackListed since ").append(Long.toString(diff/1000)).append( "sec");
             }
         }
+        sbuf.append('\n');
+        if (this.linkedConfigurations != null) {
+            for(String key : this.linkedConfigurations.keySet()) {
+                sbuf.append(" linked: ").append(key);
+                sbuf.append('\n');
+            }
+        }
+        if (this.connectChoices != null) {
+            for(String key : this.connectChoices.keySet()) {
+                Integer choice = this.connectChoices.get(key);
+                if (choice != null) {
+                    sbuf.append(" choice: ").append(key);
+                    sbuf.append(" = ").append(choice);
+                    sbuf.append('\n');
+                }
+            }
+        }
+        sbuf.append(" triggeredLow: ").append(numUserTriggeredWifiDisableLowRSSI);
+        sbuf.append(" triggeredBad: ").append(numUserTriggeredWifiDisableBadRSSI);
+        sbuf.append(" triggeredNotHigh: ").append(numUserTriggeredWifiDisableNotHighRSSI);
+        sbuf.append('\n');
+        sbuf.append(" ticksLow: ").append(numTicksAtLowRSSI);
+        sbuf.append(" ticksBad: ").append(numTicksAtBadRSSI);
+        sbuf.append(" ticksNotHigh: ").append(numTicksAtNotHighRSSI);
+        sbuf.append('\n');
+        sbuf.append(" triggeredJoin: ").append(numUserTriggeredJoinAttempts);
+        sbuf.append('\n');
 
         return sbuf.toString();
     }
@@ -1197,7 +1275,7 @@
             mCachedConfigKey = null; //force null configKey
             autoJoinStatus = source.autoJoinStatus;
             selfAdded = source.selfAdded;
-
+            noInternetAccess = source.noInternetAccess;
             if (source.visibility != null) {
                 visibility = new Visibility(source.visibility);
             }
@@ -1217,6 +1295,13 @@
             numScorerOverride = source.numScorerOverride;
             numScorerOverrideAndSwitchedNetwork = source.numScorerOverrideAndSwitchedNetwork;
             numAssociation = source.numAssociation;
+            numUserTriggeredWifiDisableLowRSSI = source.numUserTriggeredWifiDisableLowRSSI;
+            numUserTriggeredWifiDisableBadRSSI = source.numUserTriggeredWifiDisableBadRSSI;
+            numUserTriggeredWifiDisableNotHighRSSI = source.numUserTriggeredWifiDisableNotHighRSSI;
+            numTicksAtLowRSSI = source.numTicksAtLowRSSI;
+            numTicksAtBadRSSI = source.numTicksAtBadRSSI;
+            numTicksAtNotHighRSSI = source.numTicksAtNotHighRSSI;
+            numUserTriggeredJoinAttempts = source.numUserTriggeredJoinAttempts;
         }
     }
 
@@ -1259,6 +1344,7 @@
         dest.writeInt(autoJoinStatus);
         dest.writeInt(selfAdded ? 1 : 0);
         dest.writeInt(didSelfAdd ? 1 : 0);
+        dest.writeInt(noInternetAccess ? 1 : 0);
         dest.writeInt(creatorUid);
         dest.writeInt(lastConnectUid);
         dest.writeInt(lastUpdateUid);
@@ -1269,6 +1355,14 @@
         dest.writeInt(numScorerOverride);
         dest.writeInt(numScorerOverrideAndSwitchedNetwork);
         dest.writeInt(numAssociation);
+        dest.writeInt(numUserTriggeredWifiDisableLowRSSI);
+        dest.writeInt(numUserTriggeredWifiDisableBadRSSI);
+        dest.writeInt(numUserTriggeredWifiDisableNotHighRSSI);
+        dest.writeInt(numTicksAtLowRSSI);
+        dest.writeInt(numTicksAtBadRSSI);
+        dest.writeInt(numTicksAtNotHighRSSI);
+        dest.writeInt(numUserTriggeredJoinAttempts);
+
     }
 
     /** Implement the Parcelable interface {@hide} */
@@ -1307,6 +1401,7 @@
                 config.autoJoinStatus = in.readInt();
                 config.selfAdded = in.readInt() != 0;
                 config.didSelfAdd = in.readInt() != 0;
+                config.noInternetAccess = in.readInt() != 0;
                 config.creatorUid = in.readInt();
                 config.lastConnectUid = in.readInt();
                 config.lastUpdateUid = in.readInt();
@@ -1317,6 +1412,13 @@
                 config.numScorerOverride = in.readInt();
                 config.numScorerOverrideAndSwitchedNetwork = in.readInt();
                 config.numAssociation = in.readInt();
+                config.numUserTriggeredWifiDisableLowRSSI = in.readInt();
+                config.numUserTriggeredWifiDisableBadRSSI = in.readInt();
+                config.numUserTriggeredWifiDisableNotHighRSSI = in.readInt();
+                config.numTicksAtLowRSSI = in.readInt();
+                config.numTicksAtBadRSSI = in.readInt();
+                config.numTicksAtNotHighRSSI = in.readInt();
+                config.numUserTriggeredJoinAttempts = in.readInt();
                 return config;
             }