Merge "Fixed another case where the systemUI could crashloop" into nyc-dev
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index a028449..716997f 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -41,6 +41,7 @@
 import android.view.textservice.SpellCheckerInfo;
 import android.view.textservice.TextServicesManager;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.ArrayList;
@@ -83,6 +84,17 @@
         Locale.UK, // "en_GB"
     };
 
+    // A temporary workaround for the performance concerns in
+    // #getImplicitlyApplicableSubtypesLocked(Resources, InputMethodInfo).
+    // TODO: Optimize all the critical paths including this one.
+    private static final Object sCacheLock = new Object();
+    @GuardedBy("sCacheLock")
+    private static LocaleList sCachedSystemLocales;
+    @GuardedBy("sCacheLock")
+    private static InputMethodInfo sCachedInputMethodInfo;
+    @GuardedBy("sCacheLock")
+    private static ArrayList<InputMethodSubtype> sCachedResult;
+
     private InputMethodUtils() {
         // This utility class is not publicly instantiable.
     }
@@ -498,6 +510,32 @@
     @VisibleForTesting
     public static ArrayList<InputMethodSubtype> getImplicitlyApplicableSubtypesLocked(
             Resources res, InputMethodInfo imi) {
+        final LocaleList systemLocales = res.getConfiguration().getLocales();
+
+        synchronized (sCacheLock) {
+            // We intentionally do not use InputMethodInfo#equals(InputMethodInfo) here because
+            // it does not check if subtypes are also identical.
+            if (systemLocales.equals(sCachedSystemLocales) && sCachedInputMethodInfo == imi) {
+                return new ArrayList<>(sCachedResult);
+            }
+        }
+
+        // Note: Only resource info in "res" is used in getImplicitlyApplicableSubtypesLockedImpl().
+        // TODO: Refactor getImplicitlyApplicableSubtypesLockedImpl() so that it can receive
+        // LocaleList rather than Resource.
+        final ArrayList<InputMethodSubtype> result =
+                getImplicitlyApplicableSubtypesLockedImpl(res, imi);
+        synchronized (sCacheLock) {
+            // Both LocaleList and InputMethodInfo are immutable. No need to copy them here.
+            sCachedSystemLocales = systemLocales;
+            sCachedInputMethodInfo = imi;
+            sCachedResult = new ArrayList<>(result);
+        }
+        return result;
+    }
+
+    private static ArrayList<InputMethodSubtype> getImplicitlyApplicableSubtypesLockedImpl(
+            Resources res, InputMethodInfo imi) {
         final List<InputMethodSubtype> subtypes = InputMethodUtils.getSubtypes(imi);
         final LocaleList systemLocales = res.getConfiguration().getLocales();
         final String systemLocale = systemLocales.get(0).toString();
diff --git a/docs/html/preview/api-overview.jd b/docs/html/preview/api-overview.jd
index 4abd956..f2bc111 100644
--- a/docs/html/preview/api-overview.jd
+++ b/docs/html/preview/api-overview.jd
@@ -37,6 +37,7 @@
         <li><a href="#apk_signature_v2">APK Signature Scheme v2</a></li>
         <li><a href="#scoped_directory_access">Scoped Directory Access</a></li>
         <li><a href="#keyboard_shortcuts_helper">Keyboard Shortcuts Helper</a></li>
+        <li><a href="#custom_pointer_api">Custom Pointer API</a></li>
         <li><a href="#sustained_performance_api">Sustained Performance API</a></li>
         <li><a href="#vr">VR Support</a></li>
         <li><a href="#print_svc">Print Service Enhancements</a></li>
@@ -865,6 +866,26 @@
   {@code Activity.requestKeyboardShortcutsHelper()} for the relevant activity.
 </p>
 
+<h2 id="custom_pointer_api">
+  Custom Pointer API
+</h2>
+
+<p>
+  Android N introduces the Custom Pointer API, which lets you customize the
+  appearance, visibility, and behavior of the pointer. This capability is
+  especially useful when a user is using a mouse or touchpad to interact with
+  UI objects. The default pointer uses a standard icon. This API also includes
+  advanced functionality such as changing the pointer icon's appearance based
+  on specific mouse or touchpad movements.
+</p>
+
+<p>
+  To set a pointer icon, override the <code>onResolvePointerIcon()</code>
+  method of the <code>View</code> class. This method uses a
+  <code>PointerIcon</code> object to draw the icon that corresponds to a
+  specific motion event.
+</p>
+
 <h2 id="sustained_performance_api">Sustained Performance API</h2>
 
 <p>
diff --git a/docs/html/preview/behavior-changes.jd b/docs/html/preview/behavior-changes.jd
index 66dce7a..ece6b43 100644
--- a/docs/html/preview/behavior-changes.jd
+++ b/docs/html/preview/behavior-changes.jd
@@ -612,5 +612,15 @@
 {@link android.content.pm.PackageInstaller#uninstall PackageInstaller.uninstall()}.
 </li>
 
+  <li>The JCA provider called <em>Crypto</em> is deprecated, because its only
+  algorithm, SHA1PRNG, is cryptographically weak. Apps can no longer use
+  SHA1PRNG to (insecurely) derive keys, because this provider is no longer
+  available. For more information, see the blog
+  post <a href=
+  "http://android-developers.blogspot.com/2016/06/security-crypto-provider-deprecated-in.html"
+  class="external-link">Security "Crypto" provider deprecated in Android
+  N</a>.
+  </li>
+
 </ul>
 
diff --git a/docs/html/topic/libraries/support-library/revisions.jd b/docs/html/topic/libraries/support-library/revisions.jd
index 7525760..88b0ca1 100644
--- a/docs/html/topic/libraries/support-library/revisions.jd
+++ b/docs/html/topic/libraries/support-library/revisions.jd
@@ -6,6 +6,124 @@
 <p>This page provides details about the Support Library package releases.</p>
 
 <div class="toggle-content opened">
+  <p id="rev24-0-0">
+    <a href="#" onclick="return toggleContent(this)"><img src=
+    "{@docRoot}assets/images/styles/disclosure_up.png" class=
+    "toggle-content-img" alt="">Android Support Library, revision 24.0.0</a>
+    <em>(June 2016)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+    <dl>
+      <dt>
+        Changes for <a href=
+        "{@docRoot}tools/support-library/features.html#v4">v4 Support
+        Library</a>:
+      </dt>
+
+      <dd>
+          <ul>
+            <li>Added <code>Fragment.commitNow()</code>
+            for synchronous commit
+            </li>
+
+            <li>Added <code>NotificationCompat.MessagingStyle</code>
+            for multi-party conversations
+            </li>
+
+            <li>Added <code>NotificationManagerCompat.areNotificationsEnabled()</code>
+            and <code>getImportance()</code>
+            </li>
+
+            <li>{@link android.support.v4.media.session.MediaSessionCompat}
+            now mirrors the functionality of {@link
+            android.media.session.MediaSession} and no longer calls {@link
+            android.media.session.MediaSession#setMediaButtonReceiver
+            setMediaButtonReceiver()} automatically
+            </li>
+          </ul>
+          <p class="note">
+            <strong>Note:</strong> <a href=
+            "{@docRoot}reference/android/support/v4/media/MediaBrowserServiceCompat.html"
+            ><code>MediaBrowserServiceCompat</code></a> is compatible with
+            devices running API Level 24 as of Support Library revision 24.0.0.
+            Older versions of <a href=
+            "{@docRoot}reference/android/support/v4/media/MediaBrowserServiceCompat.html"
+            ><code>MediaBrowserServiceCompat</code></a>
+            are <em>not</em> compatible with API Level 24. If your app uses
+            <a href=
+            "{@docRoot}reference/android/support/v4/media/MediaBrowserServiceCompat.html"
+            ><code>MediaBrowserServiceCompat</code></a> and
+            supports devices running API level 24, you must update to Support
+            Library version 24.0.0 or later.
+          </p>
+
+      <dt>
+        Changes for <a href=
+        "{@docRoot}tools/support-library/features.html#v7-appcompat">v7
+        appcompat library</a>:
+      </dt>
+
+      <dd>
+        <ul>
+          <li>Added support for referencing themed {@link
+            android.content.res.ColorStateList} objects from XML
+          </li>
+        </ul>
+      </dd>
+
+      <dt>
+        Changes for <a href=
+        "{@docRoot}tools/support-library/features.html#design">Design Support
+        Library</a>:
+      </dt>
+
+      <dd>
+        <ul>
+          <li>Improvements to {@link android.support.design.widget.AppBarLayout}
+            handling of elevation using {@link
+            android.animation.StateListAnimator}
+          </li>
+        </ul>
+      </dd>
+
+      <dt>
+        Changes for <a href=
+        "{@docRoot}topic/libraries/support-library/features.html#v17-leanback"
+        >v17 Leanback library</a>:
+      </dt>
+
+      <dd>
+        <ul>
+          <li>Added <code>OnboardingFragment</code> to provide first-run welcome
+            and setup flow
+          </li>
+        </ul>
+      </dd>
+
+      <dt>
+        Changes for <a href=
+        "{@docRoot}topic/libraries/support-library/features.html#custom-tabs"
+        >custom tabs</a>:
+      </dt>
+
+      <dd>
+        <ul>
+          <li>Added support for providing a {@link android.widget.RemoteViews}
+            hierarchy for the secondary toolbar</li>
+          <li>Added <code>CustomTabsClient.connectAndInitialize()</code>
+            for one-line warm up</li>
+        </ul>
+      </dd>
+
+    </dl>
+  </div>
+</div>
+
+<!-- end of collapsible section: 24.0.0 -->
+
+
+<div class="toggle-content closed">
   <p id="rev23-4-0">
     <a href="#" onclick="return toggleContent(this)"><img src=
     "{@docRoot}assets/images/styles/disclosure_up.png" class=
@@ -45,10 +163,9 @@
 
       <dd>
         <ul>
-          <li>Added <!-- TODO: Link to method -->
-             <code><a href=
-            "{@docRoot}reference/android/support/v7/app/AppCompatDelegate.html">
-            AppCompatDelegate</a>.setCompatVectorFromResourcesEnabled()</code>
+          <li>Added
+            {@link android.support.v7.app.AppCompatDelegate#setCompatVectorFromResourcesEnabled
+            AppCompatDelegate.setCompatVectorFromResourcesEnabled()}
             method to re-enable usage of vector drawables in {@link
             android.graphics.drawable.DrawableContainer} objects on devices
             running Android 4.4 (API level 19) and lower. See <a href=
@@ -118,8 +235,9 @@
 
       <dd>
         <ul>
-          <li>Fixed a bug where <!-- TODO: Javadoc link -->
-             <code>VectorDrawableCompat</code> does not render correctly in
+          <li>Fixed a bug where {@link
+            android.support.graphics.drawable.VectorDrawableCompat} does
+            not render correctly in
             {@link android.widget.TextView} on API level 23. (<a class=
             "external-link" href=
             "https://code.google.com/p/android/issues/detail?id=206227">Issue
diff --git a/packages/PrintRecommendationService/AndroidManifest.xml b/packages/PrintRecommendationService/AndroidManifest.xml
index 0eb218c..c6736d7 100644
--- a/packages/PrintRecommendationService/AndroidManifest.xml
+++ b/packages/PrintRecommendationService/AndroidManifest.xml
@@ -17,7 +17,12 @@
  */
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.printservice.recommendation">
+    package="com.android.printservice.recommendation"
+    android:versionCode="1"
+    android:versionName="1.0.0">
+
+    <uses-sdk android:minSdkVersion="24"
+        android:targetSdkVersion="24" />
 
     <uses-permission android:name="android.permission.INTERNET" />
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
index e071f6a..284827b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
@@ -28,13 +28,10 @@
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.SparseArray;
-import android.view.View;
 import android.widget.TextView;
 
 import com.android.settingslib.R;
 
-import java.util.Objects;
-
 public class AccessPointPreference extends Preference {
 
     private static final int[] STATE_SECURED = {
@@ -111,7 +108,6 @@
             mTitleView.setCompoundDrawablePadding(mBadgePadding);
         }
         view.itemView.setContentDescription(mContentDescription);
-        view.itemView.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
     }
 
     protected void updateIcon(int level, Context context) {
@@ -152,7 +148,6 @@
      * Updates the title and summary; may indirectly call notifyChanged().
      */
     public void refresh() {
-        boolean updated = false;
         if (mForSavedNetworks) {
             setTitle(mAccessPoint.getConfigName());
         } else {
@@ -164,28 +159,21 @@
         if (level != mLevel) {
             mLevel = level;
             updateIcon(mLevel, context);
-            updated = true;
+            notifyChanged();
         }
         updateBadge(context);
 
         setSummary(mForSavedNetworks ? mAccessPoint.getSavedNetworkSummary()
                 : mAccessPoint.getSettingsSummary());
 
-        CharSequence contentDescription = getTitle();
+        mContentDescription = getTitle();
         if (getSummary() != null) {
-            contentDescription = TextUtils.concat(contentDescription, ",", getSummary());
+            mContentDescription = TextUtils.concat(mContentDescription, ",", getSummary());
         }
         if (level >= 0 && level < WIFI_CONNECTION_STRENGTH.length) {
-            contentDescription = TextUtils.concat(contentDescription, ",",
+            mContentDescription = TextUtils.concat(mContentDescription, ",",
                     getContext().getString(WIFI_CONNECTION_STRENGTH[level]));
         }
-        if (!Objects.equals(contentDescription, mContentDescription)) {
-            mContentDescription = contentDescription;
-            updated = true;
-        }
-        if (updated) {
-            notifyChanged();
-        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
index 9fb8bd5..2c5c437 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
@@ -34,6 +34,7 @@
 import android.util.Property;
 import android.util.TypedValue;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.ViewParent;
 import android.view.ViewStub;
 
@@ -285,6 +286,26 @@
     }
 
     /**
+     * Returns whether this view, or one of its descendants have accessibility focus.
+     */
+    public static boolean isDescendentAccessibilityFocused(View v) {
+        if (v.isAccessibilityFocused()) {
+            return true;
+        }
+
+        if (v instanceof ViewGroup) {
+            ViewGroup vg = (ViewGroup) v;
+            int childCount = vg.getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                if (isDescendentAccessibilityFocused(vg.getChildAt(i))) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
      * Returns the application configuration, which is independent of the activity's current
      * configuration in multiwindow.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 231360e..586a8bc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -44,6 +44,7 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.FrameLayout;
+import android.widget.ScrollView;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
@@ -170,7 +171,7 @@
     @ViewDebug.ExportedProperty(category="recents")
     private boolean mEnterAnimationComplete = false;
     @ViewDebug.ExportedProperty(category="recents")
-    private boolean mTouchExplorationEnabled;
+    boolean mTouchExplorationEnabled;
     @ViewDebug.ExportedProperty(category="recents")
     boolean mScreenPinningEnabled;
 
@@ -579,7 +580,7 @@
             if (task.isFreeformTask() || (transform != null && transform.visible)) {
                 mTmpTaskViewMap.put(task.key, tv);
             } else {
-                if (mTouchExplorationEnabled) {
+                if (mTouchExplorationEnabled && Utilities.isDescendentAccessibilityFocused(tv)) {
                     lastFocusedTaskIndex = taskIndex;
                     resetFocusedTask(task);
                 }
@@ -630,12 +631,14 @@
 
         // Update the focus if the previous focused task was returned to the view pool
         if (lastFocusedTaskIndex != -1) {
-            if (lastFocusedTaskIndex < visibleTaskRange[1]) {
-                setFocusedTask(visibleTaskRange[1], false /* scrollToTask */,
-                        true /* requestViewFocus */);
-            } else {
-                setFocusedTask(visibleTaskRange[0], false /* scrollToTask */,
-                        true /* requestViewFocus */);
+            int newFocusedTaskIndex = (lastFocusedTaskIndex < visibleTaskRange[1])
+                    ? visibleTaskRange[1]
+                    : visibleTaskRange[0];
+            setFocusedTask(newFocusedTaskIndex, false /* scrollToTask */,
+                    true /* requestViewFocus */);
+            TaskView focusedTaskView = getChildViewForTask(mFocusedTask);
+            if (focusedTaskView != null) {
+                focusedTaskView.requestAccessibilityFocus();
             }
         }
     }
@@ -938,24 +941,7 @@
      *                            focus.
      */
     public void setRelativeFocusedTask(boolean forward, boolean stackTasksOnly, boolean animated) {
-        setRelativeFocusedTask(forward, stackTasksOnly, animated, false);
-    }
-
-    /**
-     * Sets the focused task relative to the currently focused task.
-     *
-     * @param forward whether to go to the next task in the stack (along the curve) or the previous
-     * @param stackTasksOnly if set, will ensure that the traversal only goes along stack tasks, and
-     *                       if the currently focused task is not a stack task, will set the focus
-     *                       to the first visible stack task
-     * @param animated determines whether to actually draw the highlight along with the change in
-     *                            focus.
-     * @param cancelWindowAnimations if set, will attempt to cancel window animations if a scroll
-     *                               happens.
-     */
-    public void setRelativeFocusedTask(boolean forward, boolean stackTasksOnly, boolean animated,
-                                       boolean cancelWindowAnimations) {
-        setRelativeFocusedTask(forward, stackTasksOnly, animated, cancelWindowAnimations, 0);
+        setRelativeFocusedTask(forward, stackTasksOnly, animated, false, 0);
     }
 
     /**
@@ -972,13 +958,13 @@
      * @param timerIndicatorDuration the duration to initialize the auto-advance timer indicator
      */
     public void setRelativeFocusedTask(boolean forward, boolean stackTasksOnly, boolean animated,
-                                       boolean cancelWindowAnimations,
-                                       int timerIndicatorDuration) {
-        int newIndex = mStack.indexOfStackTask(mFocusedTask);
-        if (mFocusedTask != null) {
+                                       boolean cancelWindowAnimations, int timerIndicatorDuration) {
+        Task focusedTask = getFocusedTask();
+        int newIndex = mStack.indexOfStackTask(focusedTask);
+        if (focusedTask != null) {
             if (stackTasksOnly) {
                 List<Task> tasks =  mStack.getStackTasks();
-                if (mFocusedTask.isFreeformTask()) {
+                if (focusedTask.isFreeformTask()) {
                     // Try and focus the front most stack task
                     TaskView tv = getFrontMostTaskView(stackTasksOnly);
                     if (tv != null) {
@@ -1054,6 +1040,25 @@
         return mFocusedTask;
     }
 
+    /**
+     * Returns the accessibility focused task.
+     */
+    Task getAccessibilityFocusedTask() {
+        List<TaskView> taskViews = getTaskViews();
+        int taskViewCount = taskViews.size();
+        for (int i = 0; i < taskViewCount; i++) {
+            TaskView tv = taskViews.get(i);
+            if (Utilities.isDescendentAccessibilityFocused(tv)) {
+                return tv.getTask();
+            }
+        }
+        TaskView frontTv = getFrontMostTaskView(true /* stackTasksOnly */);
+        if (frontTv != null) {
+            return frontTv.getTask();
+        }
+        return null;
+    }
+
     @Override
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
@@ -1078,21 +1083,23 @@
         super.onInitializeAccessibilityNodeInfo(info);
         List<TaskView> taskViews = getTaskViews();
         int taskViewCount = taskViews.size();
-        if (taskViewCount > 1 && mFocusedTask != null) {
+        if (taskViewCount > 1) {
+            // Find the accessibility focused task
+            Task focusedTask = getAccessibilityFocusedTask();
             info.setScrollable(true);
-            int focusedTaskIndex = mStack.indexOfStackTask(mFocusedTask);
+            int focusedTaskIndex = mStack.indexOfStackTask(focusedTask);
             if (focusedTaskIndex > 0) {
-                info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
-            }
-            if (focusedTaskIndex < mStack.getTaskCount() - 1) {
                 info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
             }
+            if (0 <= focusedTaskIndex && focusedTaskIndex < mStack.getTaskCount() - 1) {
+                info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+            }
         }
     }
 
     @Override
     public CharSequence getAccessibilityClassName() {
-        return TaskStackView.class.getName();
+        return ScrollView.class.getName();
     }
 
     @Override
@@ -1100,14 +1107,20 @@
         if (super.performAccessibilityAction(action, arguments)) {
             return true;
         }
-        switch (action) {
-            case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
-                setRelativeFocusedTask(true, false /* stackTasksOnly */, false /* animated */);
-                return true;
-            }
-            case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
-                setRelativeFocusedTask(false, false /* stackTasksOnly */, false /* animated */);
-                return true;
+        Task focusedTask = getAccessibilityFocusedTask();
+        int taskIndex = mStack.indexOfStackTask(focusedTask);
+        if (0 <= taskIndex && taskIndex < mStack.getTaskCount()) {
+            switch (action) {
+                case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
+                    setFocusedTask(taskIndex + 1, true /* scrollToTask */, true /* requestViewFocus */,
+                            0);
+                    return true;
+                }
+                case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
+                    setFocusedTask(taskIndex - 1, true /* scrollToTask */, true /* requestViewFocus */,
+                            0);
+                    return true;
+                }
             }
         }
         return false;
@@ -1489,6 +1502,7 @@
         unbindTaskView(tv, task);
 
         // Reset the view properties and view state
+        tv.clearAccessibilityFocus();
         tv.resetViewProperties();
         tv.setFocusedState(false, false /* requestViewFocus */);
         tv.setClipViewInStack(false);
@@ -1949,6 +1963,10 @@
                         RecentsActivityLaunchState launchState = config.getLaunchState();
                         setFocusedTask(mStack.indexOfStackTask(mFocusedTask),
                                 false /* scrollToTask */, launchState.launchedWithAltTab);
+                        TaskView focusedTaskView = getChildViewForTask(mFocusedTask);
+                        if (mTouchExplorationEnabled && focusedTaskView != null) {
+                            focusedTaskView.requestAccessibilityFocus();
+                        }
                     }
 
                     EventBus.getDefault().send(new EnterRecentsTaskStackAnimationCompletedEvent());
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index b554a46..67a2595 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -343,7 +343,9 @@
                     }
 
                     // Reset the focused task after the user has scrolled
-                    mSv.resetFocusedTask(mSv.getFocusedTask());
+                    if (!mSv.mTouchExplorationEnabled) {
+                        mSv.resetFocusedTask(mSv.getFocusedTask());
+                    }
                 } else if (mActiveTaskView == null) {
                     // This tap didn't start on a task.
                     maybeHideRecentsFromBackgroundTap((int) ev.getX(), (int) ev.getY());
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 612c41d..4ecdd77 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -133,8 +133,6 @@
     @ViewDebug.ExportedProperty(deepExport=true, prefix="task_")
     private Task mTask;
     @ViewDebug.ExportedProperty(category="recents")
-    private boolean mTaskDataLoaded;
-    @ViewDebug.ExportedProperty(category="recents")
     private boolean mClipViewInStack = true;
     @ViewDebug.ExportedProperty(category="recents")
     private boolean mTouchExplorationEnabled;
@@ -451,16 +449,12 @@
      * Explicitly sets the focused state of this task.
      */
     public void setFocusedState(boolean isFocused, boolean requestViewFocus) {
-        SystemServicesProxy ssp = Recents.getSystemServices();
         if (isFocused) {
             if (requestViewFocus && !isFocused()) {
                 requestFocus();
             }
-            if (requestViewFocus && !isAccessibilityFocused() && ssp.isTouchExplorationEnabled()) {
-                requestAccessibilityFocus();
-            }
         } else {
-            if (isAccessibilityFocused() && ssp.isTouchExplorationEnabled()) {
+            if (isAccessibilityFocused() && mTouchExplorationEnabled) {
                 clearAccessibilityFocus();
             }
         }
@@ -622,7 +616,6 @@
         // Update each of the views to the new task data
         mThumbnailView.onTaskDataLoaded(thumbnailInfo);
         mHeaderView.onTaskDataLoaded();
-        mTaskDataLoaded = true;
     }
 
     @Override
@@ -631,7 +624,6 @@
         mTask.removeCallback(this);
         mThumbnailView.unbindFromTask();
         mHeaderView.unbindFromTask(mTouchExplorationEnabled);
-        mTaskDataLoaded = false;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index c6992aa..1973e05 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -977,6 +977,7 @@
             final int density = newConfig.densityDpi;
             if (density != mDensity) {
                 mDialog.dismiss();
+                mZenFooter.cleanup();
                 initDialog();
             }
             updateWindowWidthH();
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
index 65975d9..f01e95f 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
@@ -79,18 +79,11 @@
         mZen = controller.getZen();
         mConfig = controller.getConfig();
         mController = controller;
+        mController.addCallback(mZenCallback);
         update();
     }
 
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        mController.addCallback(mZenCallback);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
+    public void cleanup() {
         mController.removeCallback(mZenCallback);
     }
 
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 8ad6e6a..400c4a7 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -3073,9 +3073,14 @@
                 fs.numWakeup++;
                 if (alarm.workSource != null && alarm.workSource.size() > 0) {
                     for (int wi=0; wi<alarm.workSource.size(); wi++) {
+                        final String wsName = alarm.workSource.getName(wi);
+                        if (wsName == null) {
+                            Slog.w(TAG, "Null worksource name for alarm " + alarm);
+                        }
                         ActivityManagerNative.noteWakeupAlarm(
                                 alarm.operation, alarm.workSource.get(wi),
-                                alarm.workSource.getName(wi), alarm.statsTag);
+                                (wsName != null) ? wsName : alarm.packageName,
+                                alarm.statsTag);
                     }
                 } else {
                     ActivityManagerNative.noteWakeupAlarm(
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index df85cfa..d83a750 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -2581,14 +2581,11 @@
     }
 
     private void insertTaskAtTop(TaskRecord task, ActivityRecord newActivity) {
-        boolean isLastTaskOverHome = false;
         // If the moving task is over home stack, transfer its return type to next task
         if (task.isOverHomeStack()) {
             final TaskRecord nextTask = getNextTask(task);
             if (nextTask != null) {
                 nextTask.setTaskToReturnTo(task.getTaskToReturnTo());
-            } else {
-                isLastTaskOverHome = true;
             }
         }
 
@@ -2598,10 +2595,7 @@
             ActivityStack lastStack = mStackSupervisor.getLastStack();
             final boolean fromHome = lastStack.isHomeStack();
             if (!isHomeStack() && (fromHome || topTask() != task)) {
-                // If it's a last task over home - we default to keep its return to type not to
-                // make underlying task focused when this one will be finished.
-                int returnToType = isLastTaskOverHome
-                        ? task.getTaskToReturnTo() : APPLICATION_ACTIVITY_TYPE;
+                int returnToType = APPLICATION_ACTIVITY_TYPE;
                 if (fromHome && StackId.allowTopTaskToReturnHome(mStackId)) {
                     returnToType = lastStack.topTask() == null
                             ? HOME_ACTIVITY_TYPE : lastStack.topTask().taskType;