Merge "Associate rotation watchers with displays"
diff --git a/api/current.txt b/api/current.txt
index 7e1dec3..2dbc4e4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -34646,6 +34646,7 @@
     field public static final java.lang.String ACTION_NFCSHARING_SETTINGS = "android.settings.NFCSHARING_SETTINGS";
     field public static final java.lang.String ACTION_NFC_PAYMENT_SETTINGS = "android.settings.NFC_PAYMENT_SETTINGS";
     field public static final java.lang.String ACTION_NFC_SETTINGS = "android.settings.NFC_SETTINGS";
+    field public static final java.lang.String ACTION_NIGHT_DISPLAY_SETTINGS = "android.settings.NIGHT_DISPLAY_SETTINGS";
     field public static final java.lang.String ACTION_NOTIFICATION_LISTENER_SETTINGS = "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS";
     field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS = "android.settings.NOTIFICATION_POLICY_ACCESS_SETTINGS";
     field public static final java.lang.String ACTION_PRINT_SETTINGS = "android.settings.ACTION_PRINT_SETTINGS";
@@ -47497,15 +47498,16 @@
   }
 
   public final class AutofillManager {
+    method public void cancel();
+    method public void commit();
+    method public void notifyValueChanged(android.view.View);
+    method public void notifyViewEntered(android.view.View);
+    method public void notifyViewExited(android.view.View);
+    method public void notifyVirtualValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
+    method public void notifyVirtualViewEntered(android.view.View, int, android.graphics.Rect);
+    method public void notifyVirtualViewExited(android.view.View, int);
     method public void registerCallback(android.view.autofill.AutofillManager.AutofillCallback);
-    method public void reset();
-    method public void startAutofillRequest(android.view.View);
-    method public void startAutofillRequestOnVirtualView(android.view.View, int, android.graphics.Rect);
-    method public void stopAutofillRequest(android.view.View);
-    method public void stopAutofillRequestOnVirtualView(android.view.View, int);
     method public void unregisterCallback(android.view.autofill.AutofillManager.AutofillCallback);
-    method public void valueChanged(android.view.View);
-    method public void virtualValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
     field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
     field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
   }
diff --git a/api/system-current.txt b/api/system-current.txt
index bb2678c..094cb1d 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -27720,7 +27720,6 @@
     method public boolean clearScores() throws java.lang.SecurityException;
     method public void disableScoring() throws java.lang.SecurityException;
     method public java.lang.String getActiveScorerPackage();
-    method public android.net.RecommendationResult requestRecommendation(android.net.RecommendationRequest) throws java.lang.SecurityException;
     method public boolean setActiveScorer(java.lang.String) throws java.lang.SecurityException;
     method public boolean updateScores(android.net.ScoredNetwork[]) throws java.lang.SecurityException;
     field public static final java.lang.String ACTION_CHANGE_ACTIVE = "android.net.scoring.CHANGE_ACTIVE";
@@ -37655,6 +37654,7 @@
     field public static final java.lang.String ACTION_NFCSHARING_SETTINGS = "android.settings.NFCSHARING_SETTINGS";
     field public static final java.lang.String ACTION_NFC_PAYMENT_SETTINGS = "android.settings.NFC_PAYMENT_SETTINGS";
     field public static final java.lang.String ACTION_NFC_SETTINGS = "android.settings.NFC_SETTINGS";
+    field public static final java.lang.String ACTION_NIGHT_DISPLAY_SETTINGS = "android.settings.NIGHT_DISPLAY_SETTINGS";
     field public static final java.lang.String ACTION_NOTIFICATION_LISTENER_SETTINGS = "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS";
     field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS = "android.settings.NOTIFICATION_POLICY_ACCESS_SETTINGS";
     field public static final java.lang.String ACTION_PRINT_SETTINGS = "android.settings.ACTION_PRINT_SETTINGS";
@@ -50960,15 +50960,16 @@
   }
 
   public final class AutofillManager {
+    method public void cancel();
+    method public void commit();
+    method public void notifyValueChanged(android.view.View);
+    method public void notifyViewEntered(android.view.View);
+    method public void notifyViewExited(android.view.View);
+    method public void notifyVirtualValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
+    method public void notifyVirtualViewEntered(android.view.View, int, android.graphics.Rect);
+    method public void notifyVirtualViewExited(android.view.View, int);
     method public void registerCallback(android.view.autofill.AutofillManager.AutofillCallback);
-    method public void reset();
-    method public void startAutofillRequest(android.view.View);
-    method public void startAutofillRequestOnVirtualView(android.view.View, int, android.graphics.Rect);
-    method public void stopAutofillRequest(android.view.View);
-    method public void stopAutofillRequestOnVirtualView(android.view.View, int);
     method public void unregisterCallback(android.view.autofill.AutofillManager.AutofillCallback);
-    method public void valueChanged(android.view.View);
-    method public void virtualValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
     field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
     field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
   }
diff --git a/api/test-current.txt b/api/test-current.txt
index bf9fc82..f35f321 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -34774,6 +34774,7 @@
     field public static final java.lang.String ACTION_NFCSHARING_SETTINGS = "android.settings.NFCSHARING_SETTINGS";
     field public static final java.lang.String ACTION_NFC_PAYMENT_SETTINGS = "android.settings.NFC_PAYMENT_SETTINGS";
     field public static final java.lang.String ACTION_NFC_SETTINGS = "android.settings.NFC_SETTINGS";
+    field public static final java.lang.String ACTION_NIGHT_DISPLAY_SETTINGS = "android.settings.NIGHT_DISPLAY_SETTINGS";
     field public static final java.lang.String ACTION_NOTIFICATION_LISTENER_SETTINGS = "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS";
     field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS = "android.settings.NOTIFICATION_POLICY_ACCESS_SETTINGS";
     field public static final java.lang.String ACTION_PRINT_SETTINGS = "android.settings.ACTION_PRINT_SETTINGS";
@@ -47866,15 +47867,16 @@
   }
 
   public final class AutofillManager {
+    method public void cancel();
+    method public void commit();
+    method public void notifyValueChanged(android.view.View);
+    method public void notifyViewEntered(android.view.View);
+    method public void notifyViewExited(android.view.View);
+    method public void notifyVirtualValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
+    method public void notifyVirtualViewEntered(android.view.View, int, android.graphics.Rect);
+    method public void notifyVirtualViewExited(android.view.View, int);
     method public void registerCallback(android.view.autofill.AutofillManager.AutofillCallback);
-    method public void reset();
-    method public void startAutofillRequest(android.view.View);
-    method public void startAutofillRequestOnVirtualView(android.view.View, int, android.graphics.Rect);
-    method public void stopAutofillRequest(android.view.View);
-    method public void stopAutofillRequestOnVirtualView(android.view.View, int);
     method public void unregisterCallback(android.view.autofill.AutofillManager.AutofillCallback);
-    method public void valueChanged(android.view.View);
-    method public void virtualValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
     field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
     field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
   }
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 1969f8b..78c29e8 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1783,7 +1783,7 @@
         mTranslucentCallback = null;
         mCalled = true;
         if (isFinishing() && mAutoFillResetNeeded) {
-            getSystemService(AutofillManager.class).reset();
+            getSystemService(AutofillManager.class).commit();
         }
     }
 
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index e6fe0d0..70ecf89 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -419,6 +419,7 @@
      *         to connect to
      * @throws SecurityException if the caller does not hold the
      *         {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission.
+     * @hide
      */
     public RecommendationResult requestRecommendation(RecommendationRequest request)
             throws SecurityException {
diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java
index 9db58ee..6656b00 100644
--- a/core/java/android/os/RemoteCallbackList.java
+++ b/core/java/android/os/RemoteCallbackList.java
@@ -18,6 +18,8 @@
 
 import android.util.ArrayMap;
 
+import java.util.function.Consumer;
+
 /**
  * Takes care of the grunt work of maintaining a list of remote interfaces,
  * typically for the use of performing callbacks from a
@@ -308,6 +310,23 @@
     }
 
     /**
+     * Performs {@code action} on each callback, calling
+     * {@link #beginBroadcast()}/{@link #finishBroadcast()} before/after looping
+     *
+     * @hide
+     */
+    public void broadcast(Consumer<E> action) {
+        int itemCount = beginBroadcast();
+        try {
+            for (int i = 0; i < itemCount; i++) {
+                action.accept(getBroadcastItem(i));
+            }
+        } finally {
+            finishBroadcast();
+        }
+    }
+
+    /**
      * Returns the number of registered callbacks. Note that the number of registered
      * callbacks may differ from the value returned by {@link #beginBroadcast()} since
      * the former returns the number of callbacks registered at the time of the call
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4482662..8a2a14c 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -506,8 +506,6 @@
      * Input: Nothing.
      * <p>
      * Output: Nothing.
-     *
-     * @hide
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_NIGHT_DISPLAY_SETTINGS =
@@ -7668,12 +7666,14 @@
        public static final String HDMI_CONTROL_ENABLED = "hdmi_control_enabled";
 
        /**
-        * Whether HDMI system audio is enabled. If enabled, TV internal speaker is muted,
-        * and the output is redirected to AV Receiver connected via
-        * {@Global#HDMI_SYSTEM_AUDIO_OUTPUT}.
+        * Whether HDMI System Audio Control feature is enabled. If enabled, TV will try to turn on
+        * system audio mode if there's a connected CEC-enabled AV Receiver. Then audio stream will
+        * be played on AVR instead of TV spaeker. If disabled, the system audio mode will never be
+        * activated.
         * @hide
         */
-       public static final String HDMI_SYSTEM_AUDIO_ENABLED = "hdmi_system_audio_enabled";
+        public static final String HDMI_SYSTEM_AUDIO_CONTROL_ENABLED =
+                "hdmi_system_audio_control_enabled";
 
        /**
         * Whether TV will automatically turn on upon reception of the CEC command
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 61b1247..6d320ef 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -500,7 +500,12 @@
                         // While creating the surface, we will set it's initial
                         // geometry. Outside of that though, we should generally
                         // leave it to the RenderThread.
-                        if (creating || !mRtHandlingPositionUpdates) {
+                        //
+                        // There is one more case when the buffer size changes we aren't yet
+                        // prepared to sync (as even following the transaction applying
+                        // we still need to latch a buffer).
+                        // b/28866173
+                        if (sizeChanged || creating || !mRtHandlingPositionUpdates) {
                             mSurfaceControl.setPosition(mScreenRect.left, mScreenRect.top);
                             mSurfaceControl.setMatrix(mScreenRect.width() / (float) mSurfaceWidth,
                                     0.0f, 0.0f,
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index aa1cbf2..029caf9 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6132,6 +6132,9 @@
         }
 
         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
+
+        notifyEnterOrExitForAutoFillIfNeeded(true);
+
         return result;
     }
 
@@ -6791,14 +6794,18 @@
             mAttachInfo.mKeyDispatchState.reset(this);
         }
 
+        notifyEnterOrExitForAutoFillIfNeeded(gainFocus);
+    }
+
+    private void notifyEnterOrExitForAutoFillIfNeeded(boolean enter) {
         if (isAutofillable() && isAttachedToWindow()
                 && getResolvedAutofillMode() == AUTOFILL_MODE_AUTO) {
             AutofillManager afm = getAutofillManager();
             if (afm != null) {
-                if (gainFocus) {
-                    afm.startAutofillRequest(this);
-                } else {
-                    afm.stopAutofillRequest(this);
+                if (enter && hasWindowFocus() && isFocused()) {
+                    afm.notifyViewEntered(this);
+                } else if (!hasWindowFocus() || !isFocused()) {
+                    afm.notifyViewExited(this);
                 }
             }
         }
@@ -7368,13 +7375,17 @@
      * <li>Also implement {@link #autofillVirtual(int, AutofillValue)} to autofill the virtual
      * children.
      * <li>Call
-     * {@link android.view.autofill.AutofillManager#startAutofillRequestOnVirtualView} and
-     * {@link android.view.autofill.AutofillManager#stopAutofillRequestOnVirtualView(View, int)}
+     * {@link android.view.autofill.AutofillManager#notifyVirtualViewEntered} and
+     * {@link android.view.autofill.AutofillManager#notifyVirtualViewExited(View, int)}
      * when the focus inside the view changed.
-     * <li>Call {@link android.view.autofill.AutofillManager#virtualValueChanged(View, int,
+     * <li>Call {@link android.view.autofill.AutofillManager#notifyVirtualValueChanged(View, int,
      * AutofillValue)} when the value of a child changed.
-     * <li>Call {@link android.view.autofill.AutofillManager#reset()} when the autofill context
-     * of the view structure changed.
+     * <li>Call {@link AutofillManager#commit()} when the autofill context
+     * of the view structure changed and you want the current autofill interaction if such
+     * to be commited.
+     * <li>Call {@link AutofillManager#cancel()} ()} when the autofill context
+     * of the view structure changed and you want the current autofill interaction if such
+     * to be cancelled.
      * </ol>
      *
      * @param structure Fill in with structured view data.
@@ -11085,6 +11096,7 @@
     @CallSuper
     public void dispatchStartTemporaryDetach() {
         mPrivateFlags3 |= PFLAG3_TEMPORARY_DETACH;
+        notifyEnterOrExitForAutoFillIfNeeded(false);
         onStartTemporaryDetach();
     }
 
@@ -11110,6 +11122,7 @@
         if (hasWindowFocus() && hasFocus()) {
             InputMethodManager.getInstance().focusIn(this);
         }
+        notifyEnterOrExitForAutoFillIfNeeded(true);
     }
 
     /**
@@ -11512,6 +11525,9 @@
         } else if (imm != null && (mPrivateFlags & PFLAG_FOCUSED) != 0) {
             imm.focusIn(this);
         }
+
+        notifyEnterOrExitForAutoFillIfNeeded(hasWindowFocus);
+
         refreshDrawableState();
     }
 
@@ -16879,12 +16895,7 @@
         }
         needGlobalAttributesUpdate(false);
 
-        if (isAutofillable() && isFocused() && getResolvedAutofillMode() == AUTOFILL_MODE_AUTO) {
-            AutofillManager afm = getAutofillManager();
-            if (afm != null) {
-                afm.startAutofillRequest(this);
-            }
-        }
+        notifyEnterOrExitForAutoFillIfNeeded(true);
     }
 
     void dispatchDetachedFromWindow() {
@@ -16932,12 +16943,7 @@
             mOverlay.getOverlayView().dispatchDetachedFromWindow();
         }
 
-        if (isAutofillable() && isFocused() && getResolvedAutofillMode() == AUTOFILL_MODE_AUTO) {
-            AutofillManager afm = getAutofillManager();
-            if (afm != null) {
-                afm.stopAutofillRequest(this);
-            }
-        }
+        notifyEnterOrExitForAutoFillIfNeeded(false);
     }
 
     /**
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 9fa9985e..de0ec40 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -46,6 +46,7 @@
 import android.os.SystemClock;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.Pools;
 import android.util.Pools.SynchronizedPool;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
@@ -3327,7 +3328,74 @@
     @Override
     public void dispatchProvideStructure(ViewStructure structure) {
         super.dispatchProvideStructure(structure);
-        dispatchProvideStructureForAssistOrAutoFill(structure, false);
+        if (isAssistBlocked() || structure.getChildCount() != 0) {
+            return;
+        }
+        final int childrenCount = mChildrenCount;
+        if (childrenCount <= 0) {
+            return;
+        }
+        structure.setChildCount(childrenCount);
+        ArrayList<View> preorderedList = buildOrderedChildList();
+        boolean customOrder = preorderedList == null
+                && isChildrenDrawingOrderEnabled();
+        for (int i = 0; i < childrenCount; i++) {
+            int childIndex;
+            try {
+                childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
+            } catch (IndexOutOfBoundsException e) {
+                childIndex = i;
+                if (mContext.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.M) {
+                    Log.w(TAG, "Bad getChildDrawingOrder while collecting assist @ "
+                            + i + " of " + childrenCount, e);
+                    // At least one app is failing when we call getChildDrawingOrder
+                    // at this point, so deal semi-gracefully with it by falling back
+                    // on the basic order.
+                    customOrder = false;
+                    if (i > 0) {
+                        // If we failed at the first index, there really isn't
+                        // anything to do -- we will just proceed with the simple
+                        // sequence order.
+                        // Otherwise, we failed in the middle, so need to come up
+                        // with an order for the remaining indices and use that.
+                        // Failed at the first one, easy peasy.
+                        int[] permutation = new int[childrenCount];
+                        SparseBooleanArray usedIndices = new SparseBooleanArray();
+                        // Go back and collected the indices we have done so far.
+                        for (int j = 0; j < i; j++) {
+                            permutation[j] = getChildDrawingOrder(childrenCount, j);
+                            usedIndices.put(permutation[j], true);
+                        }
+                        // Fill in the remaining indices with indices that have not
+                        // yet been used.
+                        int nextIndex = 0;
+                        for (int j = i; j < childrenCount; j++) {
+                            while (usedIndices.get(nextIndex, false)) {
+                                nextIndex++;
+                            }
+                            permutation[j] = nextIndex;
+                            nextIndex++;
+                        }
+                        // Build the final view list.
+                        preorderedList = new ArrayList<>(childrenCount);
+                        for (int j = 0; j < childrenCount; j++) {
+                            final int index = permutation[j];
+                            final View child = mChildren[index];
+                            preorderedList.add(child);
+                        }
+                    }
+                } else {
+                    throw e;
+                }
+            }
+            final View child = getAndVerifyPreorderedView(preorderedList, mChildren,
+                    childIndex);
+            final ViewStructure cstructure = structure.newChild(i);
+            child.dispatchProvideStructure(cstructure);
+        }
+        if (preorderedList != null) {
+            preorderedList.clear();
+        }
     }
 
     /**
@@ -3339,21 +3407,44 @@
     @Override
     public void dispatchProvideAutofillStructure(ViewStructure structure, int flags) {
         super.dispatchProvideAutofillStructure(structure, flags);
-        dispatchProvideStructureForAssistOrAutoFill(structure, true);
+        if (isAutofillBlocked() || structure.getChildCount() != 0) {
+            return;
+        }
+        final ChildListForAutoFill children = getChildrenForAutofill();
+        final int childrenCount = children.size();
+        structure.setChildCount(childrenCount);
+        for (int i = 0; i < childrenCount; i++) {
+            final View child = children.get(i);
+            final ViewStructure cstructure = structure.newChild(i);
+            child.dispatchProvideAutofillStructure(cstructure, flags);
+        }
+        children.recycle();
     }
 
-    /** @hide */
-    private ArrayList<View> getChildrenForAutofill() {
-        final ArrayList<View> list = new ArrayList<>();
-        populateChildrenForAutofill(list);
-        return list;
+    /**
+     * Gets the children for autofill. Children for autofill are the first
+     * level descendants that are important for autofill. The returned
+     * child list object is pooled and the caller must recycle it once done.
+     * @hide */
+    private @NonNull ChildListForAutoFill getChildrenForAutofill() {
+        final ChildListForAutoFill children = ChildListForAutoFill.obtain();
+        populateChildrenForAutofill(children);
+        return children;
     }
 
     /** @hide */
     private void populateChildrenForAutofill(ArrayList<View> list) {
-        final int count = mChildrenCount;
-        for (int i = 0; i < count; i++) {
-            final View child = mChildren[i];
+        final int childrenCount = mChildrenCount;
+        if (childrenCount <= 0) {
+            return;
+        }
+        final ArrayList<View> preorderedList = buildOrderedChildList();
+        final boolean customOrder = preorderedList == null
+                && isChildrenDrawingOrderEnabled();
+        for (int i = 0; i < childrenCount; i++) {
+            final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
+            final View child = (preorderedList == null)
+                    ? mChildren[childIndex] : preorderedList.get(childIndex);
             if (child.isImportantForAutofill()) {
                 list.add(child);
             } else if (child instanceof ViewGroup) {
@@ -3362,106 +3453,6 @@
         }
     }
 
-    private void dispatchProvideStructureForAssistOrAutoFill(ViewStructure structure,
-            boolean forAutofill) {
-        boolean blocked = forAutofill ? isAutofillBlocked() : isAssistBlocked();
-        if (blocked || structure.getChildCount() != 0) {
-            return;
-        }
-        final View[] childrenArray;
-        final ArrayList<View> childrenList;
-        final int childrenCount;
-
-        if (forAutofill) {
-            childrenArray = null;
-            // TODO(b/33197203): the current algorithm allocates a new list for each children that
-            // is a view group; ideally, we should use mAttachInfo.mTempArrayList instead, but that
-            // would complicated the algorithm a lot...
-            childrenList = getChildrenForAutofill();
-
-            childrenCount = childrenList.size();
-        } else {
-            childrenArray = mChildren;
-            childrenList = null;
-            childrenCount = getChildCount();
-        }
-
-        if (childrenCount > 0) {
-            structure.setChildCount(childrenCount);
-            ArrayList<View> preorderedList = buildOrderedChildList();
-            boolean customOrder = preorderedList == null
-                    && isChildrenDrawingOrderEnabled();
-            for (int i = 0; i < childrenCount; i++) {
-                int childIndex;
-                try {
-                    childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
-                } catch (IndexOutOfBoundsException e) {
-                    childIndex = i;
-                    if (mContext.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.M) {
-                        Log.w(TAG, "Bad getChildDrawingOrder while collecting assist @ "
-                                + i + " of " + childrenCount, e);
-                        // At least one app is failing when we call getChildDrawingOrder
-                        // at this point, so deal semi-gracefully with it by falling back
-                        // on the basic order.
-                        customOrder = false;
-                        if (i > 0) {
-                            // If we failed at the first index, there really isn't
-                            // anything to do -- we will just proceed with the simple
-                            // sequence order.
-                            // Otherwise, we failed in the middle, so need to come up
-                            // with an order for the remaining indices and use that.
-                            // Failed at the first one, easy peasy.
-                            int[] permutation = new int[childrenCount];
-                            SparseBooleanArray usedIndices = new SparseBooleanArray();
-                            // Go back and collected the indices we have done so far.
-                            for (int j = 0; j < i; j++) {
-                                permutation[j] = getChildDrawingOrder(childrenCount, j);
-                                usedIndices.put(permutation[j], true);
-                            }
-                            // Fill in the remaining indices with indices that have not
-                            // yet been used.
-                            int nextIndex = 0;
-                            for (int j = i; j < childrenCount; j++) {
-                                while (usedIndices.get(nextIndex, false)) {
-                                    nextIndex++;
-                                }
-                                permutation[j] = nextIndex;
-                                nextIndex++;
-                            }
-                            // Build the final view list.
-                            preorderedList = new ArrayList<>(childrenCount);
-                            for (int j = 0; j < childrenCount; j++) {
-                                final int index = permutation[j];
-                                final View child = forAutofill
-                                        ? childrenList.get(index)
-                                        : childrenArray[index];
-                                preorderedList.add(child);
-                            }
-                        }
-                    } else {
-                        throw e;
-                    }
-                }
-
-                final View child = forAutofill
-                        ? getAndVerifyPreorderedView(preorderedList, childrenList, childIndex)
-                        : getAndVerifyPreorderedView(preorderedList, childrenArray, childIndex);
-                final ViewStructure cstructure = structure.newChild(i);
-
-                // Must explicitly check which recursive method to call.
-                if (forAutofill) {
-                    // NOTE: flags are not currently supported, hence 0
-                    child.dispatchProvideAutofillStructure(cstructure, 0);
-                } else {
-                    child.dispatchProvideStructure(cstructure);
-                }
-            }
-            if (preorderedList != null) {
-                preorderedList.clear();
-            }
-        }
-    }
-
     private static View getAndVerifyPreorderedView(ArrayList<View> preorderedList, View[] children,
             int childIndex) {
         final View child;
@@ -3477,21 +3468,6 @@
         return child;
     }
 
-    private static View getAndVerifyPreorderedView(ArrayList<View> preorderedList,
-            ArrayList<View> children, int childIndex) {
-        final View child;
-        if (preorderedList != null) {
-            child = preorderedList.get(childIndex);
-            if (child == null) {
-                throw new RuntimeException("Invalid preorderedList contained null child at index "
-                        + childIndex);
-            }
-        } else {
-            child = children.get(childIndex);
-        }
-        return child;
-    }
-
     /** @hide */
     @Override
     public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
@@ -8192,6 +8168,29 @@
     }
 
     /**
+     * Pooled class that to hold the children for autifill.
+     */
+    static class ChildListForAutoFill extends ArrayList<View> {
+        private static final int MAX_POOL_SIZE = 32;
+
+        private static final Pools.SimplePool<ChildListForAutoFill> sPool =
+                new Pools.SimplePool<>(MAX_POOL_SIZE);
+
+        public static ChildListForAutoFill obtain() {
+            ChildListForAutoFill list = sPool.acquire();
+            if (list == null) {
+                list = new ChildListForAutoFill();
+            }
+            return list;
+        }
+
+        public void recycle() {
+            clear();
+            sPool.release(this);
+        }
+    }
+
+    /**
      * Pooled class that orderes the children of a ViewGroup from start
      * to end based on how they are laid out and the layout direction.
      */
@@ -8228,10 +8227,6 @@
             return mChildren.get(index);
         }
 
-        public int getChildIndex(View child) {
-            return mChildren.indexOf(child);
-        }
-
         private void init(ViewGroup parent, boolean sort) {
             ArrayList<View> children = mChildren;
             final int childCount = parent.getChildCount();
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index fe888ec..c9f9f31 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -40,6 +40,8 @@
 import android.view.IWindow;
 import android.view.View;
 
+import com.android.internal.util.IntPair;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -109,6 +111,8 @@
 
     boolean mIsEnabled;
 
+    int mRelevantEventTypes = AccessibilityEvent.TYPES_ALL_MASK;
+
     boolean mIsTouchExplorationEnabled;
 
     boolean mIsHighTextContrastEnabled;
@@ -203,6 +207,11 @@
         public void notifyServicesStateChanged() {
             mHandler.obtainMessage(MyHandler.MSG_NOTIFY_SERVICES_STATE_CHANGED).sendToTarget();
         }
+
+        @Override
+        public void setRelevantEventTypes(int eventTypes) {
+            mRelevantEventTypes = eventTypes;
+        }
     };
 
     /**
@@ -362,6 +371,14 @@
                     return;
                 }
             }
+            if ((event.getEventType() & mRelevantEventTypes) == 0) {
+                if (DEBUG) {
+                    Log.i(LOG_TAG, "Not dispatching irrelevant event: " + event
+                            + " that is not among "
+                            + AccessibilityEvent.eventTypeToString(mRelevantEventTypes));
+                }
+                return;
+            }
             userId = mUserId;
         }
         try {
@@ -865,8 +882,9 @@
         }
 
         try {
-            final int stateFlags = service.addClient(mClient, mUserId);
-            setStateLocked(stateFlags);
+            final long userStateAndRelevantEvents = service.addClient(mClient, mUserId);
+            setStateLocked(IntPair.first(userStateAndRelevantEvents));
+            mRelevantEventTypes = IntPair.second(userStateAndRelevantEvents);
             mService = service;
         } catch (RemoteException re) {
             Log.e(LOG_TAG, "AccessibilityManagerService is dead", re);
diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
index 157980f..06cb5dc 100644
--- a/core/java/android/view/accessibility/IAccessibilityManager.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -38,7 +38,7 @@
 
     oneway void sendAccessibilityEvent(in AccessibilityEvent uiEvent, int userId);
 
-    int addClient(IAccessibilityManagerClient client, int userId);
+    long addClient(IAccessibilityManagerClient client, int userId);
 
     List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList(int userId);
 
diff --git a/core/java/android/view/accessibility/IAccessibilityManagerClient.aidl b/core/java/android/view/accessibility/IAccessibilityManagerClient.aidl
index 045ac91..9cc0315 100644
--- a/core/java/android/view/accessibility/IAccessibilityManagerClient.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManagerClient.aidl
@@ -25,5 +25,8 @@
 oneway interface IAccessibilityManagerClient {
 
     void setState(int stateFlags);
+
     void notifyServicesStateChanged();
+
+    void setRelevantEventTypes(int eventTypes);
 }
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 2a12e4b..c4f90dc 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -72,8 +72,8 @@
             "android.view.autofill.extra.AUTHENTICATION_RESULT";
 
     /** @hide */ public static final int FLAG_START_SESSION = 0x1;
-    /** @hide */ public static final int FLAG_FOCUS_GAINED = 0x2;
-    /** @hide */ public static final int FLAG_FOCUS_LOST = 0x4;
+    /** @hide */ public static final int FLAG_VIEW_ENTERED = 0x2;
+    /** @hide */ public static final int FLAG_VIEW_EXITED = 0x4;
     /** @hide */ public static final int FLAG_VALUE_CHANGED = 0x8;
 
     private final Rect mTempRect = new Rect();
@@ -121,11 +121,11 @@
     }
 
     /**
-     * Called when an autofill operation on a {@link View} should start.
+     * Called when a {@link View} that supports autofill is entered.
      *
-     * @param view {@link View} that triggered the autofill request.
+     * @param view {@link View} that was entered.
      */
-    public void startAutofillRequest(@NonNull View view) {
+    public void notifyViewEntered(@NonNull View view) {
         ensureServiceClientAddedIfNeeded();
 
         if (!mEnabled) {
@@ -142,35 +142,34 @@
             startSession(id, view.getWindowToken(), bounds, value);
         } else {
             // Update focus on existing session.
-            updateSession(id, bounds, value, FLAG_FOCUS_GAINED);
+            updateSession(id, bounds, value, FLAG_VIEW_ENTERED);
         }
     }
 
     /**
-     * Called when an autofill operation on a {@link View} should stop.
+     * Called when a {@link View} that supports autofill is exited.
      *
-     * @param view {@link View} that triggered the autofill request in
-     *             {@link #startAutofillRequest(View)}.
+     * @param view {@link View} that was exited.
      */
-    public void stopAutofillRequest(@NonNull View view) {
+    public void notifyViewExited(@NonNull View view) {
         ensureServiceClientAddedIfNeeded();
 
         if (mEnabled && mHasSession) {
             final AutofillId id = getAutofillId(view);
 
             // Update focus on existing session.
-            updateSession(id, null, null, FLAG_FOCUS_LOST);
+            updateSession(id, null, null, FLAG_VIEW_EXITED);
         }
     }
 
     /**
-     * Called when an autofill operation on a virtual {@link View} should start.
+     * Called when a virtual view that supports autofill is entered.
      *
-     * @param parent parent of the {@link View} that triggered the autofill request.
-     * @param childId id identifying the virtual child inside the parent view.
+     * @param view the {@link View} whose descendant is the virtual view.
+     * @param childId id identifying the virtual child inside the view.
      * @param bounds child boundaries, relative to the top window.
      */
-    public void startAutofillRequestOnVirtualView(@NonNull View parent, int childId,
+    public void notifyVirtualViewEntered(@NonNull View view, int childId,
             @NonNull Rect bounds) {
         ensureServiceClientAddedIfNeeded();
 
@@ -178,32 +177,31 @@
             return;
         }
 
-        final AutofillId id = getAutofillId(parent, childId);
+        final AutofillId id = getAutofillId(view, childId);
 
         if (!mHasSession) {
             // Starts new session.
-            startSession(id, parent.getWindowToken(), bounds, null);
+            startSession(id, view.getWindowToken(), bounds, null);
         } else {
             // Update focus on existing session.
-            updateSession(id, bounds, null, FLAG_FOCUS_GAINED);
+            updateSession(id, bounds, null, FLAG_VIEW_ENTERED);
         }
     }
 
     /**
-     * Called when an autofill operation on a virtual {@link View} should stop.
+     * Called when a virtual view that supports autofill is exited.
      *
-     * @param parent parent of the {@link View} that triggered the autofill request in
-     *               {@link #startAutofillRequestOnVirtualView(View, int, Rect)}.
-     * @param childId id identifying the virtual child inside the parent view.
+     * @param view the {@link View} whose descendant is the virtual view.
+     * @param childId id identifying the virtual child inside the view.
      */
-    public void stopAutofillRequestOnVirtualView(@NonNull View parent, int childId) {
+    public void notifyVirtualViewExited(@NonNull View view, int childId) {
         ensureServiceClientAddedIfNeeded();
 
         if (mEnabled && mHasSession) {
-            final AutofillId id = getAutofillId(parent, childId);
+            final AutofillId id = getAutofillId(view, childId);
 
             // Update focus on existing session.
-            updateSession(id, null, null, FLAG_FOCUS_LOST);
+            updateSession(id, null, null, FLAG_VIEW_EXITED);
         }
     }
 
@@ -212,7 +210,7 @@
      *
      * @param view view whose value changed.
      */
-    public void valueChanged(View view) {
+    public void notifyValueChanged(View view) {
         if (!mEnabled || !mHasSession) {
             return;
         }
@@ -230,7 +228,7 @@
      * @param childId id identifying the virtual child inside the parent view.
      * @param value new value of the child.
      */
-    public void virtualValueChanged(View parent, int childId, AutofillValue value) {
+    public void notifyVirtualValueChanged(View parent, int childId, AutofillValue value) {
         if (!mEnabled || !mHasSession) {
             return;
         }
@@ -240,12 +238,12 @@
     }
 
     /**
-     * Called to indicate the current autofill context should be reset.
+     * Called to indicate the current autofill context should be commited.
      *
      * <p>For example, when a virtual view is rendering an {@code HTML} page with a form, it should
      * call this method after the form is submitted and another page is rendered.
      */
-    public void reset() {
+    public void commit() {
         if (!mEnabled && !mHasSession) {
             return;
         }
@@ -253,6 +251,20 @@
         finishSession();
     }
 
+    /**
+     * Called to indicate the current autofill context should be cancelled.
+     *
+     * <p>For example, when a virtual view is rendering an {@code HTML} page with a form, it should
+     * call this method if the user does not post the form but moves to another form in this page.
+     */
+    public void cancel() {
+        if (!mEnabled && !mHasSession) {
+            return;
+        }
+
+        cancelSession();
+    }
+
     private AutofillClient getClient() {
         if (mContext instanceof AutofillClient) {
             return (AutofillClient) mContext;
@@ -324,9 +336,21 @@
         }
     }
 
+    private void cancelSession() {
+        if (DEBUG) {
+            Log.d(TAG, "cancelSession()");
+        }
+        mHasSession = false;
+        try {
+            mService.cancelSession(mContext.getActivityToken(), mContext.getUserId());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     private void updateSession(AutofillId id, Rect bounds, AutofillValue value, int flags) {
         if (DEBUG) {
-            if (VERBOSE || (flags & FLAG_FOCUS_LOST) != 0) {
+            if (VERBOSE || (flags & FLAG_VIEW_EXITED) != 0) {
                 Log.d(TAG, "updateSession(): id=" + id + ", bounds=" + bounds + ", value=" + value
                         + ", flags=" + flags);
             }
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
index 07d8cab..86a4965 100644
--- a/core/java/android/view/autofill/IAutoFillManager.aidl
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -36,6 +36,7 @@
     oneway void updateSession(in IBinder activityToken, in AutofillId id, in Rect bounds,
             in AutofillValue value, int flags, int userId);
     oneway void finishSession(in IBinder activityToken, int userId);
+    oneway void cancelSession(in IBinder activityToken, int userId);
     oneway void setAuthenticationResult(in Bundle data,
             in IBinder activityToken, int userId);
     oneway void setHasCallback(in IBinder activityToken, int userId, boolean hasIt);
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index e5505a6..5725b49 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -918,7 +918,7 @@
         // Always notify AutoFillManager - it will return right away if autofill is disabled.
         final AutofillManager afm = mContext.getSystemService(AutofillManager.class);
         if (afm != null) {
-            afm.valueChanged(this);
+            afm.notifyValueChanged(this);
         }
     }
 
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index 81aec9c..d246405 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -173,7 +173,7 @@
             }
             final AutofillManager afm = mContext.getSystemService(AutofillManager.class);
             if (afm != null) {
-                afm.valueChanged(this);
+                afm.notifyValueChanged(this);
             }
 
             mBroadcasting = false;
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index fa8316c..31a88d4 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -182,7 +182,7 @@
         mDelegate.setAutoFillChangeListener((v, y, m, d) -> {
             final AutofillManager afm = context.getSystemService(AutofillManager.class);
             if (afm != null) {
-                afm.valueChanged(this);
+                afm.notifyValueChanged(this);
             }
         });
     }
diff --git a/core/java/android/widget/RadioGroup.java b/core/java/android/widget/RadioGroup.java
index bd62d6c..dc9976d 100644
--- a/core/java/android/widget/RadioGroup.java
+++ b/core/java/android/widget/RadioGroup.java
@@ -188,7 +188,7 @@
         }
         final AutofillManager afm = mContext.getSystemService(AutofillManager.class);
         if (afm != null) {
-            afm.valueChanged(this);
+            afm.notifyValueChanged(this);
         }
     }
 
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index ee70acc..d591316f 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -9136,7 +9136,7 @@
             if (DEBUG_AUTOFILL) {
                 Log.v(LOG_TAG, "sendAfterTextChanged(): notify AFM for text=" + mText);
             }
-            afm.valueChanged(TextView.this);
+            afm.notifyValueChanged(TextView.this);
         }
     }
 
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 1435983..9825f1e 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -144,7 +144,7 @@
         mDelegate.setAutoFillChangeListener((v, h, m) -> {
             final AutofillManager afm = context.getSystemService(AutofillManager.class);
             if (afm != null) {
-                afm.valueChanged(this);
+                afm.notifyValueChanged(this);
             }
         });
     }
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 2aeddb3..6aa7766 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -6027,7 +6027,8 @@
          * Clear all stats for this uid.  Returns true if the uid is completely
          * inactive so can be dropped.
          */
-        boolean reset() {
+        @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+        public boolean reset() {
             boolean active = false;
 
             if (mWifiRunningTimer != null) {
@@ -6968,7 +6969,10 @@
 
             boolean reset() {
                 if (mBgCounter != null) {
-                    mBgCounter.reset(true);
+                    mBgCounter.reset(true /*detachIfReset*/);
+                    // If we detach, we must null the mBgCounter reference so that it
+                    // can be recreated and attached.
+                    mBgCounter = null;
                 }
                 if (mTimer.reset(true)) {
                     mTimer = null;
diff --git a/core/java/com/android/internal/util/IntPair.java b/core/java/com/android/internal/util/IntPair.java
new file mode 100644
index 0000000..7992507
--- /dev/null
+++ b/core/java/com/android/internal/util/IntPair.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+/**
+ * Utilities for treating a {@code long} as a pair of {@code int}s
+ *
+ * @hide
+ */
+public class IntPair {
+    private IntPair() {}
+
+    public static long of(int first, int second) {
+        return (((long)first) << 32) | ((long)second & 0xffffffffL);
+    }
+
+    public static int first(long intPair) {
+        return (int)(intPair >> 32);
+    }
+
+    public static int second(long intPair) {
+        return (int)intPair;
+    }
+}
diff --git a/core/proto/android/providers/settings.proto b/core/proto/android/providers/settings.proto
index 7eb0582..98c9e78 100644
--- a/core/proto/android/providers/settings.proto
+++ b/core/proto/android/providers/settings.proto
@@ -97,7 +97,7 @@
     SettingProto download_max_bytes_over_mobile = 52;
     SettingProto download_recommended_max_bytes_over_mobile = 53;
     SettingProto hdmi_control_enabled = 54;
-    SettingProto hdmi_system_audio_enabled = 55;
+    SettingProto hdmi_system_audio_control_enabled = 55;
     SettingProto hdmi_control_auto_wakeup_enabled = 56;
     SettingProto hdmi_control_auto_device_off_enabled = 57;
     SettingProto mhl_input_switching_enabled = 58;
diff --git a/core/res/res/layout/autofill_dataset_picker.xml b/core/res/res/layout/autofill_dataset_picker.xml
index 9b90de6..133265b 100644
--- a/core/res/res/layout/autofill_dataset_picker.xml
+++ b/core/res/res/layout/autofill_dataset_picker.xml
@@ -18,6 +18,7 @@
     android:id="@+id/autofill_dataset_picker"
     android:layout_width="wrap_content"
     android:layout_height="fill_parent"
-    android:divider="?android:attr/listDivider"
-    android:background="#ffffffff">
+    android:divider="@null"
+    android:background="#ffffffff"
+    android:elevation="@dimen/floating_window_z">
 </ListView>
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 903ef84..0cfdaf5 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -198,7 +198,7 @@
                     Settings.Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED,
                     Settings.Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED,
                     Settings.Global.HDMI_CONTROL_ENABLED,
-                    Settings.Global.HDMI_SYSTEM_AUDIO_ENABLED,
+                    Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED,
                     Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
                     Settings.Global.HTTP_PROXY,
                     Settings.Global.INET_CONDITION_DEBOUNCE_DOWN_DELAY,
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
index e152163..4ec78ff 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
@@ -65,4 +65,49 @@
 
         assertEquals(1, sensorBgCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
     }
+
+    @SmallTest
+    public void testNestedSensorReset() throws Exception {
+        final MockClocks clocks = new MockClocks();
+        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
+        bi.mForceOnBattery = true;
+        clocks.realtime = 100;
+        clocks.uptime = 100;
+        bi.getOnBatteryTimeBase().setRunning(true, 100, 100);
+        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_RECEIVER);
+
+        clocks.realtime += 100;
+        clocks.uptime += 100;
+
+        bi.noteStartSensorLocked(UID, SENSOR_ID);
+
+        clocks.realtime += 100;
+        clocks.uptime += 100;
+
+        // The sensor is started and the background counter has been created.
+        final BatteryStats.Uid uid = bi.getUidStats().get(UID);
+        assertNotNull(uid);
+
+        BatteryStats.Uid.Sensor sensor = uid.getSensorStats().get(SENSOR_ID);
+        assertNotNull(sensor);
+        assertNotNull(sensor.getSensorTime());
+        assertNotNull(sensor.getSensorBgCount());
+
+        // Reset the stats. Since the sensor is still running, we should still see the sensor
+        // timer. Background counter should be gone though.
+        bi.getUidStatsLocked(UID).reset();
+
+        sensor = uid.getSensorStats().get(SENSOR_ID);
+        assertNotNull(sensor);
+        assertNotNull(sensor.getSensorTime());
+        assertNull(sensor.getSensorBgCount());
+
+        bi.noteStopSensorLocked(UID, SENSOR_ID);
+
+        // Now the sensor timer has stopped so this reset should also take out the sensor.
+        bi.getUidStatsLocked(UID).reset();
+
+        sensor = uid.getSensorStats().get(SENSOR_ID);
+        assertNull(sensor);
+    }
 }
diff --git a/libs/common_time/Android.mk b/libs/common_time/Android.mk
index 636f057..1fec504 100644
--- a/libs/common_time/Android.mk
+++ b/libs/common_time/Android.mk
@@ -15,8 +15,7 @@
     clock_recovery.cpp \
     common_clock.cpp \
     main.cpp \
-    utils.cpp \
-    LinearTransform.cpp
+    utils.cpp
 
 # Uncomment to enable vesbose logging and debug service.
 #TIME_SERVICE_DEBUG=true
diff --git a/libs/common_time/LinearTransform.cpp b/libs/common_time/LinearTransform.cpp
deleted file mode 100644
index 6730855..0000000
--- a/libs/common_time/LinearTransform.cpp
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define __STDC_LIMIT_MACROS
-
-#include "LinearTransform.h"
-#include <assert.h>
-
-
-// disable sanitize as these functions may intentionally overflow (see comments below).
-// the ifdef can be removed when host builds use clang.
-#if defined(__clang__)
-#define ATTRIBUTE_NO_SANITIZE_INTEGER __attribute__((no_sanitize("integer")))
-#else
-#define ATTRIBUTE_NO_SANITIZE_INTEGER
-#endif
-
-namespace android {
-
-// sanitize failure with T = int32_t and x = 0x80000000
-template<class T>
-ATTRIBUTE_NO_SANITIZE_INTEGER
-static inline T ABS(T x) { return (x < 0) ? -x : x; }
-
-// Static math methods involving linear transformations
-// remote sanitize failure on overflow case.
-ATTRIBUTE_NO_SANITIZE_INTEGER
-static bool scale_u64_to_u64(
-        uint64_t val,
-        uint32_t N,
-        uint32_t D,
-        uint64_t* res,
-        bool round_up_not_down) {
-    uint64_t tmp1, tmp2;
-    uint32_t r;
-
-    assert(res);
-    assert(D);
-
-    // Let U32(X) denote a uint32_t containing the upper 32 bits of a 64 bit
-    // integer X.
-    // Let L32(X) denote a uint32_t containing the lower 32 bits of a 64 bit
-    // integer X.
-    // Let X[A, B] with A <= B denote bits A through B of the integer X.
-    // Let (A | B) denote the concatination of two 32 bit ints, A and B.
-    // IOW X = (A | B) => U32(X) == A && L32(X) == B
-    //
-    // compute M = val * N (a 96 bit int)
-    // ---------------------------------
-    // tmp2 = U32(val) * N (a 64 bit int)
-    // tmp1 = L32(val) * N (a 64 bit int)
-    // which means
-    // M = val * N = (tmp2 << 32) + tmp1
-    tmp2 = (val >> 32) * N;
-    tmp1 = (val & UINT32_MAX) * N;
-
-    // compute M[32, 95]
-    // tmp2 = tmp2 + U32(tmp1)
-    //      = (U32(val) * N) + U32(L32(val) * N)
-    //      = M[32, 95]
-    tmp2 += tmp1 >> 32;
-
-    // if M[64, 95] >= D, then M/D has bits > 63 set and we have
-    // an overflow.
-    if ((tmp2 >> 32) >= D) {
-        *res = UINT64_MAX;
-        return false;
-    }
-
-    // Divide.  Going in we know
-    // tmp2 = M[32, 95]
-    // U32(tmp2) < D
-    r = tmp2 % D;
-    tmp2 /= D;
-
-    // At this point
-    // tmp1      = L32(val) * N
-    // tmp2      = M[32, 95] / D
-    //           = (M / D)[32, 95]
-    // r         = M[32, 95] % D
-    // U32(tmp2) = 0
-    //
-    // compute tmp1 = (r | M[0, 31])
-    tmp1 = (tmp1 & UINT32_MAX) | ((uint64_t)r << 32);
-
-    // Divide again.  Keep the remainder around in order to round properly.
-    r = tmp1 % D;
-    tmp1 /= D;
-
-    // At this point
-    // tmp2      = (M / D)[32, 95]
-    // tmp1      = (M / D)[ 0, 31]
-    // r         =  M % D
-    // U32(tmp1) = 0
-    // U32(tmp2) = 0
-
-    // Pack the result and deal with the round-up case (As well as the
-    // remote possiblility over overflow in such a case).
-    *res = (tmp2 << 32) | tmp1;
-    if (r && round_up_not_down) {
-        ++(*res);
-        if (!(*res)) {
-            *res = UINT64_MAX;
-            return false;
-        }
-    }
-
-    return true;
-}
-
-// at least one known sanitize failure (see comment below)
-ATTRIBUTE_NO_SANITIZE_INTEGER
-static bool linear_transform_s64_to_s64(
-        int64_t  val,
-        int64_t  basis1,
-        int32_t  N,
-        uint32_t D,
-        bool     invert_frac,
-        int64_t  basis2,
-        int64_t* out) {
-    uint64_t scaled, res;
-    uint64_t abs_val;
-    bool is_neg;
-
-    if (!out)
-        return false;
-
-    // Compute abs(val - basis_64). Keep track of whether or not this delta
-    // will be negative after the scale opertaion.
-    if (val < basis1) {
-        is_neg = true;
-        abs_val = basis1 - val;
-    } else {
-        is_neg = false;
-        abs_val = val - basis1;
-    }
-
-    if (N < 0)
-        is_neg = !is_neg;
-
-    if (!scale_u64_to_u64(abs_val,
-                          invert_frac ? D : ABS(N),
-                          invert_frac ? ABS(N) : D,
-                          &scaled,
-                          is_neg))
-        return false; // overflow/undeflow
-
-    // if scaled is >= 0x8000<etc>, then we are going to overflow or
-    // underflow unless ABS(basis2) is large enough to pull us back into the
-    // non-overflow/underflow region.
-    if (scaled & INT64_MIN) {
-        if (is_neg && (basis2 < 0))
-            return false; // certain underflow
-
-        if (!is_neg && (basis2 >= 0))
-            return false; // certain overflow
-
-        if (ABS(basis2) <= static_cast<int64_t>(scaled & INT64_MAX))
-            return false; // not enough
-
-        // Looks like we are OK
-        *out = (is_neg ? (-scaled) : scaled) + basis2;
-    } else {
-        // Scaled fits within signed bounds, so we just need to check for
-        // over/underflow for two signed integers.  Basically, if both scaled
-        // and basis2 have the same sign bit, and the result has a different
-        // sign bit, then we have under/overflow.  An easy way to compute this
-        // is
-        // (scaled_signbit XNOR basis_signbit) &&
-        // (scaled_signbit XOR res_signbit)
-        // ==
-        // (scaled_signbit XOR basis_signbit XOR 1) &&
-        // (scaled_signbit XOR res_signbit)
-
-        if (is_neg)
-            scaled = -scaled; // known sanitize failure
-        res = scaled + basis2;
-
-        if ((scaled ^ basis2 ^ INT64_MIN) & (scaled ^ res) & INT64_MIN)
-            return false;
-
-        *out = res;
-    }
-
-    return true;
-}
-
-bool LinearTransform::doForwardTransform(int64_t a_in, int64_t* b_out) const {
-    if (0 == a_to_b_denom)
-        return false;
-
-    return linear_transform_s64_to_s64(a_in,
-                                       a_zero,
-                                       a_to_b_numer,
-                                       a_to_b_denom,
-                                       false,
-                                       b_zero,
-                                       b_out);
-}
-
-bool LinearTransform::doReverseTransform(int64_t b_in, int64_t* a_out) const {
-    if (0 == a_to_b_numer)
-        return false;
-
-    return linear_transform_s64_to_s64(b_in,
-                                       b_zero,
-                                       a_to_b_numer,
-                                       a_to_b_denom,
-                                       true,
-                                       a_zero,
-                                       a_out);
-}
-
-template <class T> void LinearTransform::reduce(T* N, T* D) {
-    T a, b;
-    if (!N || !D || !(*D)) {
-        assert(false);
-        return;
-    }
-
-    a = *N;
-    b = *D;
-
-    if (a == 0) {
-        *D = 1;
-        return;
-    }
-
-    // This implements Euclid's method to find GCD.
-    if (a < b) {
-        T tmp = a;
-        a = b;
-        b = tmp;
-    }
-
-    while (1) {
-        // a is now the greater of the two.
-        const T remainder = a % b;
-        if (remainder == 0) {
-            *N /= b;
-            *D /= b;
-            return;
-        }
-        // by swapping remainder and b, we are guaranteeing that a is
-        // still the greater of the two upon entrance to the loop.
-        a = b;
-        b = remainder;
-    }
-};
-
-template void LinearTransform::reduce<uint64_t>(uint64_t* N, uint64_t* D);
-template void LinearTransform::reduce<uint32_t>(uint32_t* N, uint32_t* D);
-
-// sanitize failure if *N = 0x80000000
-ATTRIBUTE_NO_SANITIZE_INTEGER
-void LinearTransform::reduce(int32_t* N, uint32_t* D) {
-    if (N && D && *D) {
-        if (*N < 0) {
-            *N = -(*N);
-            reduce(reinterpret_cast<uint32_t*>(N), D);
-            *N = -(*N);
-        } else {
-            reduce(reinterpret_cast<uint32_t*>(N), D);
-        }
-    }
-}
-
-}  // namespace android
diff --git a/libs/common_time/LinearTransform.h b/libs/common_time/LinearTransform.h
deleted file mode 100644
index bf6ab8e..0000000
--- a/libs/common_time/LinearTransform.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _LINEAR_TRANSFORM_H
-#define _LINEAR_TRANSFORM_H
-
-#include <stdint.h>
-
-namespace android {
-
-// LinearTransform defines a structure which hold the definition of a
-// transformation from single dimensional coordinate system A into coordinate
-// system B (and back again).  Values in A and in B are 64 bit, the linear
-// scale factor is expressed as a rational number using two 32 bit values.
-//
-// Specifically, let
-// f(a) = b
-// F(b) = f^-1(b) = a
-// then
-//
-// f(a) = (((a - a_zero) * a_to_b_numer) / a_to_b_denom) + b_zero;
-//
-// and
-//
-// F(b) = (((b - b_zero) * a_to_b_denom) / a_to_b_numer) + a_zero;
-//
-struct LinearTransform {
-  int64_t  a_zero;
-  int64_t  b_zero;
-  int32_t  a_to_b_numer;
-  uint32_t a_to_b_denom;
-
-  // Transform from A->B
-  // Returns true on success, or false in the case of a singularity or an
-  // overflow.
-  bool doForwardTransform(int64_t a_in, int64_t* b_out) const;
-
-  // Transform from B->A
-  // Returns true on success, or false in the case of a singularity or an
-  // overflow.
-  bool doReverseTransform(int64_t b_in, int64_t* a_out) const;
-
-  // Helpers which will reduce the fraction N/D using Euclid's method.
-  template <class T> static void reduce(T* N, T* D);
-  static void reduce(int32_t* N, uint32_t* D);
-};
-
-
-}
-
-#endif  // _LINEAR_TRANSFORM_H
diff --git a/libs/common_time/clock_recovery.h b/libs/common_time/clock_recovery.h
index 8066a39..278a75e 100644
--- a/libs/common_time/clock_recovery.h
+++ b/libs/common_time/clock_recovery.h
@@ -19,10 +19,9 @@
 
 #include <stdint.h>
 #include <common_time/ICommonClock.h>
+#include <utils/LinearTransform.h>
 #include <utils/threads.h>
 
-#include "LinearTransform.h"
-
 #ifdef TIME_SERVICE_DEBUG
 #include "diag_thread.h"
 #endif
diff --git a/libs/common_time/common_clock.cpp b/libs/common_time/common_clock.cpp
index aed52f1..ee326e1 100644
--- a/libs/common_time/common_clock.cpp
+++ b/libs/common_time/common_clock.cpp
@@ -23,6 +23,7 @@
 #include <stdint.h>
 
 #include <utils/Errors.h>
+#include <utils/LinearTransform.h>
 
 #include "common_clock.h"
 
diff --git a/libs/common_time/common_clock.h b/libs/common_time/common_clock.h
index 5e4e5f5..b786fdc 100644
--- a/libs/common_time/common_clock.h
+++ b/libs/common_time/common_clock.h
@@ -20,10 +20,9 @@
 #include <stdint.h>
 
 #include <utils/Errors.h>
+#include <utils/LinearTransform.h>
 #include <utils/threads.h>
 
-#include "LinearTransform.h"
-
 namespace android {
 
 class CommonClock {
diff --git a/packages/CarrierDefaultApp/res/values/strings.xml b/packages/CarrierDefaultApp/res/values/strings.xml
index fe5669d..f904600 100644
--- a/packages/CarrierDefaultApp/res/values/strings.xml
+++ b/packages/CarrierDefaultApp/res/values/strings.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
     <string name="app_name">CarrierDefaultApp</string>
-    <string name="android_system_label">Android System</string>
+    <string name="android_system_label">Mobile Carrier</string>
     <string name="portal_notification_id">Mobile data has run out</string>
-    <string name="no_data_notification_id">No Mobile data service</string>
-    <string name="portal_notification_detail">Tap to add funds to your %s SIM</string>
+    <string name="no_data_notification_id">Your mobile data has been deactivated</string>
+    <string name="portal_notification_detail">Tap to visit the %s website</string>
     <string name="no_data_notification_detail">Please contact your service provider %s</string>
     <string name="progress_dialogue_network_connection">Connecting to captive portal...</string>
     <string name="alert_dialogue_network_timeout">Network timeout, would you like to retry?</string>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 1fe3c48..4a54c0e 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -240,8 +240,8 @@
                 Settings.Global.HDMI_CONTROL_ENABLED,
                 GlobalSettingsProto.HDMI_CONTROL_ENABLED);
         dumpSetting(s, p,
-                Settings.Global.HDMI_SYSTEM_AUDIO_ENABLED,
-                GlobalSettingsProto.HDMI_SYSTEM_AUDIO_ENABLED);
+                Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED,
+                GlobalSettingsProto.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED);
         dumpSetting(s, p,
                 Settings.Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED,
                 GlobalSettingsProto.HDMI_CONTROL_AUTO_WAKEUP_ENABLED);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
index 6a66fca7..8882cab 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.recents.views;
 
+import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID;
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
@@ -303,7 +304,7 @@
         // TODO: Sometimes targetStackId is not initialized after reboot, so we also have to
         // check for INVALID_STACK_ID
         if (targetStackId == FULLSCREEN_WORKSPACE_STACK_ID || targetStackId == DOCKED_STACK_ID
-                || targetStackId == INVALID_STACK_ID) {
+                || targetStackId == ASSISTANT_STACK_ID || targetStackId == INVALID_STACK_ID) {
             if (taskView == null) {
                 specs.add(composeOffscreenAnimationSpec(task, offscreenTaskRect));
             } else {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index e0d7806..b56035f 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -50,6 +50,7 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.hardware.display.DisplayManager;
+import android.hardware.fingerprint.IFingerprintService;
 import android.hardware.input.InputManager;
 import android.net.Uri;
 import android.os.Binder;
@@ -69,7 +70,6 @@
 import android.os.UserManager;
 import android.os.UserManagerInternal;
 import android.provider.Settings;
-import android.hardware.fingerprint.IFingerprintService;
 import android.provider.SettingsStringUtil.ComponentNameSet;
 import android.provider.SettingsStringUtil.SettingStringHelper;
 import android.text.TextUtils;
@@ -100,7 +100,9 @@
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.content.PackageMonitor;
+import com.android.internal.os.HandlerCaller;
 import com.android.internal.os.SomeArgs;
+import com.android.internal.util.IntPair;
 import com.android.server.LocalServices;
 import com.android.server.policy.AccessibilityShortcutController;
 import com.android.server.statusbar.StatusBarManagerInternal;
@@ -120,6 +122,7 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Consumer;
 
 /**
  * This class is instantiated by the system as a system level service and can be
@@ -434,7 +437,7 @@
     }
 
     @Override
-    public int addClient(IAccessibilityManagerClient client, int userId) {
+    public long addClient(IAccessibilityManagerClient client, int userId) {
         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
@@ -450,7 +453,8 @@
                 if (DEBUG) {
                     Slog.i(LOG_TAG, "Added global client for pid:" + Binder.getCallingPid());
                 }
-                return userState.getClientState();
+                return IntPair.of(
+                        userState.getClientState(), userState.mLastSentRelevantEventTypes);
             } else {
                 userState.mUserClients.register(client);
                 // If this client is not for the current user we do not
@@ -460,7 +464,9 @@
                     Slog.i(LOG_TAG, "Added user client for pid:" + Binder.getCallingPid()
                             + " and userId:" + mCurrentUserId);
                 }
-                return (resolvedUserId == mCurrentUserId) ? userState.getClientState() : 0;
+                return IntPair.of(
+                        (resolvedUserId == mCurrentUserId) ? userState.getClientState() : 0,
+                        userState.mLastSentRelevantEventTypes);
             }
         }
     }
@@ -1323,6 +1329,35 @@
         scheduleNotifyClientsOfServicesStateChange(userState);
     }
 
+    private void updateRelevantEventsLocked(UserState userState) {
+        int relevantEventTypes = AccessibilityCache.CACHE_CRITICAL_EVENTS_MASK;
+        for (Service service : userState.mBoundServices) {
+            relevantEventTypes |= service.mEventTypes;
+        }
+        int finalRelevantEventTypes = relevantEventTypes;
+
+        if (userState.mLastSentRelevantEventTypes != finalRelevantEventTypes) {
+            userState.mLastSentRelevantEventTypes = finalRelevantEventTypes;
+            mMainHandler.obtainMessage(MainHandler.MSG_SEND_RELEVANT_EVENTS_CHANGED_TO_CLIENTS,
+                    userState.mUserId, finalRelevantEventTypes);
+            mMainHandler.post(() -> {
+                broadcastToClients(userState, (client) -> {
+                    try {
+                        client.setRelevantEventTypes(finalRelevantEventTypes);
+                    } catch (RemoteException re) {
+                        /* ignore */
+                    }
+                });
+            });
+        }
+    }
+
+    private void broadcastToClients(
+            UserState userState, Consumer<IAccessibilityManagerClient> clientAction) {
+        mGlobalClients.broadcast(clientAction);
+        userState.mUserClients.broadcast(clientAction);
+    }
+
     /**
      * Determines if given event can be dispatched to a service based on the package of the
      * event source. Specifically, a service is notified if it is interested in events from the
@@ -1633,6 +1668,7 @@
         scheduleUpdateFingerprintGestureHandling(userState);
         scheduleUpdateInputFilter(userState);
         scheduleUpdateClientsIfNeededLocked(userState);
+        updateRelevantEventsLocked(userState);
     }
 
     private void updateAccessibilityFocusBehaviorLocked(UserState userState) {
@@ -2281,6 +2317,7 @@
         public static final int MSG_CLEAR_ACCESSIBILITY_FOCUS = 9;
         public static final int MSG_SEND_SERVICES_STATE_CHANGED_TO_CLIENTS = 10;
         public static final int MSG_UPDATE_FINGERPRINT = 11;
+        public static final int MSG_SEND_RELEVANT_EVENTS_CHANGED_TO_CLIENTS = 12;
 
         public MainHandler(Looper looper) {
             super(looper);
@@ -2351,6 +2388,22 @@
                 case MSG_UPDATE_FINGERPRINT: {
                     updateFingerprintGestureHandling((UserState) msg.obj);
                 } break;
+
+                case MSG_SEND_RELEVANT_EVENTS_CHANGED_TO_CLIENTS: {
+                    final int userId = msg.arg1;
+                    final int relevantEventTypes = msg.arg2;
+                    final UserState userState;
+                    synchronized (mLock) {
+                        userState = getUserStateLocked(userId);
+                    }
+                    broadcastToClients(userState, (client) -> {
+                        try {
+                            client.setRelevantEventTypes(relevantEventTypes);
+                        } catch (RemoteException re) {
+                            /* ignore */
+                        }
+                    });
+                } break;
             }
         }
 
@@ -2380,19 +2433,13 @@
 
         private void sendStateToClients(int clientState,
                 RemoteCallbackList<IAccessibilityManagerClient> clients) {
-            try {
-                final int userClientCount = clients.beginBroadcast();
-                for (int i = 0; i < userClientCount; i++) {
-                    IAccessibilityManagerClient client = clients.getBroadcastItem(i);
-                    try {
-                        client.setState(clientState);
-                    } catch (RemoteException re) {
-                        /* ignore */
-                    }
+            clients.broadcast((client) -> {
+                try {
+                    client.setState(clientState);
+                } catch (RemoteException re) {
+                    /* ignore */
                 }
-            } finally {
-                clients.finishBroadcast();
-            }
+            });
         }
 
         private void notifyClientsOfServicesStateChange(
@@ -4710,6 +4757,8 @@
         public final CopyOnWriteArrayList<Service> mBoundServices =
                 new CopyOnWriteArrayList<>();
 
+        public int mLastSentRelevantEventTypes = AccessibilityEvent.TYPES_ALL_MASK;
+
         public final Map<ComponentName, Service> mComponentNameToServiceMap =
                 new HashMap<>();
 
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
similarity index 88%
rename from services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
rename to services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index b90a2a2..a372f95 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -67,13 +67,13 @@
  * Entry point service for autofill management.
  *
  * <p>This service provides the {@link IAutoFillManager} implementation and keeps a list of
- * {@link AutoFillManagerServiceImpl} per user; the real work is done by
- * {@link AutoFillManagerServiceImpl} itself.
+ * {@link AutofillManagerServiceImpl} per user; the real work is done by
+ * {@link AutofillManagerServiceImpl} itself.
  */
 // TODO(b/33197203): Handle removing of packages
-public final class AutoFillManagerService extends SystemService {
+public final class AutofillManagerService extends SystemService {
 
-    private static final String TAG = "AutoFillManagerService";
+    private static final String TAG = "AutofillManagerService";
 
     static final String RECEIVER_BUNDLE_EXTRA_SESSIONS = "sessions";
 
@@ -83,7 +83,7 @@
     private final Object mLock = new Object();
 
     /**
-     * Cache of {@link AutoFillManagerServiceImpl} per user id.
+     * Cache of {@link AutofillManagerServiceImpl} per user id.
      * <p>
      * It has to be mapped by user id because the same current user could have simultaneous sessions
      * associated to different user profiles (for example, in a multi-window environment or when
@@ -97,7 +97,7 @@
      */
     // TODO(b/33197203): Update the above comment
     @GuardedBy("mLock")
-    private SparseArray<AutoFillManagerServiceImpl> mServicesCache = new SparseArray<>();
+    private SparseArray<AutofillManagerServiceImpl> mServicesCache = new SparseArray<>();
 
     // TODO(b/33197203): set a different max (or disable it) on low-memory devices.
     private final LocalLog mRequestsHistory = new LocalLog(20);
@@ -115,7 +115,7 @@
         }
     };
 
-    public AutoFillManagerService(Context context) {
+    public AutofillManagerService(Context context) {
         super(context);
         mContext = context;
         mUi = new AutoFillUI(mContext);
@@ -157,10 +157,11 @@
      *
      * @return service instance.
      */
-    @NonNull AutoFillManagerServiceImpl getServiceForUserLocked(int userId) {
-        AutoFillManagerServiceImpl service = mServicesCache.get(userId);
+    @NonNull
+    AutofillManagerServiceImpl getServiceForUserLocked(int userId) {
+        AutofillManagerServiceImpl service = mServicesCache.get(userId);
         if (service == null) {
-            service = new AutoFillManagerServiceImpl(mContext, mLock,
+            service = new AutofillManagerServiceImpl(mContext, mLock,
                     mRequestsHistory, userId, mUi);
             mServicesCache.put(userId, service);
         }
@@ -174,7 +175,7 @@
         final IBinder activityToken = getTopActivityForUser();
         if (activityToken != null) {
             synchronized (mLock) {
-                final AutoFillManagerServiceImpl service = mServicesCache.get(userId);
+                final AutofillManagerServiceImpl service = mServicesCache.get(userId);
                 if (service == null) {
                     Log.w(TAG, "handleSaveForUser(): no cached service for userId " + userId);
                     return;
@@ -258,7 +259,7 @@
      * Removes a cached service for a given user.
      */
     private void removeCachedServiceLocked(int userId) {
-        final AutoFillManagerServiceImpl service = mServicesCache.get(userId);
+        final AutofillManagerServiceImpl service = mServicesCache.get(userId);
         if (service != null) {
             mServicesCache.delete(userId);
             service.destroyLocked();
@@ -269,7 +270,7 @@
      * Updates a cached service for a given user.
      */
     private void updateCachedServiceLocked(int userId) {
-        AutoFillManagerServiceImpl service = mServicesCache.get(userId);
+        AutofillManagerServiceImpl service = mServicesCache.get(userId);
         if (service != null) {
             service.updateLocked();
         }
@@ -299,7 +300,7 @@
         @Override
         public void setAuthenticationResult(Bundle data, IBinder activityToken, int userId) {
             synchronized (mLock) {
-                final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
+                final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
                 service.setAuthenticationResultLocked(data, activityToken);
             }
         }
@@ -307,7 +308,7 @@
         @Override
         public void setHasCallback(IBinder activityToken, int userId, boolean hasIt) {
             synchronized (mLock) {
-                final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
+                final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
                 service.setHasCallback(activityToken, hasIt);
             }
         }
@@ -319,7 +320,7 @@
             // TODO(b/33197203): make sure it's called by resumed / focused activity
 
             synchronized (mLock) {
-                final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
+                final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
                 service.startSessionLocked(activityToken, windowToken, appCallback,
                         autofillId, bounds, value, hasCallback);
             }
@@ -329,7 +330,7 @@
         public void updateSession(IBinder activityToken, AutofillId id, Rect bounds,
                 AutofillValue value, int flags, int userId) {
             synchronized (mLock) {
-                final AutoFillManagerServiceImpl service = mServicesCache.get(
+                final AutofillManagerServiceImpl service = mServicesCache.get(
                         UserHandle.getCallingUserId());
                 if (service != null) {
                     service.updateSessionLocked(activityToken, id, bounds, value, flags);
@@ -340,7 +341,7 @@
         @Override
         public void finishSession(IBinder activityToken, int userId) {
             synchronized (mLock) {
-                final AutoFillManagerServiceImpl service = mServicesCache.get(
+                final AutofillManagerServiceImpl service = mServicesCache.get(
                         UserHandle.getCallingUserId());
                 if (service != null) {
                     service.finishSessionLocked(activityToken);
@@ -349,6 +350,17 @@
         }
 
         @Override
+        public void cancelSession(IBinder activityToken, int userId) {
+            synchronized (mLock) {
+                final AutofillManagerServiceImpl service = mServicesCache.get(
+                        UserHandle.getCallingUserId());
+                if (service != null) {
+                    service.cancelSessionLocked(activityToken);
+                }
+            }
+        }
+
+        @Override
         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (mContext.checkCallingPermission(
                     Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) {
@@ -366,7 +378,7 @@
                     pw.println(size);
                     for (int i = 0; i < size; i++) {
                         pw.print("\nService at index "); pw.println(i);
-                        final AutoFillManagerServiceImpl impl = mServicesCache.valueAt(i);
+                        final AutofillManagerServiceImpl impl = mServicesCache.valueAt(i);
                         impl.dumpLocked("  ", pw);
                     }
                 }
@@ -379,7 +391,7 @@
         @Override
         public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
                 String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
-            (new AutoFillManagerServiceShellCommand(AutoFillManagerService.this)).exec(
+            (new AutofillManagerServiceShellCommand(AutofillManagerService.this)).exec(
                     this, in, out, err, args, callback, resultReceiver);
         }
     }
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
similarity index 97%
rename from services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
rename to services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index e691623..b6c60d0 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -19,8 +19,8 @@
 import static android.service.autofill.AutofillService.EXTRA_ACTIVITY_TOKEN;
 import static android.service.voice.VoiceInteractionSession.KEY_RECEIVER_EXTRAS;
 import static android.service.voice.VoiceInteractionSession.KEY_STRUCTURE;
-import static android.view.autofill.AutofillManager.FLAG_FOCUS_GAINED;
-import static android.view.autofill.AutofillManager.FLAG_FOCUS_LOST;
+import static android.view.autofill.AutofillManager.FLAG_VIEW_ENTERED;
+import static android.view.autofill.AutofillManager.FLAG_VIEW_EXITED;
 import static android.view.autofill.AutofillManager.FLAG_START_SESSION;
 import static android.view.autofill.AutofillManager.FLAG_VALUE_CHANGED;
 
@@ -77,13 +77,13 @@
 import java.util.Map.Entry;
 
 /**
- * Bridge between the {@code system_server}'s {@link AutoFillManagerService} and the
+ * Bridge between the {@code system_server}'s {@link AutofillManagerService} and the
  * app's {@link IAutoFillService} implementation.
  *
  */
-final class AutoFillManagerServiceImpl {
+final class AutofillManagerServiceImpl {
 
-    private static final String TAG = "AutoFillManagerServiceImpl";
+    private static final String TAG = "AutofillManagerServiceImpl";
 
     private static final int MSG_SERVICE_SAVE = 1;
 
@@ -173,7 +173,7 @@
         }
     };
 
-    AutoFillManagerServiceImpl(Context context, Object lock, LocalLog requestsHistory,
+    AutofillManagerServiceImpl(Context context, Object lock, LocalLog requestsHistory,
             int userId, AutoFillUI ui) {
         mContext = context;
         mLock = lock;
@@ -240,7 +240,7 @@
     }
 
     /**
-     * Used by {@link AutoFillManagerServiceShellCommand} to request save for the current top app.
+     * Used by {@link AutofillManagerServiceShellCommand} to request save for the current top app.
      */
     void requestSaveForUserLocked(IBinder activityToken) {
         if (!hasService()) {
@@ -321,6 +321,20 @@
         session.showSaveLocked();
     }
 
+    void cancelSessionLocked(IBinder activityToken) {
+        if (!hasService()) {
+            return;
+        }
+
+        final Session session = mSessions.get(activityToken);
+        if (session == null) {
+            Slog.w(TAG, "cancelSessionLocked(): no session for " + activityToken);
+            return;
+        }
+
+        session.destroyLocked();
+    }
+
     private Session createSessionByTokenLocked(IBinder activityToken, IBinder windowToken,
             IBinder appCallbackToken, boolean hasCallback) {
         final Session newSession = new Session(mContext, activityToken,
@@ -457,7 +471,7 @@
 
     @Override
     public String toString() {
-        return "AutoFillManagerServiceImpl: [userId=" + mUserId
+        return "AutofillManagerServiceImpl: [userId=" + mUserId
                 + ", component=" + (mInfo != null
                 ? mInfo.getServiceInfo().getComponentName() : null) + "]";
     }
@@ -610,7 +624,7 @@
         private AssistStructure mStructure;
 
         /**
-         * Whether the client has an {@link android.view.autofill.AutoFillManager.AutofillCallback}.
+         * Whether the client has an {@link android.view.autofill.AutofillManager.AutofillCallback}.
          */
         private boolean mHasCallback;
 
@@ -905,7 +919,7 @@
                 return;
             }
 
-            if ((flags & FLAG_FOCUS_GAINED) != 0) {
+            if ((flags & FLAG_VIEW_ENTERED) != 0) {
                 // Remove the UI if the ViewState has changed.
                 if (mCurrentViewState != viewState) {
                     mUi.hideFillUi(mCurrentViewState != null ? mCurrentViewState.mId : null);
@@ -923,7 +937,7 @@
                 return;
             }
 
-            if ((flags & FLAG_FOCUS_LOST) != 0) {
+            if ((flags & FLAG_VIEW_EXITED) != 0) {
                 if (mCurrentViewState == viewState) {
                     mUi.hideFillUi(viewState.mId);
                     mCurrentViewState = null;
@@ -1001,7 +1015,7 @@
         }
 
         CharSequence getServiceName() {
-            return AutoFillManagerServiceImpl.this.getServiceName();
+            return AutofillManagerServiceImpl.this.getServiceName();
         }
 
         private Intent createAuthFillInIntent(AssistStructure structure) {
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
similarity index 96%
rename from services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java
rename to services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
index 76d9aea..80560f1 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
@@ -16,7 +16,7 @@
 
 package com.android.server.autofill;
 
-import static com.android.server.autofill.AutoFillManagerService.RECEIVER_BUNDLE_EXTRA_SESSIONS;
+import static com.android.server.autofill.AutofillManagerService.RECEIVER_BUNDLE_EXTRA_SESSIONS;
 
 import android.app.ActivityManager;
 import android.os.Bundle;
@@ -30,11 +30,11 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-public final class AutoFillManagerServiceShellCommand extends ShellCommand {
+public final class AutofillManagerServiceShellCommand extends ShellCommand {
 
-    private final AutoFillManagerService mService;
+    private final AutofillManagerService mService;
 
-    public AutoFillManagerServiceShellCommand(AutoFillManagerService service) {
+    public AutofillManagerServiceShellCommand(AutofillManagerService service) {
         mService = service;
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 76385b1..eeff37c 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -182,7 +182,7 @@
             return;
         }
         if (!isBound()) {
-            if (mPendingRequest != null && mPendingRequest != pendingRequest) {
+            if (mPendingRequest != null) {
                 mPendingRequest.cancel();
             }
             mPendingRequest = pendingRequest;
@@ -337,9 +337,10 @@
                 Slog.w(LOG_TAG, "Exception calling onConnected(): " + e);
             }
 
-
             if (mPendingRequest != null) {
-                handlePendingRequest(mPendingRequest);
+                PendingRequest pendingRequest = mPendingRequest;
+                mPendingRequest = null;
+                handlePendingRequest(pendingRequest);
             }
 
             mServiceDied = false;
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index 4a380c5..3fdcd9e 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -44,6 +44,8 @@
 final class FillUi {
     private static final String TAG = "FillUi";
 
+    private static final int VISIBLE_OPTIONS_MAX_COUNT = 3;
+
     interface Callback {
         void onResponsePicked(@NonNull FillResponse response);
         void onDatasetPicked(@NonNull Dataset dataset);
@@ -56,6 +58,8 @@
 
     private final @NonNull Callback mCallback;
 
+    private final @NonNull ListView mListView;
+
     private final @Nullable ArrayAdapter<ViewItem> mAdapter;
 
     private @Nullable String mFilterText;
@@ -73,6 +77,9 @@
         mCallback = callback;
 
         if (response.getAuthentication() != null) {
+            mListView = null;
+            mAdapter = null;
+
             final View content;
             try {
                 content = response.getPresentation().apply(context, null);
@@ -80,7 +87,6 @@
                 callback.onCanceled();
                 Slog.e(TAG, "Error inflating remote views", e);
                 mWindow = null;
-                mAdapter = null;
                 return;
             }
             final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0);
@@ -89,10 +95,9 @@
             content.setOnClickListener(v -> mCallback.onResponsePicked(response));
             mContentWidth = content.getMeasuredWidth();
             mContentHeight = content.getMeasuredHeight();
-            mAdapter = null;
 
             mWindow = new AnchoredWindow(windowToken, content);
-            mWindow.update(mContentWidth, mContentHeight, mAnchorBounds);
+            mWindow.show(mContentWidth, mContentHeight, mAnchorBounds);
         } else {
             final int datasetCount = response.getDatasets().size();
             final ArrayList<ViewItem> items = new ArrayList<>(datasetCount);
@@ -121,16 +126,16 @@
             };
 
             final LayoutInflater inflater = LayoutInflater.from(context);
-            final ListView listView = (ListView) inflater.inflate(
+            mListView = (ListView) inflater.inflate(
                     com.android.internal.R.layout.autofill_dataset_picker, null);
-            listView.setAdapter(mAdapter);
-            listView.setOnItemClickListener((adapter, view, position, id) -> {
+            mListView.setAdapter(mAdapter);
+            mListView.setOnItemClickListener((adapter, view, position, id) -> {
                 final ViewItem vi = mAdapter.getItem(position);
                 mCallback.onDatasetPicked(vi.getDataset());
             });
 
             filter(filterText);
-            mWindow = new AnchoredWindow(windowToken, listView);
+            mWindow = new AnchoredWindow(windowToken, mListView);
         }
     }
 
@@ -138,7 +143,7 @@
         throwIfDestroyed();
         if (!mAnchorBounds.equals(anchorBounds)) {
             mAnchorBounds.set(anchorBounds);
-            mWindow.update(mContentWidth, mContentHeight, anchorBounds);
+            mWindow.show(mContentWidth, mContentHeight, anchorBounds);
         }
     }
 
@@ -156,10 +161,16 @@
                 return;
             }
             if (count <= 0) {
-                mCallback.onCanceled();
+                mWindow.hide();
             } else {
                 if (updateContentSize()) {
-                    mWindow.update(mContentWidth, mContentHeight, mAnchorBounds);
+                    mWindow.show(mContentWidth, mContentHeight, mAnchorBounds);
+                }
+                if (mAdapter.getCount() > VISIBLE_OPTIONS_MAX_COUNT) {
+                    mListView.setVerticalScrollBarEnabled(true);
+                    mListView.onVisibilityAggregated(true);
+                } else {
+                    mListView.setVerticalScrollBarEnabled(false);
                 }
             }
         });
@@ -167,7 +178,7 @@
 
     public void destroy() {
         throwIfDestroyed();
-        mWindow.destroy();
+        mWindow.hide();
         mDestroyed = true;
     }
 
@@ -193,7 +204,7 @@
 
         final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0);
         final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0);
-        final int itemCount = mAdapter.getCount();
+        final int itemCount = Math.min(mAdapter.getCount(), VISIBLE_OPTIONS_MAX_COUNT);
         for (int i = 0; i < itemCount; i++) {
             View view = mAdapter.getItem(i).getView();
             view.measure(widthMeasureSpec, heightMeasureSpec);
@@ -266,7 +277,7 @@
         /**
          * Hides the window.
          */
-        void destroy() {
+        void hide() {
             if (mContentView.isAttachedToWindow()) {
                 mContentView.setOnTouchListener(null);
                 mWm.removeView(mContentView);
@@ -283,7 +294,7 @@
             return false;
         }
 
-        public void update(int desiredWidth, int desiredHeight, Rect anchorBounds) {
+        public void show(int desiredWidth, int desiredHeight, Rect anchorBounds) {
             final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
             params.setTitle("FillUi");
             params.token = mActivityToken;
@@ -293,7 +304,6 @@
                     | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                     | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                     | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
-            params.format = PixelFormat.TRANSLUCENT;
 
             mWm.getDefaultDisplay().getRealSize(mTempPoint);
             final int screenWidth = mTempPoint.x;
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index de11f36..a5e357c 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -235,6 +235,7 @@
     }
 
     public AppOpsService(File storagePath, Handler handler) {
+        LockGuard.installLock(this, LockGuard.INDEX_APP_OPS);
         mFile = new AtomicFile(storagePath);
         mHandler = handler;
         readState();
diff --git a/services/core/java/com/android/server/LockGuard.java b/services/core/java/com/android/server/LockGuard.java
index 3a381ae..b744917 100644
--- a/services/core/java/com/android/server/LockGuard.java
+++ b/services/core/java/com/android/server/LockGuard.java
@@ -53,10 +53,29 @@
  * <li>A guarded synchronized block takes 50ns when disabled.
  * <li>A guarded synchronized block takes 460ns per lock checked when enabled.
  * </ul>
+ * <p>
+ * This class also supports a second simpler mode of operation where well-known
+ * locks are explicitly registered and checked via indexes.
  */
 public class LockGuard {
     private static final String TAG = "LockGuard";
 
+    public static final boolean ENABLED = false;
+
+    /**
+     * Well-known locks ordered by fixed index. Locks with a specific index
+     * should never be acquired while holding a lock of a lower index.
+     */
+    public static final int INDEX_APP_OPS = 0;
+    public static final int INDEX_POWER = 1;
+    public static final int INDEX_USER = 2;
+    public static final int INDEX_PACKAGES = 3;
+    public static final int INDEX_STORAGE = 4;
+    public static final int INDEX_WINDOW = 5;
+    public static final int INDEX_ACTIVITY = 6;
+
+    private static Object[] sKnownFixed = new Object[INDEX_ACTIVITY + 1];
+
     private static ArrayMap<Object, LockInfo> sKnown = new ArrayMap<>(0, true);
 
     private static class LockInfo {
@@ -119,11 +138,41 @@
     }
 
     /**
+     * Yell if any lower-level locks are being held by the calling thread that
+     * is about to acquire the given lock.
+     */
+    public static void guard(int index) {
+        for (int i = 0; i < index; i++) {
+            final Object lock = sKnownFixed[i];
+            if (lock != null && Thread.holdsLock(lock)) {
+                Slog.w(TAG, "Calling thread " + Thread.currentThread().getName() + " is holding "
+                        + lockToString(i) + " while trying to acquire "
+                        + lockToString(index), new Throwable());
+            }
+        }
+    }
+
+    /**
      * Report the given lock with a well-known label.
      */
-    public static void installLock(Object lock, String label) {
+    public static Object installLock(Object lock, String label) {
         final LockInfo info = findOrCreateLockInfo(lock);
         info.label = label;
+        return lock;
+    }
+
+    /**
+     * Report the given lock with a well-known index.
+     */
+    public static Object installLock(Object lock, int index) {
+        sKnownFixed[index] = lock;
+        return lock;
+    }
+
+    public static Object installNewLock(int index) {
+        final Object lock = new Object();
+        installLock(lock, index);
+        return lock;
     }
 
     private static String lockToString(Object lock) {
@@ -135,6 +184,19 @@
         }
     }
 
+    private static String lockToString(int index) {
+        switch (index) {
+            case INDEX_APP_OPS: return "APP_OPS";
+            case INDEX_POWER: return "POWER";
+            case INDEX_USER: return "USER";
+            case INDEX_PACKAGES: return "PACKAGES";
+            case INDEX_STORAGE: return "STORAGE";
+            case INDEX_WINDOW: return "WINDOW";
+            case INDEX_ACTIVITY: return "ACTIVITY";
+            default: return Integer.toString(index);
+        }
+    }
+
     public static void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         for (int i = 0; i < sKnown.size(); i++) {
             final Object lock = sKnown.keyAt(i);
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 1f544a0..3667ecd 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -308,7 +308,7 @@
      * <em>Never</em> hold the lock while performing downcalls into vold, since
      * unsolicited events can suddenly appear to update data structures.
      */
-    private final Object mLock = new Object();
+    private final Object mLock = LockGuard.installNewLock(LockGuard.INDEX_STORAGE);
 
     /** Set of users that we know are unlocked. */
     @GuardedBy("mLock")
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5a6d9aa..9dc59cb 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -691,6 +691,9 @@
             Process.setThreadPriority(tid, -2);
         }
         state.regionCounter++;
+        if (LockGuard.ENABLED) {
+            LockGuard.guard(LockGuard.INDEX_ACTIVITY);
+        }
     }
 
     static void resetPriorityAfterLockedSection() {
@@ -2657,6 +2660,7 @@
     // Note: This method is invoked on the main thread but may need to attach various
     // handlers to other threads.  So take care to be explicit about the looper.
     public ActivityManagerService(Context systemContext) {
+        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
         mContext = systemContext;
         mFactoryTest = FactoryTest.getMode();
         mSystemThread = ActivityThread.currentActivityThread();
@@ -8533,13 +8537,21 @@
 
         // Third...  does the caller itself have permission to access
         // this uri?
-        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
-            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
-                // Require they hold a strong enough Uri permission
-                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
-                    throw new SecurityException("Uid " + callingUid
-                            + " does not have permission to uri " + grantUri);
-                }
+        final int callingAppId = UserHandle.getAppId(callingUid);
+        if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
+            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
+                // Exempted authority for cropping user photos in Settings app
+            } else {
+                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
+                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
+                return -1;
+            }
+        }
+        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
+            // Require they hold a strong enough Uri permission
+            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
+                throw new SecurityException("Uid " + callingUid
+                        + " does not have permission to uri " + grantUri);
             }
         }
         return targetUid;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index d81e092..a50ec49f 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -72,7 +72,8 @@
     @ServiceThreadOnly
     private boolean mArcEstablished = false;
 
-    // Stores whether ARC feature is enabled per port. True by default for all the ARC-enabled ports.
+    // Stores whether ARC feature is enabled per port.
+    // True by default for all the ARC-enabled ports.
     private final SparseBooleanArray mArcFeatureEnabled = new SparseBooleanArray();
 
     // Whether System audio mode is activated or not.
@@ -80,6 +81,10 @@
     @GuardedBy("mLock")
     private boolean mSystemAudioActivated = false;
 
+    // Whether the System Audio Control feature is enabled or not. True by default.
+    @GuardedBy("mLock")
+    private boolean mSystemAudioControlFeatureEnabled;
+
     // The previous port id (input) before switching to the new one. This is remembered in order to
     // be able to switch to it upon receiving <Inactive Source> from currently active source.
     // This remains valid only when the active source was switched via one touch play operation
@@ -186,6 +191,8 @@
         mAutoDeviceOff = mService.readBooleanSetting(Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED,
                 true);
         mAutoWakeup = mService.readBooleanSetting(Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED, true);
+        mSystemAudioControlFeatureEnabled =
+                mService.readBooleanSetting(Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED, true);
         mStandbyHandler = new HdmiCecStandbyModeHandler(service, this);
     }
 
@@ -778,14 +785,11 @@
                         addAndStartAction(new HotplugDetectionAction(HdmiCecLocalDeviceTv.this));
                         addAndStartAction(new PowerStatusMonitorAction(HdmiCecLocalDeviceTv.this));
 
-                        // If there is AVR, initiate System Audio Auto initiation action,
-                        // which turns on and off system audio according to last system
-                        // audio setting.
                         HdmiDeviceInfo avr = getAvrDeviceInfo();
                         if (avr != null) {
                             onNewAvrAdded(avr);
                         } else {
-                            setSystemAudioMode(false, true);
+                            setSystemAudioMode(false);
                         }
                     }
                 });
@@ -818,13 +822,13 @@
     void changeSystemAudioMode(boolean enabled, IHdmiControlCallback callback) {
         assertRunOnServiceThread();
         if (!mService.isControlEnabled() || hasAction(DeviceDiscoveryAction.class)) {
-            setSystemAudioMode(false, true);
+            setSystemAudioMode(false);
             invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE);
             return;
         }
         HdmiDeviceInfo avr = getAvrDeviceInfo();
         if (avr == null) {
-            setSystemAudioMode(false, true);
+            setSystemAudioMode(false);
             invokeCallback(callback, HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
             return;
         }
@@ -834,12 +838,13 @@
     }
 
     // # Seq 25
-    void setSystemAudioMode(boolean on, boolean updateSetting) {
-        HdmiLogger.debug("System Audio Mode change[old:%b new:%b]", mSystemAudioActivated, on);
-
-        if (updateSetting) {
-            mService.writeBooleanSetting(Global.HDMI_SYSTEM_AUDIO_ENABLED, on);
+    void setSystemAudioMode(boolean on) {
+        if (!isSystemAudioControlFeatureEnabled() && on) {
+            HdmiLogger.debug("Cannot turn on system audio mode "
+                    + "because the System Audio Control feature is disabled.");
+            return;
         }
+        HdmiLogger.debug("System Audio Mode change[old:%b new:%b]", mSystemAudioActivated, on);
         updateAudioManagerForSystemAudio(on);
         synchronized (mLock) {
             if (mSystemAudioActivated != on) {
@@ -863,8 +868,21 @@
         }
     }
 
-    boolean getSystemAudioModeSetting() {
-        return mService.readBooleanSetting(Global.HDMI_SYSTEM_AUDIO_ENABLED, false);
+    @ServiceThreadOnly
+    void setSystemAudioControlFeatureEnabled(boolean enabled) {
+        assertRunOnServiceThread();
+        synchronized (mLock) {
+            mSystemAudioControlFeatureEnabled = enabled;
+        }
+        if (hasSystemAudioDevice()) {
+            changeSystemAudioMode(enabled, null);
+        }
+    }
+
+    boolean isSystemAudioControlFeatureEnabled() {
+        synchronized (mLock) {
+            return mSystemAudioControlFeatureEnabled;
+        }
     }
 
     /**
@@ -1112,6 +1130,7 @@
     @ServiceThreadOnly
     protected boolean handleSetSystemAudioMode(HdmiCecMessage message) {
         assertRunOnServiceThread();
+        boolean systemAudioStatus = HdmiUtils.parseCommandParamSystemAudioStatus(message);
         if (!isMessageForSystemAudio(message)) {
             if (getAvrDeviceInfo() == null) {
                 // AVR may not have been discovered yet. Delay the message processing.
@@ -1121,10 +1140,15 @@
                 mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
             }
             return true;
+        } else if (systemAudioStatus && !isSystemAudioControlFeatureEnabled()) {
+            HdmiLogger.debug("Ignoring <Set System Audio Mode> message "
+                    + "because the System Audio Control feature is disabled: %s", message);
+            mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
+            return true;
         }
         removeAction(SystemAudioAutoInitiationAction.class);
         SystemAudioActionFromAvr action = new SystemAudioActionFromAvr(this,
-                message.getSource(), HdmiUtils.parseCommandParamSystemAudioStatus(message), null);
+                message.getSource(), systemAudioStatus, null);
         addAndStartAction(action);
         return true;
     }
@@ -1138,7 +1162,7 @@
             // Ignore this message.
             return true;
         }
-        setSystemAudioMode(HdmiUtils.parseCommandParamSystemAudioStatus(message), true);
+        setSystemAudioMode(HdmiUtils.parseCommandParamSystemAudioStatus(message));
         return true;
     }
 
@@ -1882,6 +1906,7 @@
         pw.println("mArcFeatureEnabled: " + mArcFeatureEnabled);
         pw.println("mSystemAudioActivated: " + mSystemAudioActivated);
         pw.println("mSystemAudioMute: " + mSystemAudioMute);
+        pw.println("mSystemAudioControlFeatureEnabled: " + mSystemAudioControlFeatureEnabled);
         pw.println("mAutoDeviceOff: " + mAutoDeviceOff);
         pw.println("mAutoWakeup: " + mAutoWakeup);
         pw.println("mSkipRoutingControl: " + mSkipRoutingControl);
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 89b10ac..6864e1e 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -486,7 +486,7 @@
                 Global.HDMI_CONTROL_ENABLED,
                 Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED,
                 Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED,
-                Global.HDMI_SYSTEM_AUDIO_ENABLED,
+                Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED,
                 Global.MHL_INPUT_SWITCHING_ENABLED,
                 Global.MHL_POWER_CHARGE_ENABLED
         };
@@ -525,9 +525,9 @@
                     }
                     // No need to propagate to HAL.
                     break;
-                case Global.HDMI_SYSTEM_AUDIO_ENABLED:
-                    if (isTvDeviceEnabled() && tv().isSystemAudioActivated() != enabled) {
-                        tv().changeSystemAudioMode(enabled, null);
+                case Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED:
+                    if (isTvDeviceEnabled()) {
+                        tv().setSystemAudioControlFeatureEnabled(enabled);
                     }
                     break;
                 case Global.MHL_INPUT_SWITCHING_ENABLED:
diff --git a/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java b/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
index e1bcd99..7670dcc 100644
--- a/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
+++ b/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
@@ -262,8 +262,7 @@
             return;
         }
 
-        // Turn off system audio mode and update settings.
-        tv().setSystemAudioMode(false, true);
+        tv().setSystemAudioMode(false);
         if (tv().isArcEstablished()) {
             tv().enableAudioReturnChannel(false);
             addAndStartAction(new RequestArcTerminationAction(localDevice(), address));
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioAction.java b/services/core/java/com/android/server/hdmi/SystemAudioAction.java
index af1a85d..449b208 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioAction.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioAction.java
@@ -133,7 +133,7 @@
     }
 
     protected void setSystemAudioMode(boolean mode) {
-        tv().setSystemAudioMode(mode, true);
+        tv().setSystemAudioMode(mode);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java b/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
index 01063b7..d347a91 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
@@ -50,7 +50,7 @@
             @Override
             public void onSendCompleted(int error) {
                 if (error != SendMessageResult.SUCCESS) {
-                    tv().setSystemAudioMode(false, true);
+                    tv().setSystemAudioMode(false);
                     finish();
                 }
             }
@@ -71,18 +71,24 @@
         return false;
     }
 
-    private void handleSystemAudioModeStatusMessage(boolean isSystemAudioModeOn) {
+    private void handleSystemAudioModeStatusMessage(boolean currentSystemAudioMode) {
         if (!canChangeSystemAudio()) {
             HdmiLogger.debug("Cannot change system audio mode in auto initiation action.");
             finish();
             return;
         }
 
-        boolean systemAudioModeSetting = tv().getSystemAudioModeSetting();
-        if (systemAudioModeSetting && !isSystemAudioModeOn) {
-            addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress, systemAudioModeSetting, null));
+        // If System Audio Control feature is enabled, turn on system audio mode when new AVR is
+        // detected. Otherwise, turn off system audio mode.
+        boolean targetSystemAudioMode = tv().isSystemAudioControlFeatureEnabled();
+        if (currentSystemAudioMode != targetSystemAudioMode) {
+            // Start System Audio Control feature actions only if necessary.
+            addAndStartAction(
+                    new SystemAudioActionFromTv(tv(), mAvrAddress, targetSystemAudioMode, null));
         } else {
-            tv().setSystemAudioMode(isSystemAudioModeOn, true);
+            // If AVR already has correct system audio mode, update target system audio mode
+            // immediately rather than starting feature action.
+            tv().setSystemAudioMode(targetSystemAudioMode);
         }
         finish();
     }
@@ -101,13 +107,15 @@
     }
 
     private void handleSystemAudioModeStatusTimeout() {
-        if (tv().getSystemAudioModeSetting()) {
-            if (canChangeSystemAudio()) {
-                addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress, true, null));
-            }
-        } else {
-            tv().setSystemAudioMode(false, true);
+        if (!canChangeSystemAudio()) {
+            HdmiLogger.debug("Cannot change system audio mode in auto initiation action.");
+            finish();
+            return;
         }
+        // If we can't get the current system audio mode status, just try to turn on/off system
+        // audio mode according to the system audio control setting.
+        addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress,
+                tv().isSystemAudioControlFeatureEnabled(), null));
         finish();
     }
 
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index 6365d15..bb7ffda 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -207,9 +207,35 @@
     }
 
     public void grantDefaultPermissions(int userId) {
-        grantPermissionsToSysComponentsAndPrivApps(userId);
-        grantDefaultSystemHandlerPermissions(userId);
-        grantDefaultPermissionExceptions(userId);
+        if (mService.hasSystemFeature(PackageManager.FEATURE_EMBEDDED, 0)) {
+            grantAllRuntimePermissions(userId);
+        } else {
+            grantPermissionsToSysComponentsAndPrivApps(userId);
+            grantDefaultSystemHandlerPermissions(userId);
+            grantDefaultPermissionExceptions(userId);
+        }
+    }
+
+    private void grantRuntimePermissionsForPackageLocked(int userId, PackageParser.Package pkg) {
+        Set<String> permissions = new ArraySet<>();
+        for (String permission :  pkg.requestedPermissions) {
+            BasePermission bp = mService.mSettings.mPermissions.get(permission);
+            if (bp != null && bp.isRuntime()) {
+                permissions.add(permission);
+            }
+        }
+        if (!permissions.isEmpty()) {
+            grantRuntimePermissionsLPw(pkg, permissions, true, userId);
+        }
+    }
+
+    private void grantAllRuntimePermissions(int userId) {
+        Log.i(TAG, "Granting all runtime permissions for user " + userId);
+        synchronized (mService.mPackages) {
+            for (PackageParser.Package pkg : mService.mPackages.values()) {
+                grantRuntimePermissionsForPackageLocked(userId, pkg);
+            }
+        }
     }
 
     public void scheduleReadDefaultPermissionExceptions() {
@@ -226,18 +252,7 @@
                         || pkg.requestedPermissions.isEmpty()) {
                     continue;
                 }
-                Set<String> permissions = new ArraySet<>();
-                final int permissionCount = pkg.requestedPermissions.size();
-                for (int i = 0; i < permissionCount; i++) {
-                    String permission = pkg.requestedPermissions.get(i);
-                    BasePermission bp = mService.mSettings.mPermissions.get(permission);
-                    if (bp != null && bp.isRuntime()) {
-                        permissions.add(permission);
-                    }
-                }
-                if (!permissions.isEmpty()) {
-                    grantRuntimePermissionsLPw(pkg, permissions, true, userId);
-                }
+                grantRuntimePermissionsForPackageLocked(userId, pkg);
             }
         }
     }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e8af310..c27806d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -266,6 +266,7 @@
 import com.android.server.FgThread;
 import com.android.server.IntentResolver;
 import com.android.server.LocalServices;
+import com.android.server.LockGuard;
 import com.android.server.ServiceThread;
 import com.android.server.SystemConfig;
 import com.android.server.SystemServerInitThreadPool;
@@ -2212,6 +2213,7 @@
 
     public PackageManagerService(Context context, Installer installer,
             boolean factoryTest, boolean onlyCore) {
+        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
                 SystemClock.uptimeMillis());
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 627fa54..b9fcf4e 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -94,6 +94,7 @@
 import com.android.internal.util.XmlUtils;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.server.LocalServices;
+import com.android.server.LockGuard;
 import com.android.server.SystemService;
 import com.android.server.am.UserState;
 import com.android.server.storage.DeviceStorageMonitorInternal;
@@ -227,7 +228,7 @@
     private final Object mPackagesLock;
     private final UserDataPreparer mUserDataPreparer;
     // Short-term lock for internal state, when interaction/sync with PM is not required
-    private final Object mUsersLock = new Object();
+    private final Object mUsersLock = LockGuard.installNewLock(LockGuard.INDEX_USER);
     private final Object mRestrictionsLock = new Object();
 
     private final Handler mHandler;
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 24f6f89..4f67e8c 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -76,6 +76,7 @@
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.ArrayUtils;
 import com.android.server.EventLogTags;
+import com.android.server.LockGuard;
 import com.android.server.RescueParty;
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
@@ -210,7 +211,7 @@
     private DreamManagerInternal mDreamManager;
     private Light mAttentionLight;
 
-    private final Object mLock = new Object();
+    private final Object mLock = LockGuard.installNewLock(LockGuard.INDEX_POWER);
 
     // A bitfield that indicates what parts of the power state have
     // changed and need to be recalculated.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 3e9f2a8..f9c4efd 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -213,6 +213,7 @@
 import com.android.server.EventLogTags;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
+import com.android.server.LockGuard;
 import com.android.server.UiThread;
 import com.android.server.Watchdog;
 import com.android.server.input.InputManagerService;
@@ -940,6 +941,7 @@
     private WindowManagerService(Context context, InputManagerService inputManager,
             boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore,
             WindowManagerPolicy policy) {
+        LockGuard.installLock(this, LockGuard.INDEX_WINDOW);
         mRoot = new RootWindowContainer(this);
         mContext = context;
         mHaveInputMethods = haveInputMethods;
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 1a0aff7..a8423e2 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -195,7 +195,7 @@
     private static final String WALLPAPER_SERVICE_CLASS =
             "com.android.server.wallpaper.WallpaperManagerService$Lifecycle";
     private static final String AUTO_FILL_MANAGER_SERVICE_CLASS =
-            "com.android.server.autofill.AutoFillManagerService";
+            "com.android.server.autofill.AutofillManagerService";
 
     private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
 
diff --git a/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java
index 60842a6..340c624 100644
--- a/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java
@@ -34,6 +34,8 @@
 import android.view.accessibility.IAccessibilityManager;
 import android.view.accessibility.IAccessibilityManagerClient;
 
+import com.android.internal.util.IntPair;
+
 /**
  * This test exercises the
  * {@link com.android.server.accessibility.AccessibilityManagerService} by mocking the
@@ -109,7 +111,7 @@
 
         // invoke the method under test
         final int stateFlagsDisabled =
-                mManagerService.addClient(mockClient, UserHandle.USER_CURRENT);
+                IntPair.first(mManagerService.addClient(mockClient, UserHandle.USER_CURRENT));
         boolean enabledAccessibilityDisabled =
             (stateFlagsDisabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
 
@@ -122,7 +124,7 @@
 
         // invoke the method under test
         final int stateFlagsEnabled =
-                mManagerService.addClient(mockClient, UserHandle.USER_CURRENT);
+                IntPair.first(mManagerService.addClient(mockClient, UserHandle.USER_CURRENT));
         boolean enabledAccessibilityEnabled =
             (stateFlagsEnabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
 
@@ -144,7 +146,7 @@
 
         // invoke the method under test
         final int stateFlagsEnabled =
-                mManagerService.addClient(mockClient, UserHandle.USER_CURRENT);
+                IntPair.first(mManagerService.addClient(mockClient, UserHandle.USER_CURRENT));
         boolean enabledAccessibilityEnabled =
             (stateFlagsEnabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
 
@@ -157,7 +159,7 @@
 
         // invoke the method under test
         final int stateFlagsDisabled =
-                mManagerService.addClient(mockClient, UserHandle.USER_CURRENT);
+                IntPair.first(mManagerService.addClient(mockClient, UserHandle.USER_CURRENT));
         boolean enabledAccessibilityDisabled =
             (stateFlagsDisabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
 
@@ -572,8 +574,9 @@
 
         public void notifyServicesStateChanged() {}
 
-        public void setTouchExplorationEnabled(boolean enabled) {
-        }
+        public void setRelevantEventTypes(int eventTypes) {}
+
+        public void setTouchExplorationEnabled(boolean enabled) {}
     }
 
     /**
diff --git a/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java b/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java
index 6e3e6c6..9261771 100644
--- a/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java
@@ -18,7 +18,6 @@
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -32,6 +31,8 @@
 import android.view.accessibility.IAccessibilityManager;
 import android.view.accessibility.IAccessibilityManagerClient;
 
+import com.android.internal.util.IntPair;
+
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
@@ -60,10 +61,12 @@
     private AccessibilityManager createManager(boolean enabled) throws Exception {
         if (enabled) {
             when(mMockService.addClient(any(IAccessibilityManagerClient.class), anyInt()))
-                    .thenReturn(AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
+                    .thenReturn(
+                            IntPair.of(AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED,
+                                    AccessibilityEvent.TYPES_ALL_MASK));
         } else {
             when(mMockService.addClient(any(IAccessibilityManagerClient.class), anyInt()))
-                    .thenReturn(0);
+                    .thenReturn(IntPair.of(0, AccessibilityEvent.TYPES_ALL_MASK));
         }
 
         AccessibilityManager manager =
diff --git a/tests/net/java/android/net/ip/IpManagerTest.java b/tests/net/java/android/net/ip/IpManagerTest.java
new file mode 100644
index 0000000..025b017
--- /dev/null
+++ b/tests/net/java/android/net/ip/IpManagerTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ip;
+
+import static org.mockito.Mockito.when;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.INetworkManagementService;
+import android.provider.Settings;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.mock.MockContentResolver;
+
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.internal.R;
+
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for IpManager.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class IpManagerTest {
+    private static final int DEFAULT_AVOIDBADWIFI_CONFIG_VALUE = 1;
+
+    @Mock private Context mContext;
+    @Mock private INetworkManagementService mNMService;
+    @Mock private Resources mResources;
+    private MockContentResolver mContentResolver;
+
+    @Before public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        when(mContext.getResources()).thenReturn(mResources);
+        when(mResources.getInteger(R.integer.config_networkAvoidBadWifi))
+                .thenReturn(DEFAULT_AVOIDBADWIFI_CONFIG_VALUE);
+
+        mContentResolver = new MockContentResolver();
+        mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+        when(mContext.getContentResolver()).thenReturn(mContentResolver);
+    }
+
+    @Test
+    public void testNullCallbackDoesNotThrow() throws Exception {
+        final IpManager ipm = new IpManager(mContext, "lo", null, mNMService);
+    }
+
+    @Test
+    public void testInvalidInterfaceDoesNotThrow() throws Exception {
+        final IpManager.Callback cb = new IpManager.Callback();
+        final IpManager ipm = new IpManager(mContext, "test_wlan0", cb, mNMService);
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java b/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java
index 3ce7cab..672ff6d 100644
--- a/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java
+++ b/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java
@@ -95,6 +95,9 @@
 
                 public void notifyServicesStateChanged() {
                 }
+
+                public void setRelevantEventTypes(int eventTypes) {
+                }
             };
 
     /**