Merge "Make stack queries multi-display aware"
diff --git a/api/current.txt b/api/current.txt
index e14784e..a45583a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9895,6 +9895,7 @@
     method public abstract void sendBroadcast(@RequiresPermission android.content.Intent, @Nullable String);
     method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public abstract void sendBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle);
     method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public abstract void sendBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle, @Nullable String);
+    method public void sendBroadcastWithMultiplePermissions(@NonNull android.content.Intent, @NonNull String[]);
     method public abstract void sendOrderedBroadcast(@RequiresPermission android.content.Intent, @Nullable String);
     method public abstract void sendOrderedBroadcast(@NonNull @RequiresPermission android.content.Intent, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
     method public void sendOrderedBroadcast(@NonNull android.content.Intent, @Nullable String, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
@@ -41457,6 +41458,7 @@
     method @NonNull public android.service.autofill.FillResponse build();
     method @NonNull public android.service.autofill.FillResponse.Builder disableAutofill(long);
     method @NonNull public android.service.autofill.FillResponse.Builder setAuthentication(@NonNull android.view.autofill.AutofillId[], @Nullable android.content.IntentSender, @Nullable android.widget.RemoteViews);
+    method @NonNull public android.service.autofill.FillResponse.Builder setCancelTargetIds(@Nullable int[]);
     method @NonNull public android.service.autofill.FillResponse.Builder setClientState(@Nullable android.os.Bundle);
     method @NonNull public android.service.autofill.FillResponse.Builder setFieldClassificationIds(@NonNull android.view.autofill.AutofillId...);
     method @NonNull public android.service.autofill.FillResponse.Builder setFlags(int);
diff --git a/api/system-current.txt b/api/system-current.txt
index 3a125f6..e40fd24 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1431,7 +1431,6 @@
     method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public android.content.Intent registerReceiverForAllUsers(@Nullable android.content.BroadcastReceiver, @NonNull android.content.IntentFilter, @Nullable String, @Nullable android.os.Handler);
     method public abstract void sendBroadcast(android.content.Intent, @Nullable String, @Nullable android.os.Bundle);
     method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public abstract void sendBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle, @Nullable String, @Nullable android.os.Bundle);
-    method public void sendBroadcastMultiplePermissions(@NonNull android.content.Intent, @NonNull String[]);
     method public abstract void sendOrderedBroadcast(@NonNull android.content.Intent, @Nullable String, @Nullable android.os.Bundle, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
     method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public void startActivityAsUser(@NonNull @RequiresPermission android.content.Intent, @NonNull android.os.UserHandle);
     field public static final String APP_PREDICTION_SERVICE = "app_prediction";
diff --git a/config/OWNERS b/config/OWNERS
new file mode 100644
index 0000000..53f80e6
--- /dev/null
+++ b/config/OWNERS
@@ -0,0 +1,5 @@
+# compat-team@ for changes to hiddenapi files
+per-file hiddenapi-* = andreionea@google.com, atrost@google.com, mathewi@google.com, satayev@google.com
+
+# Escalations:
+per-file hiddenapi-* = bdc@google.com, narayan@google.com
\ No newline at end of file
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index 038994f..7511fd0 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -671,8 +671,6 @@
 
         /**
          * Set filter on on manufacturerData. A negative manufacturerId is considered as invalid id.
-         * <p>
-         * Note the first two bytes of the {@code manufacturerData} is the manufacturerId.
          *
          * @throws IllegalArgumentException If the {@code manufacturerId} is invalid.
          */
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 936790f..7703e08 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2081,7 +2081,6 @@
      * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
      * @hide
      */
-    @SystemApi
     public void sendBroadcastMultiplePermissions(@NonNull Intent intent,
             @NonNull String[] receiverPermissions) {
         throw new RuntimeException("Not implemented. Must override in a subclass.");
@@ -2099,6 +2098,33 @@
      *
      * @param intent The Intent to broadcast; all receivers matching this
      *               Intent will receive the broadcast.
+     * @param receiverPermissions Array of names of permissions that a receiver must hold
+     *                            in order to receive your broadcast.
+     *                            If empty, no permissions are required.
+     *
+     * @see android.content.BroadcastReceiver
+     * @see #registerReceiver
+     * @see #sendBroadcast(Intent)
+     * @see #sendOrderedBroadcast(Intent, String)
+     * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
+     */
+    public void sendBroadcastWithMultiplePermissions(@NonNull Intent intent,
+            @NonNull String[] receiverPermissions) {
+        sendBroadcastMultiplePermissions(intent, receiverPermissions);
+    }
+
+    /**
+     * Broadcast the given intent to all interested BroadcastReceivers, allowing
+     * an array of required permissions to be enforced.  This call is asynchronous; it returns
+     * immediately, and you will continue executing while the receivers are run.  No results are
+     * propagated from receivers and receivers can not abort the broadcast. If you want to allow
+     * receivers to propagate results or abort the broadcast, you must send an ordered broadcast
+     * using {@link #sendOrderedBroadcast(Intent, String)}.
+     *
+     * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
+     *
+     * @param intent The Intent to broadcast; all receivers matching this
+     *               Intent will receive the broadcast.
      * @param user The user to send the broadcast to.
      * @param receiverPermissions Array of names of permissions that a receiver must hold
      *                            in order to receive your broadcast.
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 1a33166..194068c 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -52,13 +52,12 @@
 import android.os.ServiceSpecificException;
 import android.provider.Settings;
 import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.SparseIntArray;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.telephony.ITelephony;
-import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.Protocol;
 
@@ -711,6 +710,12 @@
     @Deprecated
     public static final int TYPE_TEST = 18; // TODO: Remove this once NetworkTypes are unused.
 
+    // Deprecated constants for return values of startUsingNetworkFeature. They used to live
+    // in com.android.internal.telephony.PhoneConstants until they were made inaccessible.
+    private static final int DEPRECATED_PHONE_CONSTANT_APN_ALREADY_ACTIVE = 0;
+    private static final int DEPRECATED_PHONE_CONSTANT_APN_REQUEST_STARTED = 1;
+    private static final int DEPRECATED_PHONE_CONSTANT_APN_REQUEST_FAILED = 3;
+
     /** {@hide} */
     public static final int MAX_RADIO_TYPE = TYPE_TEST;
 
@@ -1407,7 +1412,7 @@
         if (netCap == null) {
             Log.d(TAG, "Can't satisfy startUsingNetworkFeature for " + networkType + ", " +
                     feature);
-            return PhoneConstants.APN_REQUEST_FAILED;
+            return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_FAILED;
         }
 
         NetworkRequest request = null;
@@ -1417,9 +1422,9 @@
                 Log.d(TAG, "renewing startUsingNetworkFeature request " + l.networkRequest);
                 renewRequestLocked(l);
                 if (l.currentNetwork != null) {
-                    return PhoneConstants.APN_ALREADY_ACTIVE;
+                    return DEPRECATED_PHONE_CONSTANT_APN_ALREADY_ACTIVE;
                 } else {
-                    return PhoneConstants.APN_REQUEST_STARTED;
+                    return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_STARTED;
                 }
             }
 
@@ -1427,10 +1432,10 @@
         }
         if (request != null) {
             Log.d(TAG, "starting startUsingNetworkFeature for request " + request);
-            return PhoneConstants.APN_REQUEST_STARTED;
+            return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_STARTED;
         } else {
             Log.d(TAG, " request Failed");
-            return PhoneConstants.APN_REQUEST_FAILED;
+            return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_FAILED;
         }
     }
 
@@ -2148,19 +2153,14 @@
     @Deprecated
     @UnsupportedAppUsage
     public boolean getMobileDataEnabled() {
-        IBinder b = ServiceManager.getService(Context.TELEPHONY_SERVICE);
-        if (b != null) {
-            try {
-                ITelephony it = ITelephony.Stub.asInterface(b);
-                int subId = SubscriptionManager.getDefaultDataSubscriptionId();
-                Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId);
-                boolean retVal = it.isUserDataEnabled(subId);
-                Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId
-                        + " retVal=" + retVal);
-                return retVal;
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
+        TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
+        if (tm != null) {
+            int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+            Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId);
+            boolean retVal = tm.createForSubscriptionId(subId).isDataEnabled();
+            Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId
+                    + " retVal=" + retVal);
+            return retVal;
         }
         Log.d("ConnectivityManager", "getMobileDataEnabled()- remote exception retVal=false");
         return false;
diff --git a/core/java/android/os/RemoteException.java b/core/java/android/os/RemoteException.java
index 10ef279..98c66d1 100644
--- a/core/java/android/os/RemoteException.java
+++ b/core/java/android/os/RemoteException.java
@@ -44,6 +44,8 @@
      * state or making security decisions based on the perceived success or
      * failure of a call, or any default values returned. For this reason, we
      * want to strongly throw when there was trouble with the transaction.
+     *
+     * @throws RuntimeException
      */
     @NonNull
     public RuntimeException rethrowAsRuntimeException() {
@@ -60,6 +62,8 @@
      * state or making security decisions based on the perceived success or
      * failure of a call, or any default values returned. For this reason, we
      * want to strongly throw when there was trouble with the transaction.
+     *
+     * @throws RuntimeException
      */
     @NonNull
     public RuntimeException rethrowFromSystemServer() {
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index 9d14d9d..e7a271c 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -26,6 +26,9 @@
 
 import com.android.internal.annotations.GuardedBy;
 
+import dalvik.annotation.optimization.CriticalNative;
+import dalvik.annotation.optimization.FastNative;
+
 import libcore.util.HexEncoding;
 
 import java.nio.charset.StandardCharsets;
@@ -93,18 +96,43 @@
         }
     }
 
+    // The one-argument version of native_get used to be a regular native function. Nowadays,
+    // we use the two-argument form of native_get all the time, but we can't just delete the
+    // one-argument overload: apps use it via reflection, as the UnsupportedAppUsage annotation
+    // indicates. Let's just live with having a Java function with a very unusual name.
     @UnsupportedAppUsage
-    private static native String native_get(String key);
+    private static String native_get(String key) {
+        return native_get(key, "");
+    }
+
+    @FastNative
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     private static native String native_get(String key, String def);
+    @FastNative
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     private static native int native_get_int(String key, int def);
+    @FastNative
     @UnsupportedAppUsage
     private static native long native_get_long(String key, long def);
+    @FastNative
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     private static native boolean native_get_boolean(String key, boolean def);
+
+    @FastNative
+    private static native long native_find(String name);
+    @FastNative
+    private static native String native_get(long handle);
+    @CriticalNative
+    private static native int native_get_int(long handle, int def);
+    @CriticalNative
+    private static native long native_get_long(long handle, long def);
+    @CriticalNative
+    private static native boolean native_get_boolean(long handle, boolean def);
+
+    // _NOT_ FastNative: native_set performs IPC and can block
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     private static native void native_set(String key, String def);
+
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     private static native void native_add_change_callback();
     private static native void native_report_sysprop_change();
@@ -246,25 +274,27 @@
 
     @SuppressWarnings("unused")  // Called from native code.
     private static void callChangeCallbacks() {
+        ArrayList<Runnable> callbacks = null;
         synchronized (sChangeCallbacks) {
             //Log.i("foo", "Calling " + sChangeCallbacks.size() + " change callbacks!");
             if (sChangeCallbacks.size() == 0) {
                 return;
             }
-            ArrayList<Runnable> callbacks = new ArrayList<Runnable>(sChangeCallbacks);
-            final long token = Binder.clearCallingIdentity();
-            try {
-                for (int i = 0; i < callbacks.size(); i++) {
-                    try {
-                        callbacks.get(i).run();
-                    } catch (Throwable t) {
-                        Log.wtf(TAG, "Exception in SystemProperties change callback", t);
-                        // Ignore and try to go on.
-                    }
+            callbacks = new ArrayList<Runnable>(sChangeCallbacks);
+        }
+        final long token = Binder.clearCallingIdentity();
+        try {
+            for (int i = 0; i < callbacks.size(); i++) {
+                try {
+                    callbacks.get(i).run();
+                } catch (Throwable t) {
+                    // Ignore and try to go on. Don't use wtf here: that
+                    // will cause the process to exit on some builds and break tests.
+                    Log.e(TAG, "Exception in SystemProperties change callback", t);
                 }
-            } finally {
-                Binder.restoreCallingIdentity(token);
             }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
@@ -301,4 +331,60 @@
     @UnsupportedAppUsage
     private SystemProperties() {
     }
+
+    /**
+     * Look up a property location by name.
+     * @name name of the property
+     * @return property handle or {@code null} if property isn't set
+     * @hide
+     */
+    @Nullable public static Handle find(@NonNull String name) {
+        long nativeHandle = native_find(name);
+        if (nativeHandle == 0) {
+            return null;
+        }
+        return new Handle(nativeHandle);
+    }
+
+    /**
+     * Handle to a pre-located property. Looking up a property handle in advance allows
+     * for optimal repeated lookup of a single property.
+     * @hide
+     */
+    public static final class Handle {
+
+        private final long mNativeHandle;
+
+        /**
+         * @return Value of the property
+         */
+        @NonNull public String get() {
+            return native_get(mNativeHandle);
+        }
+        /**
+         * @param def default value
+         * @return value or {@code def} on parse error
+         */
+        public int getInt(int def) {
+            return native_get_int(mNativeHandle, def);
+        }
+        /**
+         * @param def default value
+         * @return value or {@code def} on parse error
+         */
+        public long getLong(long def) {
+            return native_get_long(mNativeHandle, def);
+        }
+        /**
+         * @param def default value
+         * @return value or {@code def} on parse error
+         */
+        public boolean getBoolean(boolean def) {
+            return native_get_boolean(mNativeHandle, def);
+        }
+
+        private Handle(long nativeHandle) {
+            mNativeHandle = nativeHandle;
+        }
+    }
 }
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index 6b3009f..c99fe61 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -85,6 +85,7 @@
     private final int mFlags;
     private int mRequestId;
     private final @Nullable UserData mUserData;
+    private final @Nullable int[] mCancelIds;
 
     private FillResponse(@NonNull Builder builder) {
         mDatasets = (builder.mDatasets != null) ? new ParceledListSlice<>(builder.mDatasets) : null;
@@ -101,6 +102,7 @@
         mFlags = builder.mFlags;
         mRequestId = INVALID_REQUEST_ID;
         mUserData = builder.mUserData;
+        mCancelIds = builder.mCancelIds;
     }
 
     /** @hide */
@@ -187,6 +189,12 @@
         return mRequestId;
     }
 
+    /** @hide */
+    @Nullable
+    public int[] getCancelIds() {
+        return mCancelIds;
+    }
+
     /**
      * Builder for {@link FillResponse} objects. You must to provide at least
      * one dataset or set an authentication intent with a presentation view.
@@ -206,6 +214,7 @@
         private int mFlags;
         private boolean mDestroyed;
         private UserData mUserData;
+        private int[] mCancelIds;
 
         /**
          * Triggers a custom UI before before autofilling the screen with any data set in this
@@ -542,6 +551,25 @@
         }
 
         /**
+         * Sets targets with the resources IDs of the child view of
+         * {@link RemoteViews Presentation Template} which will cancel the session when clicked.
+         * Those targets will be respectively applied to a child of the header, footer and
+         * each {@link Dataset}.
+         *
+         * @param ids array of the resource id. Empty list or non-existing id has no effect.
+         *
+         * @return this builder
+         *
+         * @throws IllegalStateException if {@link #build()} was already called.
+         */
+        @NonNull
+        public Builder setCancelTargetIds(@Nullable int[] ids) {
+            throwIfDestroyed();
+            mCancelIds = ids;
+            return this;
+        }
+
+        /**
          * Builds a new {@link FillResponse} instance.
          *
          * @throws IllegalStateException if any of the following conditions occur:
@@ -639,6 +667,10 @@
         if (mUserData != null) {
             builder.append(", userData=").append(mUserData);
         }
+        if (mCancelIds != null) {
+            builder.append(", mCancelIds=").append(mCancelIds.length);
+        }
+
         return builder.append("]").toString();
     }
 
@@ -666,6 +698,8 @@
         parcel.writeLong(mDisableDuration);
         parcel.writeParcelableArray(mFieldClassificationIds, flags);
         parcel.writeInt(mFlags);
+        parcel.writeIntArray(mCancelIds);
+
         parcel.writeInt(mRequestId);
     }
 
@@ -718,6 +752,8 @@
                 builder.setFieldClassificationIds(fieldClassifactionIds);
             }
             builder.setFlags(parcel.readInt());
+            final int[] cancelIds = parcel.createIntArray();
+            builder.setCancelTargetIds(cancelIds);
 
             final FillResponse response = builder.build();
             response.setRequestId(parcel.readInt());
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 37b685a..3927ebf 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -69,14 +69,14 @@
     void insetsChanged(in InsetsState insetsState);
 
     /**
-     * Called when this window retrieved control over a specified set of inset sources.
+     * Called when this window retrieved control over a specified set of insets sources.
      */
     void insetsControlChanged(in InsetsState insetsState, in InsetsSourceControl[] activeControls);
 
     /**
      * Called when a set of insets source window should be shown by policy.
      *
-     * @param types internal inset types (WindowInsets.Type.InsetType) to show
+     * @param types internal insets types (WindowInsets.Type.InsetsType) to show
      * @param fromIme true if this request originated from IME (InputMethodService).
      */
     void showInsets(int types, boolean fromIme);
@@ -84,7 +84,7 @@
     /**
      * Called when a set of insets source window should be hidden by policy.
      *
-     * @param types internal inset types (WindowInsets.Type.InsetType) to hide
+     * @param types internal insets types (WindowInsets.Type.InsetsType) to hide
      * @param fromIme true if this request originated from IME (InputMethodService).
      */
     void hideInsets(int types, boolean fromIme);
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index 3bf44ac..d069437 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -16,7 +16,7 @@
 
 package android.view;
 
-import static android.view.InsetsState.TYPE_IME;
+import static android.view.InsetsState.ITYPE_IME;
 
 import android.inputmethodservice.InputMethodService;
 import android.os.Parcel;
@@ -46,7 +46,7 @@
     public ImeInsetsSourceConsumer(
             InsetsState state, Supplier<Transaction> transactionSupplier,
             InsetsController controller) {
-        super(TYPE_IME, state, transactionSupplier, controller);
+        super(ITYPE_IME, state, transactionSupplier, controller);
     }
 
     public void onPreRendered(EditorInfo info) {
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java
index 786dbb0..3d139cd 100644
--- a/core/java/android/view/InsetsAnimationControlImpl.java
+++ b/core/java/android/view/InsetsAnimationControlImpl.java
@@ -16,11 +16,11 @@
 
 package android.view;
 
-import static android.view.InsetsState.INSET_SIDE_BOTTOM;
-import static android.view.InsetsState.INSET_SIDE_FLOATING;
-import static android.view.InsetsState.INSET_SIDE_LEFT;
-import static android.view.InsetsState.INSET_SIDE_RIGHT;
-import static android.view.InsetsState.INSET_SIDE_TOP;
+import static android.view.InsetsState.ISIDE_BOTTOM;
+import static android.view.InsetsState.ISIDE_FLOATING;
+import static android.view.InsetsState.ISIDE_LEFT;
+import static android.view.InsetsState.ISIDE_RIGHT;
+import static android.view.InsetsState.ISIDE_TOP;
 import static android.view.InsetsState.toPublicType;
 
 import android.annotation.Nullable;
@@ -31,9 +31,9 @@
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.util.SparseSetArray;
-import android.view.InsetsState.InsetSide;
+import android.view.InsetsState.InternalInsetsSide;
 import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
-import android.view.WindowInsets.Type.InsetType;
+import android.view.WindowInsets.Type.InsetsType;
 import android.view.WindowInsetsAnimationListener.InsetsAnimation;
 import android.view.WindowManager.LayoutParams;
 
@@ -63,7 +63,7 @@
     private final Insets mShownInsets;
     private final Matrix mTmpMatrix = new Matrix();
     private final InsetsState mInitialInsetsState;
-    private final @InsetType int mTypes;
+    private final @InsetsType int mTypes;
     private final Supplier<SyncRtSurfaceTransactionApplier> mTransactionApplierSupplier;
     private final InsetsController mController;
     private final WindowInsetsAnimationListener.InsetsAnimation mAnimation;
@@ -77,7 +77,7 @@
     @VisibleForTesting
     public InsetsAnimationControlImpl(SparseArray<InsetsSourceConsumer> consumers, Rect frame,
             InsetsState state, WindowInsetsAnimationControlListener listener,
-            @InsetType int types,
+            @InsetsType int types,
             Supplier<SyncRtSurfaceTransactionApplier> transactionApplierSupplier,
             InsetsController controller) {
         mConsumers = consumers;
@@ -118,8 +118,7 @@
     }
 
     @Override
-    @InsetType
-    public int getTypes() {
+    @InsetsType public int getTypes() {
         return mTypes;
     }
 
@@ -147,12 +146,11 @@
         }
         final Insets offset = Insets.subtract(mShownInsets, mPendingInsets);
         ArrayList<SurfaceParams> params = new ArrayList<>();
-        updateLeashesForSide(INSET_SIDE_LEFT, offset.left, mPendingInsets.left, params, state);
-        updateLeashesForSide(INSET_SIDE_TOP, offset.top, mPendingInsets.top, params, state);
-        updateLeashesForSide(INSET_SIDE_RIGHT, offset.right, mPendingInsets.right, params, state);
-        updateLeashesForSide(INSET_SIDE_BOTTOM, offset.bottom, mPendingInsets.bottom, params,
-                state);
-        updateLeashesForSide(INSET_SIDE_FLOATING, 0 /* offset */, 0 /* inset */, params, state);
+        updateLeashesForSide(ISIDE_LEFT, offset.left, mPendingInsets.left, params, state);
+        updateLeashesForSide(ISIDE_TOP, offset.top, mPendingInsets.top, params, state);
+        updateLeashesForSide(ISIDE_RIGHT, offset.right, mPendingInsets.right, params, state);
+        updateLeashesForSide(ISIDE_BOTTOM, offset.bottom, mPendingInsets.bottom, params, state);
+        updateLeashesForSide(ISIDE_FLOATING, 0 /* offset */, 0 /* inset */, params, state);
 
         SyncRtSurfaceTransactionApplier applier = mTransactionApplierSupplier.get();
         applier.scheduleApply(params.toArray(new SurfaceParams[params.size()]));
@@ -195,7 +193,7 @@
 
     private Insets calculateInsets(InsetsState state, Rect frame,
             SparseArray<InsetsSourceConsumer> consumers, boolean shown,
-            @Nullable @InsetSide SparseIntArray typeSideMap) {
+            @Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
         for (int i = consumers.size() - 1; i >= 0; i--) {
             state.getSource(consumers.valueAt(i).getType()).setVisible(shown);
         }
@@ -203,7 +201,7 @@
     }
 
     private Insets getInsetsFromState(InsetsState state, Rect frame,
-            @Nullable @InsetSide SparseIntArray typeSideMap) {
+            @Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
         return state.calculateInsets(frame, false /* isScreenRound */,
                 false /* alwaysConsumerNavBar */, null /* displayCutout */,
                 null /* legacyContentInsets */, null /* legacyStableInsets */,
@@ -215,7 +213,7 @@
         return Insets.max(Insets.min(insets, mShownInsets), mHiddenInsets);
     }
 
-    private void updateLeashesForSide(@InsetSide int side, int offset, int inset,
+    private void updateLeashesForSide(@InternalInsetsSide int side, int offset, int inset,
             ArrayList<SurfaceParams> surfaceParams, InsetsState state) {
         ArraySet<InsetsSourceConsumer> items = mSideSourceMap.get(side);
         if (items == null) {
@@ -242,27 +240,27 @@
             if (leash != null) {
                 surfaceParams.add(new SurfaceParams(leash, 1f /* alpha */, mTmpMatrix,
                         null /* windowCrop */, 0 /* layer */, 0f /* cornerRadius*/,
-                        side == INSET_SIDE_FLOATING
-                                ? consumer.isVisible() : inset != 0 /* visible */));
+                        side == ISIDE_FLOATING ? consumer.isVisible() : inset != 0 /* visible */));
             }
         }
     }
 
-    private void addTranslationToMatrix(@InsetSide int side, int inset, Matrix m, Rect frame) {
+    private void addTranslationToMatrix(@InternalInsetsSide int side, int inset, Matrix m,
+            Rect frame) {
         switch (side) {
-            case INSET_SIDE_LEFT:
+            case ISIDE_LEFT:
                 m.postTranslate(-inset, 0);
                 frame.offset(-inset, 0);
                 break;
-            case INSET_SIDE_TOP:
+            case ISIDE_TOP:
                 m.postTranslate(0, -inset);
                 frame.offset(0, -inset);
                 break;
-            case INSET_SIDE_RIGHT:
+            case ISIDE_RIGHT:
                 m.postTranslate(inset, 0);
                 frame.offset(inset, 0);
                 break;
-            case INSET_SIDE_BOTTOM:
+            case ISIDE_BOTTOM:
                 m.postTranslate(0, inset);
                 frame.offset(0, inset);
                 break;
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index eca6dcb..3c93bb7 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -16,7 +16,7 @@
 
 package android.view;
 
-import static android.view.InsetsState.TYPE_IME;
+import static android.view.InsetsState.ITYPE_IME;
 import static android.view.InsetsState.toPublicType;
 import static android.view.WindowInsets.Type.all;
 
@@ -35,10 +35,10 @@
 import android.util.Property;
 import android.util.SparseArray;
 import android.view.InsetsSourceConsumer.ShowResult;
-import android.view.InsetsState.InternalInsetType;
+import android.view.InsetsState.InternalInsetsType;
 import android.view.SurfaceControl.Transaction;
 import android.view.WindowInsets.Type;
-import android.view.WindowInsets.Type.InsetType;
+import android.view.WindowInsets.Type.InsetsType;
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 
@@ -220,11 +220,11 @@
     }
 
     @Override
-    public void show(@InsetType int types) {
+    public void show(@InsetsType int types) {
         show(types, false /* fromIme */);
     }
 
-    void show(@InsetType int types, boolean fromIme) {
+    void show(@InsetsType int types, boolean fromIme) {
         // TODO: Support a ResultReceiver for IME.
         // TODO(b/123718661): Make show() work for multi-session IME.
         int typesReady = 0;
@@ -232,7 +232,7 @@
         for (int i = internalTypes.size() - 1; i >= 0; i--) {
             InsetsSourceConsumer consumer = getSourceConsumer(internalTypes.valueAt(i));
             if (mAnimationDirection == DIRECTION_HIDE) {
-                // Only one animator (with multiple InsetType) can run at a time.
+                // Only one animator (with multiple InsetsType) can run at a time.
                 // previous one should be cancelled for simplicity.
                 cancelExistingAnimation();
             } else if (consumer.isVisible()
@@ -250,11 +250,11 @@
     }
 
     @Override
-    public void hide(@InsetType int types) {
+    public void hide(@InsetsType int types) {
         hide(types, false /* fromIme */);
     }
 
-    void hide(@InsetType int types, boolean fromIme) {
+    void hide(@InsetsType int types, boolean fromIme) {
         int typesReady = 0;
         final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
         for (int i = internalTypes.size() - 1; i >= 0; i--) {
@@ -273,12 +273,12 @@
     }
 
     @Override
-    public void controlWindowInsetsAnimation(@InsetType int types,
+    public void controlWindowInsetsAnimation(@InsetsType int types,
             WindowInsetsAnimationControlListener listener) {
         controlWindowInsetsAnimation(types, listener, false /* fromIme */);
     }
 
-    private void controlWindowInsetsAnimation(@InsetType int types,
+    private void controlWindowInsetsAnimation(@InsetsType int types,
             WindowInsetsAnimationControlListener listener, boolean fromIme) {
         // If the frame of our window doesn't span the entire display, the control API makes very
         // little sense, as we don't deal with negative insets. So just cancel immediately.
@@ -289,7 +289,7 @@
         controlAnimationUnchecked(types, listener, mFrame, fromIme);
     }
 
-    private void controlAnimationUnchecked(@InsetType int types,
+    private void controlAnimationUnchecked(@InsetsType int types,
             WindowInsetsAnimationControlListener listener, Rect frame, boolean fromIme) {
         if (types == 0) {
             // nothing to animate.
@@ -350,7 +350,7 @@
                         // with animation of other types.
                         if (mPendingTypesToShow != 0) {
                             // remove IME from pending because view no longer has focus.
-                            mPendingTypesToShow &= ~InsetsState.toPublicType(TYPE_IME);
+                            mPendingTypesToShow &= ~InsetsState.toPublicType(ITYPE_IME);
                         }
                         break;
                 }
@@ -368,7 +368,7 @@
         return new Pair<>(typesReady, isReady);
     }
 
-    private int collectPendingConsumers(@InsetType int typesReady,
+    private int collectPendingConsumers(@InsetsType int typesReady,
             SparseArray<InsetsSourceConsumer> consumers) {
         if (mPendingTypesToShow != 0) {
             typesReady |= mPendingTypesToShow;
@@ -382,7 +382,7 @@
         return typesReady;
     }
 
-    private void cancelExistingControllers(@InsetType int types) {
+    private void cancelExistingControllers(@InsetsType int types) {
         for (int i = mAnimationControls.size() - 1; i >= 0; i--) {
             InsetsAnimationControlImpl control = mAnimationControls.get(i);
             if ((control.getTypes() & types) != 0) {
@@ -420,7 +420,7 @@
     }
 
     @VisibleForTesting
-    public @NonNull InsetsSourceConsumer getSourceConsumer(@InternalInsetType int type) {
+    public @NonNull InsetsSourceConsumer getSourceConsumer(@InternalInsetsType int type) {
         InsetsSourceConsumer controller = mSourceConsumers.get(type);
         if (controller != null) {
             return controller;
@@ -440,14 +440,14 @@
      * Called when current window gains focus.
      */
     public void onWindowFocusGained() {
-        getSourceConsumer(TYPE_IME).onWindowFocusGained();
+        getSourceConsumer(ITYPE_IME).onWindowFocusGained();
     }
 
     /**
      * Called when current window loses focus.
      */
     public void onWindowFocusLost() {
-        getSourceConsumer(TYPE_IME).onWindowFocusLost();
+        getSourceConsumer(ITYPE_IME).onWindowFocusLost();
     }
 
     ViewRootImpl getViewRoot() {
@@ -468,7 +468,7 @@
     }
 
     private InsetsSourceConsumer createConsumerOfType(int type) {
-        if (type == TYPE_IME) {
+        if (type == ITYPE_IME) {
             return new ImeInsetsSourceConsumer(mState, Transaction::new, this);
         } else {
             return new InsetsSourceConsumer(type, mState, Transaction::new, this);
@@ -495,7 +495,7 @@
         }
     }
 
-    private void applyAnimation(@InsetType final int types, boolean show, boolean fromIme) {
+    private void applyAnimation(@InsetsType final int types, boolean show, boolean fromIme) {
         if (types == 0) {
             // nothing to animate.
             return;
@@ -554,14 +554,14 @@
         controlAnimationUnchecked(types, listener, mState.getDisplayFrame(), fromIme);
     }
 
-    private void hideDirectly(@InsetType int types) {
+    private void hideDirectly(@InsetsType int types) {
         final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
         for (int i = internalTypes.size() - 1; i >= 0; i--) {
             getSourceConsumer(internalTypes.valueAt(i)).hide();
         }
     }
 
-    private void showDirectly(@InsetType int types) {
+    private void showDirectly(@InsetsType int types) {
         final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
         for (int i = internalTypes.size() - 1; i >= 0; i--) {
             getSourceConsumer(internalTypes.valueAt(i)).show();
@@ -569,7 +569,7 @@
     }
 
     /**
-     * Cancel on-going animation to show/hide {@link InsetType}.
+     * Cancel on-going animation to show/hide {@link InsetsType}.
      */
     @VisibleForTesting
     public void cancelExistingAnimation() {
diff --git a/core/java/android/view/InsetsFlags.java b/core/java/android/view/InsetsFlags.java
index 6e459b2..385b0bf 100644
--- a/core/java/android/view/InsetsFlags.java
+++ b/core/java/android/view/InsetsFlags.java
@@ -23,11 +23,11 @@
 import static android.view.View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
 import static android.view.View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
 import static android.view.View.SYSTEM_UI_FLAG_LOW_PROFILE;
-import static android.view.WindowInsetsController.APPEARANCE_LIGHT_SIDE_BARS;
-import static android.view.WindowInsetsController.APPEARANCE_LIGHT_TOP_BAR;
+import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
 import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
-import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_SIDE_BARS;
-import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_TOP_BAR;
+import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_NAVIGATION_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_STATUS_BARS;
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE;
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
 
@@ -43,25 +43,25 @@
 
     @ViewDebug.ExportedProperty(flagMapping = {
             @ViewDebug.FlagToString(
-                    mask = APPEARANCE_OPAQUE_TOP_BAR,
-                    equals = APPEARANCE_OPAQUE_TOP_BAR,
-                    name = "OPAQUE_TOP_BAR"),
+                    mask = APPEARANCE_OPAQUE_STATUS_BARS,
+                    equals = APPEARANCE_OPAQUE_STATUS_BARS,
+                    name = "OPAQUE_STATUS_BARS"),
             @ViewDebug.FlagToString(
-                    mask = APPEARANCE_OPAQUE_SIDE_BARS,
-                    equals = APPEARANCE_OPAQUE_SIDE_BARS,
-                    name = "OPAQUE_SIDE_BARS"),
+                    mask = APPEARANCE_OPAQUE_NAVIGATION_BARS,
+                    equals = APPEARANCE_OPAQUE_NAVIGATION_BARS,
+                    name = "OPAQUE_NAVIGATION_BARS"),
             @ViewDebug.FlagToString(
                     mask = APPEARANCE_LOW_PROFILE_BARS,
                     equals = APPEARANCE_LOW_PROFILE_BARS,
                     name = "LOW_PROFILE_BARS"),
             @ViewDebug.FlagToString(
-                    mask = APPEARANCE_LIGHT_TOP_BAR,
-                    equals = APPEARANCE_LIGHT_TOP_BAR,
-                    name = "LIGHT_TOP_BAR"),
+                    mask = APPEARANCE_LIGHT_STATUS_BARS,
+                    equals = APPEARANCE_LIGHT_STATUS_BARS,
+                    name = "LIGHT_STATUS_BARS"),
             @ViewDebug.FlagToString(
-                    mask = APPEARANCE_LIGHT_SIDE_BARS,
-                    equals = APPEARANCE_LIGHT_SIDE_BARS,
-                    name = "LIGHT_SIDE_BARS")
+                    mask = APPEARANCE_LIGHT_NAVIGATION_BARS,
+                    equals = APPEARANCE_LIGHT_NAVIGATION_BARS,
+                    name = "LIGHT_NAVIGATION_BARS")
     })
     public @Appearance int appearance;
 
@@ -88,14 +88,14 @@
         appearance |= convertFlag(systemUiVisibility, SYSTEM_UI_FLAG_LOW_PROFILE,
                 APPEARANCE_LOW_PROFILE_BARS);
         appearance |= convertFlag(systemUiVisibility, SYSTEM_UI_FLAG_LIGHT_STATUS_BAR,
-                APPEARANCE_LIGHT_TOP_BAR);
+                APPEARANCE_LIGHT_STATUS_BARS);
         appearance |= convertFlag(systemUiVisibility, SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR,
-                APPEARANCE_LIGHT_SIDE_BARS);
+                APPEARANCE_LIGHT_NAVIGATION_BARS);
         appearance |= convertNoFlag(systemUiVisibility,
-                STATUS_BAR_TRANSLUCENT | STATUS_BAR_TRANSPARENT, APPEARANCE_OPAQUE_TOP_BAR);
+                STATUS_BAR_TRANSLUCENT | STATUS_BAR_TRANSPARENT, APPEARANCE_OPAQUE_STATUS_BARS);
         appearance |= convertNoFlag(systemUiVisibility,
                 NAVIGATION_BAR_TRANSLUCENT | NAVIGATION_BAR_TRANSPARENT,
-                APPEARANCE_OPAQUE_SIDE_BARS);
+                APPEARANCE_OPAQUE_NAVIGATION_BARS);
         return appearance;
     }
 
diff --git a/core/java/android/view/InsetsSource.java b/core/java/android/view/InsetsSource.java
index 16e00da..1a33ea9 100644
--- a/core/java/android/view/InsetsSource.java
+++ b/core/java/android/view/InsetsSource.java
@@ -20,7 +20,7 @@
 import android.graphics.Rect;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.view.InsetsState.InternalInsetType;
+import android.view.InsetsState.InternalInsetsType;
 
 import java.io.PrintWriter;
 
@@ -30,7 +30,7 @@
  */
 public class InsetsSource implements Parcelable {
 
-    private final @InternalInsetType int mType;
+    private final @InternalInsetsType int mType;
 
     /** Frame of the source in screen coordinate space */
     private final Rect mFrame;
@@ -38,7 +38,7 @@
 
     private final Rect mTmpFrame = new Rect();
 
-    public InsetsSource(@InternalInsetType int type) {
+    public InsetsSource(@InternalInsetsType int type) {
         mType = type;
         mFrame = new Rect();
     }
@@ -57,7 +57,7 @@
         mVisible = visible;
     }
 
-    public @InternalInsetType int getType() {
+    public @InternalInsetsType int getType() {
         return mType;
     }
 
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 08d45a7..b1caf18 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -18,7 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.Nullable;
-import android.view.InsetsState.InternalInsetType;
+import android.view.InsetsState.InternalInsetsType;
 import android.view.SurfaceControl.Transaction;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -55,12 +55,12 @@
     protected final InsetsController mController;
     protected boolean mVisible;
     private final Supplier<Transaction> mTransactionSupplier;
-    private final @InternalInsetType int mType;
+    private final @InternalInsetsType int mType;
     private final InsetsState mState;
     private @Nullable InsetsSourceControl mSourceControl;
     private boolean mHasWindowFocus;
 
-    public InsetsSourceConsumer(@InternalInsetType int type, InsetsState state,
+    public InsetsSourceConsumer(@InternalInsetsType int type, InsetsState state,
             Supplier<Transaction> transactionSupplier, InsetsController controller) {
         mType = type;
         mState = state;
diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java
index 4919074..bcf5c78 100644
--- a/core/java/android/view/InsetsSourceControl.java
+++ b/core/java/android/view/InsetsSourceControl.java
@@ -20,7 +20,7 @@
 import android.graphics.Point;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.view.InsetsState.InternalInsetType;
+import android.view.InsetsState.InternalInsetsType;
 
 /**
  * Represents a parcelable object to allow controlling a single {@link InsetsSource}.
@@ -28,11 +28,11 @@
  */
 public class InsetsSourceControl implements Parcelable {
 
-    private final @InternalInsetType int mType;
+    private final @InternalInsetsType int mType;
     private final @Nullable SurfaceControl mLeash;
     private final Point mSurfacePosition;
 
-    public InsetsSourceControl(@InternalInsetType int type, @Nullable SurfaceControl leash,
+    public InsetsSourceControl(@InternalInsetsType int type, @Nullable SurfaceControl leash,
             Point surfacePosition) {
         mType = type;
         mLeash = leash;
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index e9de3f0..e3fed3a 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -34,7 +34,7 @@
 import android.util.ArraySet;
 import android.util.SparseIntArray;
 import android.view.WindowInsets.Type;
-import android.view.WindowInsets.Type.InsetType;
+import android.view.WindowInsets.Type.InsetsType;
 import android.view.WindowManager.LayoutParams;
 
 import java.io.PrintWriter;
@@ -54,71 +54,59 @@
      * at the same time.
      */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = "TYPE", value = {
-            TYPE_TOP_BAR,
-            TYPE_SIDE_BAR_1,
-            TYPE_SIDE_BAR_2,
-            TYPE_SIDE_BAR_3,
-            TYPE_TOP_GESTURES,
-            TYPE_BOTTOM_GESTURES,
-            TYPE_LEFT_GESTURES,
-            TYPE_RIGHT_GESTURES,
-            TYPE_TOP_TAPPABLE_ELEMENT,
-            TYPE_BOTTOM_TAPPABLE_ELEMENT,
-            TYPE_IME
+    @IntDef(prefix = "ITYPE", value = {
+            ITYPE_STATUS_BAR,
+            ITYPE_NAVIGATION_BAR,
+            ITYPE_CAPTION_BAR,
+            ITYPE_TOP_GESTURES,
+            ITYPE_BOTTOM_GESTURES,
+            ITYPE_LEFT_GESTURES,
+            ITYPE_RIGHT_GESTURES,
+            ITYPE_TOP_TAPPABLE_ELEMENT,
+            ITYPE_BOTTOM_TAPPABLE_ELEMENT,
+            ITYPE_IME
     })
-    public @interface InternalInsetType {}
+    public @interface InternalInsetsType {}
 
     static final int FIRST_TYPE = 0;
 
-    /** Top bar. Can be status bar or caption in freeform windowing mode. */
-    public static final int TYPE_TOP_BAR = FIRST_TYPE;
+    public static final int ITYPE_STATUS_BAR = FIRST_TYPE;
+    public static final int ITYPE_NAVIGATION_BAR = 1;
+    public static final int ITYPE_CAPTION_BAR = 2;
 
-    /**
-     * Up to 3 side bars that appear on left/right/bottom. On phones there is only one side bar
-     * (the navigation bar, see {@link #TYPE_NAVIGATION_BAR}), but other form factors might have
-     * multiple, like Android Auto.
-     */
-    public static final int TYPE_SIDE_BAR_1 = 1;
-    public static final int TYPE_SIDE_BAR_2 = 2;
-    public static final int TYPE_SIDE_BAR_3 = 3;
-
-    public static final int TYPE_TOP_GESTURES = 4;
-    public static final int TYPE_BOTTOM_GESTURES = 5;
-    public static final int TYPE_LEFT_GESTURES = 6;
-    public static final int TYPE_RIGHT_GESTURES = 7;
-    public static final int TYPE_TOP_TAPPABLE_ELEMENT = 8;
-    public static final int TYPE_BOTTOM_TAPPABLE_ELEMENT = 9;
+    public static final int ITYPE_TOP_GESTURES = 3;
+    public static final int ITYPE_BOTTOM_GESTURES = 4;
+    public static final int ITYPE_LEFT_GESTURES = 5;
+    public static final int ITYPE_RIGHT_GESTURES = 6;
+    public static final int ITYPE_TOP_TAPPABLE_ELEMENT = 7;
+    public static final int ITYPE_BOTTOM_TAPPABLE_ELEMENT = 8;
 
     /** Input method window. */
-    public static final int TYPE_IME = 10;
+    public static final int ITYPE_IME = 9;
 
-    static final int LAST_TYPE = TYPE_IME;
+    static final int LAST_TYPE = ITYPE_IME;
 
     // Derived types
 
-    /** First side bar is navigation bar. */
-    public static final int TYPE_NAVIGATION_BAR = TYPE_SIDE_BAR_1;
-
     /** A shelf is the same as the navigation bar. */
-    public static final int TYPE_SHELF = TYPE_NAVIGATION_BAR;
+    public static final int ITYPE_SHELF = ITYPE_NAVIGATION_BAR;
 
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = "INSET_SIDE", value = {
-            INSET_SIDE_LEFT,
-            INSET_SIDE_TOP,
-            INSET_SIDE_RIGHT,
-            INSET_SIDE_BOTTOM,
-            INSET_SIDE_FLOATING,
-            INSET_SIDE_UNKNWON
+    @IntDef(prefix = "IINSETS_SIDE", value = {
+            ISIDE_LEFT,
+            ISIDE_TOP,
+            ISIDE_RIGHT,
+            ISIDE_BOTTOM,
+            ISIDE_FLOATING,
+            ISIDE_UNKNOWN
     })
-    public @interface InsetSide {}
-    static final int INSET_SIDE_LEFT = 0;
-    static final int INSET_SIDE_TOP = 1;
-    static final int INSET_SIDE_RIGHT = 2;
-    static final int INSET_SIDE_BOTTOM = 3;
-    static final int INSET_SIDE_FLOATING = 4;
-    static final int INSET_SIDE_UNKNWON = 5;
+    public @interface InternalInsetsSide {}
+    static final int ISIDE_LEFT = 0;
+    static final int ISIDE_TOP = 1;
+    static final int ISIDE_RIGHT = 2;
+    static final int ISIDE_BOTTOM = 3;
+    static final int ISIDE_FLOATING = 4;
+    static final int ISIDE_UNKNOWN = 5;
 
     private final ArrayMap<Integer, InsetsSource> mSources = new ArrayMap<>();
 
@@ -147,7 +135,7 @@
     public WindowInsets calculateInsets(Rect frame, boolean isScreenRound,
             boolean alwaysConsumeSystemBars, DisplayCutout cutout,
             @Nullable Rect legacyContentInsets, @Nullable Rect legacyStableInsets,
-            int legacySoftInputMode, @Nullable @InsetSide SparseIntArray typeSideMap) {
+            int legacySoftInputMode, @Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
         Insets[] typeInsetsMap = new Insets[Type.SIZE];
         Insets[] typeMaxInsetsMap = new Insets[Type.SIZE];
         boolean[] typeVisibilityMap = new boolean[SIZE];
@@ -165,10 +153,10 @@
             }
 
             boolean skipNonImeInImeMode = ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_IME
-                    && source.getType() != TYPE_IME;
+                    && source.getType() != ITYPE_IME;
             boolean skipSystemBars = ViewRootImpl.sNewInsetsMode != NEW_INSETS_MODE_FULL
-                    && (type == TYPE_TOP_BAR || type == TYPE_NAVIGATION_BAR);
-            boolean skipIme = source.getType() == TYPE_IME
+                    && (type == ITYPE_STATUS_BAR || type == ITYPE_NAVIGATION_BAR);
+            boolean skipIme = source.getType() == ITYPE_IME
                     && (legacySoftInputMode & LayoutParams.SOFT_INPUT_ADJUST_RESIZE) == 0;
             boolean skipLegacyTypes = ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_NONE
                     && (toPublicType(type) & Type.compatSystemInsets()) != 0;
@@ -182,7 +170,7 @@
 
             // IME won't be reported in max insets as the size depends on the EditorInfo of the IME
             // target.
-            if (source.getType() != TYPE_IME) {
+            if (source.getType() != ITYPE_IME) {
                 processSource(source, relativeFrameMax, true /* ignoreVisibility */,
                         typeMaxInsetsMap, null /* typeSideMap */, null /* typeVisibilityMap */);
             }
@@ -192,7 +180,7 @@
     }
 
     private void processSource(InsetsSource source, Rect relativeFrame, boolean ignoreVisibility,
-            Insets[] typeInsetsMap, @Nullable @InsetSide SparseIntArray typeSideMap,
+            Insets[] typeInsetsMap, @Nullable @InternalInsetsSide SparseIntArray typeSideMap,
             @Nullable boolean[] typeVisibilityMap) {
         Insets insets = source.calculateInsets(relativeFrame, ignoreVisibility);
 
@@ -212,7 +200,7 @@
     }
 
     private void processSourceAsPublicType(InsetsSource source, Insets[] typeInsetsMap,
-            @InsetSide @Nullable SparseIntArray typeSideMap,
+            @InternalInsetsSide @Nullable SparseIntArray typeSideMap,
             @Nullable boolean[] typeVisibilityMap, Insets insets, int type) {
         int index = indexOf(type);
         Insets existing = typeInsetsMap[index];
@@ -227,8 +215,8 @@
         }
 
         if (typeSideMap != null) {
-            @InsetSide int insetSide = getInsetSide(insets);
-            if (insetSide != INSET_SIDE_UNKNWON) {
+            @InternalInsetsSide int insetSide = getInsetSide(insets);
+            if (insetSide != ISIDE_UNKNOWN) {
                 typeSideMap.put(source.getType(), insetSide);
             }
         }
@@ -238,26 +226,26 @@
      * Retrieves the side for a certain {@code insets}. It is required that only one field l/t/r/b
      * is set in order that this method returns a meaningful result.
      */
-    private @InsetSide int getInsetSide(Insets insets) {
+    private @InternalInsetsSide int getInsetSide(Insets insets) {
         if (Insets.NONE.equals(insets)) {
-            return INSET_SIDE_FLOATING;
+            return ISIDE_FLOATING;
         }
         if (insets.left != 0) {
-            return INSET_SIDE_LEFT;
+            return ISIDE_LEFT;
         }
         if (insets.top != 0) {
-            return INSET_SIDE_TOP;
+            return ISIDE_TOP;
         }
         if (insets.right != 0) {
-            return INSET_SIDE_RIGHT;
+            return ISIDE_RIGHT;
         }
         if (insets.bottom != 0) {
-            return INSET_SIDE_BOTTOM;
+            return ISIDE_BOTTOM;
         }
-        return INSET_SIDE_UNKNWON;
+        return ISIDE_UNKNOWN;
     }
 
-    public InsetsSource getSource(@InternalInsetType int type) {
+    public InsetsSource getSource(@InternalInsetsType int type) {
         return mSources.computeIfAbsent(type, InsetsSource::new);
     }
 
@@ -273,19 +261,19 @@
      * Modifies the state of this class to exclude a certain type to make it ready for dispatching
      * to the client.
      *
-     * @param type The {@link InternalInsetType} of the source to remove
+     * @param type The {@link InternalInsetsType} of the source to remove
      */
-    public void removeSource(@InternalInsetType int type) {
+    public void removeSource(@InternalInsetsType int type) {
         mSources.remove(type);
     }
 
     /**
      * A shortcut for setting the visibility of the source.
      *
-     * @param type The {@link InternalInsetType} of the source to set the visibility
+     * @param type The {@link InternalInsetsType} of the source to set the visibility
      * @param visible {@code true} for visible
      */
-    public void setSourceVisible(@InternalInsetType int type, boolean visible) {
+    public void setSourceVisible(@InternalInsetsType int type, boolean visible) {
         InsetsSource source = mSources.get(type);
         if (source != null) {
             source.setVisible(visible);
@@ -321,62 +309,53 @@
         return mSources.valueAt(index);
     }
 
-    public static @InternalInsetType ArraySet<Integer> toInternalType(@InsetType int insetTypes) {
+    public static @InternalInsetsType ArraySet<Integer> toInternalType(@InsetsType int types) {
         final ArraySet<Integer> result = new ArraySet<>();
-        if ((insetTypes & Type.TOP_BAR) != 0) {
-            result.add(TYPE_TOP_BAR);
+        if ((types & Type.STATUS_BARS) != 0) {
+            result.add(ITYPE_STATUS_BAR);
         }
-        if ((insetTypes & Type.SIDE_BARS) != 0) {
-            result.add(TYPE_SIDE_BAR_1);
-            result.add(TYPE_SIDE_BAR_2);
-            result.add(TYPE_SIDE_BAR_3);
+        if ((types & Type.NAVIGATION_BARS) != 0) {
+            result.add(ITYPE_NAVIGATION_BAR);
         }
-        if ((insetTypes & Type.IME) != 0) {
-            result.add(TYPE_IME);
+        if ((types & Type.CAPTION_BAR) != 0) {
+            result.add(ITYPE_CAPTION_BAR);
+        }
+        if ((types & Type.IME) != 0) {
+            result.add(ITYPE_IME);
         }
         return result;
     }
 
-    static @InsetType int toPublicType(@InternalInsetType int type) {
+    static @Type.InsetsType int toPublicType(@InternalInsetsType int type) {
         switch (type) {
-            case TYPE_TOP_BAR:
-                return Type.TOP_BAR;
-            case TYPE_SIDE_BAR_1:
-            case TYPE_SIDE_BAR_2:
-            case TYPE_SIDE_BAR_3:
-                return Type.SIDE_BARS;
-            case TYPE_IME:
+            case ITYPE_STATUS_BAR:
+                return Type.STATUS_BARS;
+            case ITYPE_NAVIGATION_BAR:
+                return Type.NAVIGATION_BARS;
+            case ITYPE_CAPTION_BAR:
+                return Type.CAPTION_BAR;
+            case ITYPE_IME:
                 return Type.IME;
-            case TYPE_TOP_GESTURES:
-            case TYPE_BOTTOM_GESTURES:
+            case ITYPE_TOP_GESTURES:
+            case ITYPE_BOTTOM_GESTURES:
                 return Type.MANDATORY_SYSTEM_GESTURES;
-            case TYPE_LEFT_GESTURES:
-            case TYPE_RIGHT_GESTURES:
+            case ITYPE_LEFT_GESTURES:
+            case ITYPE_RIGHT_GESTURES:
                 return Type.SYSTEM_GESTURES;
-            case TYPE_TOP_TAPPABLE_ELEMENT:
-            case TYPE_BOTTOM_TAPPABLE_ELEMENT:
+            case ITYPE_TOP_TAPPABLE_ELEMENT:
+            case ITYPE_BOTTOM_TAPPABLE_ELEMENT:
                 return Type.TAPPABLE_ELEMENT;
             default:
                 throw new IllegalArgumentException("Unknown type: " + type);
         }
     }
 
-    public static boolean getDefaultVisibility(@InsetType int type) {
-        switch (type) {
-            case TYPE_TOP_BAR:
-            case TYPE_SIDE_BAR_1:
-            case TYPE_SIDE_BAR_2:
-            case TYPE_SIDE_BAR_3:
-                return true;
-            case TYPE_IME:
-                return false;
-            default:
-                return true;
-        }
+    public static boolean getDefaultVisibility(@InsetsType int type) {
+        return type != ITYPE_IME;
     }
 
-    public static boolean containsType(@InternalInsetType int[] types,
-            @InternalInsetType int type) {
+    public static boolean containsType(@InternalInsetsType int[] types,
+            @InternalInsetsType int type) {
         if (types == null) {
             return false;
         }
@@ -395,30 +374,30 @@
         }
     }
 
-    public static String typeToString(@InternalInsetType int type) {
+    public static String typeToString(@InternalInsetsType int type) {
         switch (type) {
-            case TYPE_TOP_BAR:
-                return "TYPE_TOP_BAR";
-            case TYPE_SIDE_BAR_1:
-                return "TYPE_SIDE_BAR_1";
-            case TYPE_SIDE_BAR_2:
-                return "TYPE_SIDE_BAR_2";
-            case TYPE_SIDE_BAR_3:
-                return "TYPE_SIDE_BAR_3";
-            case TYPE_TOP_GESTURES:
-                return "TYPE_TOP_GESTURES";
-            case TYPE_BOTTOM_GESTURES:
-                return "TYPE_BOTTOM_GESTURES";
-            case TYPE_LEFT_GESTURES:
-                return "TYPE_LEFT_GESTURES";
-            case TYPE_RIGHT_GESTURES:
-                return "TYPE_RIGHT_GESTURES";
-            case TYPE_TOP_TAPPABLE_ELEMENT:
-                return "TYPE_TOP_TAPPABLE_ELEMENT";
-            case TYPE_BOTTOM_TAPPABLE_ELEMENT:
-                return "TYPE_BOTTOM_TAPPABLE_ELEMENT";
+            case ITYPE_STATUS_BAR:
+                return "ITYPE_STATUS_BAR";
+            case ITYPE_NAVIGATION_BAR:
+                return "ITYPE_NAVIGATION_BAR";
+            case ITYPE_CAPTION_BAR:
+                return "ITYPE_CAPTION_BAR";
+            case ITYPE_TOP_GESTURES:
+                return "ITYPE_TOP_GESTURES";
+            case ITYPE_BOTTOM_GESTURES:
+                return "ITYPE_BOTTOM_GESTURES";
+            case ITYPE_LEFT_GESTURES:
+                return "ITYPE_LEFT_GESTURES";
+            case ITYPE_RIGHT_GESTURES:
+                return "ITYPE_RIGHT_GESTURES";
+            case ITYPE_TOP_TAPPABLE_ELEMENT:
+                return "ITYPE_TOP_TAPPABLE_ELEMENT";
+            case ITYPE_BOTTOM_TAPPABLE_ELEMENT:
+                return "ITYPE_BOTTOM_TAPPABLE_ELEMENT";
+            case ITYPE_IME:
+                return "ITYPE_IME";
             default:
-                return "TYPE_UNKNOWN_" + type;
+                return "ITYPE_UNKNOWN_" + type;
         }
     }
 
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 2ea3b63..89b111d 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -93,7 +93,7 @@
 import android.view.View.AttachInfo;
 import android.view.View.FocusDirection;
 import android.view.View.MeasureSpec;
-import android.view.WindowInsets.Type.InsetType;
+import android.view.WindowInsets.Type.InsetsType;
 import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
@@ -7504,11 +7504,11 @@
         mHandler.obtainMessage(MSG_INSETS_CONTROL_CHANGED, args).sendToTarget();
     }
 
-    private void showInsets(@InsetType int types, boolean fromIme) {
+    private void showInsets(@InsetsType int types, boolean fromIme) {
         mHandler.obtainMessage(MSG_SHOW_INSETS, types, fromIme ? 1 : 0).sendToTarget();
     }
 
-    private void hideInsets(@InsetType int types, boolean fromIme) {
+    private void hideInsets(@InsetsType int types, boolean fromIme) {
         mHandler.obtainMessage(MSG_HIDE_INSETS, types, fromIme ? 1 : 0).sendToTarget();
     }
 
@@ -8627,7 +8627,7 @@
         }
 
         @Override
-        public void showInsets(@InsetType int types, boolean fromIme) {
+        public void showInsets(@InsetsType int types, boolean fromIme) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
                 viewAncestor.showInsets(types, fromIme);
@@ -8635,7 +8635,7 @@
         }
 
         @Override
-        public void hideInsets(@InsetType int types, boolean fromIme) {
+        public void hideInsets(@InsetsType int types, boolean fromIme) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
                 viewAncestor.hideInsets(types, fromIme);
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index bcc6a55..57bd5bb 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -21,11 +21,11 @@
 import static android.view.WindowInsets.Type.IME;
 import static android.view.WindowInsets.Type.LAST;
 import static android.view.WindowInsets.Type.MANDATORY_SYSTEM_GESTURES;
-import static android.view.WindowInsets.Type.SIDE_BARS;
+import static android.view.WindowInsets.Type.NAVIGATION_BARS;
 import static android.view.WindowInsets.Type.SIZE;
+import static android.view.WindowInsets.Type.STATUS_BARS;
 import static android.view.WindowInsets.Type.SYSTEM_GESTURES;
 import static android.view.WindowInsets.Type.TAPPABLE_ELEMENT;
-import static android.view.WindowInsets.Type.TOP_BAR;
 import static android.view.WindowInsets.Type.all;
 import static android.view.WindowInsets.Type.compatSystemInsets;
 import static android.view.WindowInsets.Type.indexOf;
@@ -39,7 +39,7 @@
 import android.graphics.Insets;
 import android.graphics.Rect;
 import android.util.SparseArray;
-import android.view.WindowInsets.Type.InsetType;
+import android.view.WindowInsets.Type.InsetsType;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethod;
 
@@ -175,9 +175,9 @@
 
     /**
      * @return The insets that include system bars indicated by {@code typeMask}, taken from
-     *         {@code typeInsetMap}.
+     *         {@code typeInsetsMap}.
      */
-    private static Insets getInsets(Insets[] typeInsetsMap, @InsetType int typeMask) {
+    private static Insets getInsets(Insets[] typeInsetsMap, @InsetsType int typeMask) {
         Insets result = null;
         for (int i = FIRST; i <= LAST; i = i << 1) {
             if ((typeMask & i) == 0) {
@@ -199,7 +199,7 @@
     /**
      * Sets all entries in {@code typeInsetsMap} that belong to {@code typeMask} to {@code insets},
      */
-    private static void setInsets(Insets[] typeInsetsMap, @InsetType int typeMask, Insets insets) {
+    private static void setInsets(Insets[] typeInsetsMap, @InsetsType int typeMask, Insets insets) {
         for (int i = FIRST; i <= LAST; i = i << 1) {
             if ((typeMask & i) == 0) {
                 continue;
@@ -216,34 +216,35 @@
 
     /**
      * Creates a indexOf(type) -> inset map for which the {@code insets} is just mapped to
-     * {@link InsetType#topBar()} and {@link InsetType#sideBars()}, depending on the location of the
-     * inset.
+     * {@link InsetsType#statusBars()} and {@link InsetsType#navigationBars()}, depending on the
+     * location of the inset.
      */
     private static Insets[] createCompatTypeMap(@Nullable Rect insets) {
         if (insets == null) {
             return null;
         }
-        Insets[] typeInsetMap = new Insets[SIZE];
-        assignCompatInsets(typeInsetMap, insets);
-        return typeInsetMap;
+        Insets[] typeInsetsMap = new Insets[SIZE];
+        assignCompatInsets(typeInsetsMap, insets);
+        return typeInsetsMap;
     }
 
     /**
      * @hide
      */
-    static void assignCompatInsets(Insets[] typeInsetMap, Rect insets) {
-        typeInsetMap[indexOf(TOP_BAR)] = Insets.of(0, insets.top, 0, 0);
-        typeInsetMap[indexOf(SIDE_BARS)] = Insets.of(insets.left, 0, insets.right, insets.bottom);
+    static void assignCompatInsets(Insets[] typeInsetsMap, Rect insets) {
+        typeInsetsMap[indexOf(STATUS_BARS)] = Insets.of(0, insets.top, 0, 0);
+        typeInsetsMap[indexOf(NAVIGATION_BARS)] =
+                Insets.of(insets.left, 0, insets.right, insets.bottom);
     }
 
-    private static boolean[] createCompatVisibilityMap(@Nullable Insets[] typeInsetMap) {
+    private static boolean[] createCompatVisibilityMap(@Nullable Insets[] typeInsetsMap) {
         boolean[] typeVisibilityMap = new boolean[SIZE];
-        if (typeInsetMap == null) {
+        if (typeInsetsMap == null) {
             return typeVisibilityMap;
         }
         for (int i = FIRST; i <= LAST; i = i << 1) {
             int index = indexOf(i);
-            if (!Insets.NONE.equals(typeInsetMap[index])) {
+            if (!Insets.NONE.equals(typeInsetsMap[index])) {
                 typeVisibilityMap[index] = true;
             }
         }
@@ -284,20 +285,20 @@
 
     /**
      * Returns the insets of a specific set of windows causing insets, denoted by the
-     * {@code typeMask} bit mask of {@link InsetType}s.
+     * {@code typeMask} bit mask of {@link InsetsType}s.
      *
-     * @param typeMask Bit mask of {@link InsetType}s to query the insets for.
+     * @param typeMask Bit mask of {@link InsetsType}s to query the insets for.
      * @return The insets.
      *
      * @hide pending unhide
      */
-    public Insets getInsets(@InsetType int typeMask) {
+    public Insets getInsets(@InsetsType int typeMask) {
         return getInsets(mTypeInsetsMap, typeMask);
     }
 
     /**
      * Returns the maximum amount of insets a specific set of windows can cause, denoted by the
-     * {@code typeMask} bit mask of {@link InsetType}s.
+     * {@code typeMask} bit mask of {@link InsetsType}s.
      *
      * <p>The maximum insets represents the area of a a window that that <b>may</b> be partially
      * or fully obscured by the system window identified by {@code type}. This value does not
@@ -305,7 +306,7 @@
      * normally shown, but temporarily hidden, the maximum inset will still provide the inset
      * associated with the status bar being shown.</p>
      *
-     * @param typeMask Bit mask of {@link InsetType}s to query the insets for.
+     * @param typeMask Bit mask of {@link InsetsType}s to query the insets for.
      * @return The insets.
      *
      * @throws IllegalArgumentException If the caller tries to query {@link Type#ime()}. Maximum
@@ -314,7 +315,7 @@
      *                                  currently focused view, as well as the UI state of the IME.
      * @hide pending unhide
      */
-    public Insets getMaxInsets(@InsetType int typeMask) throws IllegalArgumentException {
+    public Insets getMaxInsets(@InsetsType int typeMask) throws IllegalArgumentException {
         if ((typeMask & IME) != 0) {
             throw new IllegalArgumentException("Unable to query the maximum insets for IME");
         }
@@ -325,12 +326,12 @@
      * Returns whether a set of windows that may cause insets is currently visible on screen,
      * regardless of whether it actually overlaps with this window.
      *
-     * @param typeMask Bit mask of {@link InsetType}s to query visibility status.
+     * @param typeMask Bit mask of {@link Type.InsetsType}s to query visibility status.
      * @return {@code true} if and only if all windows included in {@code typeMask} are currently
      *         visible on screen.
      * @hide pending unhide
      */
-    public boolean isVisible(@InsetType int typeMask) {
+    public boolean isVisible(@InsetsType int typeMask) {
         for (int i = FIRST; i <= LAST; i = i << 1) {
             if ((typeMask & i) == 0) {
                 continue;
@@ -1010,14 +1011,14 @@
          *
          * @see #getInsets(int)
          *
-         * @param typeMask The bitmask of {@link InsetType} to set the insets for.
+         * @param typeMask The bitmask of {@link InsetsType} to set the insets for.
          * @param insets The insets to set.
          *
          * @return itself
          * @hide pending unhide
          */
         @NonNull
-        public Builder setInsets(@InsetType int typeMask, @NonNull Insets insets) {
+        public Builder setInsets(@InsetsType int typeMask, @NonNull Insets insets) {
             Preconditions.checkNotNull(insets);
             WindowInsets.setInsets(mTypeInsetsMap, typeMask, insets);
             mSystemInsetsConsumed = false;
@@ -1035,7 +1036,7 @@
          *
          * @see #getMaxInsets(int)
          *
-         * @param typeMask The bitmask of {@link InsetType} to set the insets for.
+         * @param typeMask The bitmask of {@link InsetsType} to set the insets for.
          * @param insets The insets to set.
          *
          * @return itself
@@ -1048,7 +1049,7 @@
          * @hide pending unhide
          */
         @NonNull
-        public Builder setMaxInsets(@InsetType int typeMask, @NonNull Insets insets)
+        public Builder setMaxInsets(@InsetsType int typeMask, @NonNull Insets insets)
                 throws IllegalArgumentException{
             if (typeMask == IME) {
                 throw new IllegalArgumentException("Maximum inset not available for IME");
@@ -1065,14 +1066,14 @@
          *
          * @see #isVisible(int)
          *
-         * @param typeMask The bitmask of {@link InsetType} to set the visibility for.
+         * @param typeMask The bitmask of {@link InsetsType} to set the visibility for.
          * @param visible Whether to mark the windows as visible or not.
          *
          * @return itself
          * @hide pending unhide
          */
         @NonNull
-        public Builder setVisible(@InsetType int typeMask, boolean visible) {
+        public Builder setVisible(@InsetsType int typeMask, boolean visible) {
             for (int i = FIRST; i <= LAST; i = i << 1) {
                 if ((typeMask & i) == 0) {
                     continue;
@@ -1149,35 +1150,38 @@
     public static final class Type {
 
         static final int FIRST = 1 << 0;
-        static final int TOP_BAR = FIRST;
+        static final int STATUS_BARS = FIRST;
+        static final int NAVIGATION_BARS = 1 << 1;
+        static final int CAPTION_BAR = 1 << 2;
 
-        static final int IME = 1 << 1;
-        static final int SIDE_BARS = 1 << 2;
+        static final int IME = 1 << 3;
 
-        static final int SYSTEM_GESTURES = 1 << 3;
-        static final int MANDATORY_SYSTEM_GESTURES = 1 << 4;
-        static final int TAPPABLE_ELEMENT = 1 << 5;
+        static final int SYSTEM_GESTURES = 1 << 4;
+        static final int MANDATORY_SYSTEM_GESTURES = 1 << 5;
+        static final int TAPPABLE_ELEMENT = 1 << 6;
 
-        static final int LAST = 1 << 6;
-        static final int SIZE = 7;
+        static final int LAST = 1 << 7;
+        static final int SIZE = 8;
         static final int WINDOW_DECOR = LAST;
 
-        static int indexOf(@InsetType int type) {
+        static int indexOf(@InsetsType int type) {
             switch (type) {
-                case TOP_BAR:
+                case STATUS_BARS:
                     return 0;
-                case IME:
+                case NAVIGATION_BARS:
                     return 1;
-                case SIDE_BARS:
+                case CAPTION_BAR:
                     return 2;
-                case SYSTEM_GESTURES:
+                case IME:
                     return 3;
-                case MANDATORY_SYSTEM_GESTURES:
+                case SYSTEM_GESTURES:
                     return 4;
-                case TAPPABLE_ELEMENT:
+                case MANDATORY_SYSTEM_GESTURES:
                     return 5;
-                case WINDOW_DECOR:
+                case TAPPABLE_ELEMENT:
                     return 6;
+                case WINDOW_DECOR:
+                    return 7;
                 default:
                     throw new IllegalArgumentException("type needs to be >= FIRST and <= LAST,"
                             + " type=" + type);
@@ -1189,42 +1193,48 @@
 
         /** @hide */
         @Retention(RetentionPolicy.SOURCE)
-        @IntDef(flag = true, value = { TOP_BAR, IME, SIDE_BARS, WINDOW_DECOR, SYSTEM_GESTURES,
-                MANDATORY_SYSTEM_GESTURES, TAPPABLE_ELEMENT})
-        public @interface InsetType {
+        @IntDef(flag = true, value = {STATUS_BARS, NAVIGATION_BARS, CAPTION_BAR, IME, WINDOW_DECOR,
+                SYSTEM_GESTURES, MANDATORY_SYSTEM_GESTURES, TAPPABLE_ELEMENT})
+        public @interface InsetsType {
         }
 
         /**
-         * @return An inset type representing the top bar of a window, which can be the status
-         *         bar on handheld-like devices as well as a caption bar.
+         * @return An insets type representing any system bars for displaying status.
          */
-        public static @InsetType int topBar() {
-            return TOP_BAR;
+        public static @InsetsType int statusBars() {
+            return STATUS_BARS;
         }
 
         /**
-         * @return An inset type representing the window of an {@link InputMethod}.
+         * @return An insets type representing any system bars for navigation.
          */
-        public static @InsetType int ime() {
+        public static @InsetsType int navigationBars() {
+            return NAVIGATION_BARS;
+        }
+
+        /**
+         * @return An insets type representing the window of a caption bar.
+         */
+        public static @InsetsType int captionBar() {
+            return CAPTION_BAR;
+        }
+
+        /**
+         * @return An insets type representing the window of an {@link InputMethod}.
+         */
+        public static @InsetsType int ime() {
             return IME;
         }
 
         /**
-         * @return An inset type representing any system bars that are not {@link #topBar()}.
+         * @return An insets type representing decor that is being app-controlled.
          */
-        public static @InsetType int sideBars() {
-            return SIDE_BARS;
-        }
-
-        /**
-         * @return An inset type representing decor that is being app-controlled.
-         */
-        public static @InsetType int windowDecor() {
+        public static @InsetsType int windowDecor() {
             return WINDOW_DECOR;
         }
 
         /**
-         * Returns an inset type representing the system gesture insets.
+         * Returns an insets type representing the system gesture insets.
          *
          * <p>The system gesture insets represent the area of a window where system gestures have
          * priority and may consume some or all touch input, e.g. due to the a system bar
@@ -1240,30 +1250,30 @@
          *
          * @see #getSystemGestureInsets()
          */
-        public static @InsetType int systemGestures() {
+        public static @InsetsType int systemGestures() {
             return SYSTEM_GESTURES;
         }
 
         /**
          * @see #getMandatorySystemGestureInsets
          */
-        public static @InsetType int mandatorySystemGestures() {
+        public static @InsetsType int mandatorySystemGestures() {
             return MANDATORY_SYSTEM_GESTURES;
         }
 
         /**
          * @see #getTappableElementInsets
          */
-        public static @InsetType int tappableElement() {
+        public static @InsetsType int tappableElement() {
             return TAPPABLE_ELEMENT;
         }
 
         /**
-         * @return All system bars. Includes {@link #topBar()} as well as {@link #sideBars()}, but
-         *         not {@link #ime()}.
+         * @return All system bars. Includes {@link #statusBars()} as well as
+         *         {@link #navigationBars()}, but not {@link #ime()}.
          */
-        public static @InsetType int systemBars() {
-            return TOP_BAR | SIDE_BARS;
+        public static @InsetsType int systemBars() {
+            return STATUS_BARS | NAVIGATION_BARS;
         }
 
         /**
@@ -1271,8 +1281,8 @@
          *         system insets.
          * @hide
          */
-        static @InsetType int compatSystemInsets() {
-            return TOP_BAR | SIDE_BARS | IME;
+        static @InsetsType int compatSystemInsets() {
+            return STATUS_BARS | NAVIGATION_BARS | IME;
         }
 
         /**
@@ -1281,7 +1291,7 @@
          * TODO: Figure out if this makes sense at all, mixing e.g {@link #systemGestures()} and
          *       {@link #ime()} does not seem very useful.
          */
-        public static @InsetType int all() {
+        public static @InsetsType int all() {
             return 0xFFFFFFFF;
         }
     }
diff --git a/core/java/android/view/WindowInsetsAnimationControlListener.java b/core/java/android/view/WindowInsetsAnimationControlListener.java
index b27a23d..33fb327 100644
--- a/core/java/android/view/WindowInsetsAnimationControlListener.java
+++ b/core/java/android/view/WindowInsetsAnimationControlListener.java
@@ -17,7 +17,7 @@
 package android.view;
 
 import android.annotation.NonNull;
-import android.view.WindowInsets.Type.InsetType;
+import android.view.WindowInsets.Type.InsetsType;
 import android.view.inputmethod.EditorInfo;
 
 /**
@@ -32,13 +32,13 @@
      * window is starting up.
      *
      * @param controller The controller to control the inset animation.
-     * @param types The {@link InsetType}s it was able to gain control over. Note that this may be
+     * @param types The {@link InsetsType}s it was able to gain control over. Note that this may be
      *              different than the types passed into
      *              {@link WindowInsetsController#controlWindowInsetsAnimation} in case the window
      *              wasn't able to gain the controls because it wasn't the IME target or not
      *              currently the window that's controlling the system bars.
      */
-    void onReady(@NonNull WindowInsetsAnimationController controller, @InsetType int types);
+    void onReady(@NonNull WindowInsetsAnimationController controller, @InsetsType int types);
 
     /**
      * Called when the window no longer has control over the requested types. If it loses control
diff --git a/core/java/android/view/WindowInsetsAnimationController.java b/core/java/android/view/WindowInsetsAnimationController.java
index cf4415d..5cbf3b8 100644
--- a/core/java/android/view/WindowInsetsAnimationController.java
+++ b/core/java/android/view/WindowInsetsAnimationController.java
@@ -18,7 +18,7 @@
 
 import android.annotation.NonNull;
 import android.graphics.Insets;
-import android.view.WindowInsets.Type.InsetType;
+import android.view.WindowInsets.Type.InsetsType;
 import android.view.WindowInsetsAnimationListener.InsetsAnimation;
 
 /**
@@ -60,9 +60,9 @@
     @NonNull Insets getCurrentInsets();
 
     /**
-     * @return The {@link InsetType}s this object is currently controlling.
+     * @return The {@link InsetsType}s this object is currently controlling.
      */
-    @InsetType int getTypes();
+    @InsetsType int getTypes();
 
     /**
      * Modifies the insets by indirectly moving the windows around in the system that are causing
@@ -94,5 +94,5 @@
      * @param shownTypes The list of windows causing insets that should remain shown after finishing
      *                   the animation.
      */
-    void finish(@InsetType int shownTypes);
+    void finish(@InsetsType int shownTypes);
 }
diff --git a/core/java/android/view/WindowInsetsAnimationListener.java b/core/java/android/view/WindowInsetsAnimationListener.java
index 682ab5b..f734b4b 100644
--- a/core/java/android/view/WindowInsetsAnimationListener.java
+++ b/core/java/android/view/WindowInsetsAnimationListener.java
@@ -61,7 +61,7 @@
      */
     class InsetsAnimation {
 
-        private final @WindowInsets.Type.InsetType int mTypeMask;
+        private final @WindowInsets.Type.InsetsType int mTypeMask;
         private final Insets mLowerBound;
         private final Insets mUpperBound;
 
@@ -75,9 +75,9 @@
         }
 
         /**
-         * @return The bitmask of {@link WindowInsets.Type.InsetType}s that are animating.
+         * @return The bitmask of {@link WindowInsets.Type.InsetsType}s that are animating.
          */
-        public @WindowInsets.Type.InsetType int getTypeMask() {
+        public @WindowInsets.Type.InsetsType int getTypeMask() {
             return mTypeMask;
         }
 
diff --git a/core/java/android/view/WindowInsetsController.java b/core/java/android/view/WindowInsetsController.java
index b415319..39e2e73 100644
--- a/core/java/android/view/WindowInsetsController.java
+++ b/core/java/android/view/WindowInsetsController.java
@@ -21,7 +21,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.graphics.Insets;
-import android.view.WindowInsets.Type.InsetType;
+import android.view.WindowInsets.Type.InsetsType;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -35,16 +35,16 @@
 public interface WindowInsetsController {
 
     /**
-     * Makes the top bars become opaque with solid dark background and light foreground.
+     * Makes status bars become opaque with solid dark background and light foreground.
      * @hide
      */
-    int APPEARANCE_OPAQUE_TOP_BAR = 1;
+    int APPEARANCE_OPAQUE_STATUS_BARS = 1;
 
     /**
-     * Makes the side bars become opaque with solid dark background and light foreground.
+     * Makes navigation bars become opaque with solid dark background and light foreground.
      * @hide
      */
-    int APPEARANCE_OPAQUE_SIDE_BARS = 1 << 1;
+    int APPEARANCE_OPAQUE_NAVIGATION_BARS = 1 << 1;
 
     /**
      * Makes items on system bars become less noticeable without changing the layout of the bars.
@@ -53,34 +53,35 @@
     int APPEARANCE_LOW_PROFILE_BARS = 1 << 2;
 
     /**
-     * Changes the foreground color for the light top bar so that the items on the bar can be read
+     * Changes the foreground color for light status bars so that the items on the bar can be read
      * clearly.
      */
-    int APPEARANCE_LIGHT_TOP_BAR = 1 << 3;
+    int APPEARANCE_LIGHT_STATUS_BARS = 1 << 3;
 
     /**
-     * Changes the foreground color for the light side bars so that the items on the bar can be read
-     * clearly.
+     * Changes the foreground color for light navigation bars so that the items on the bar can be
+     * read clearly.
      */
-    int APPEARANCE_LIGHT_SIDE_BARS = 1 << 4;
+    int APPEARANCE_LIGHT_NAVIGATION_BARS = 1 << 4;
 
     /** Determines the appearance of system bars. */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef(flag = true, value = {APPEARANCE_OPAQUE_TOP_BAR, APPEARANCE_OPAQUE_SIDE_BARS,
-            APPEARANCE_LOW_PROFILE_BARS, APPEARANCE_LIGHT_TOP_BAR, APPEARANCE_LIGHT_SIDE_BARS})
+    @IntDef(flag = true, value = {APPEARANCE_OPAQUE_STATUS_BARS, APPEARANCE_OPAQUE_NAVIGATION_BARS,
+            APPEARANCE_LOW_PROFILE_BARS, APPEARANCE_LIGHT_STATUS_BARS,
+            APPEARANCE_LIGHT_NAVIGATION_BARS})
     @interface Appearance {
     }
 
     /**
-     * The default option for {@link #setSystemBarsBehavior(int)}. The side bars will be forcibly
-     * shown by the system on any user interaction on the corresponding display if the side bars are
-     * hidden by {@link #hide(int)} or {@link WindowInsetsAnimationController#changeInsets(Insets)}.
+     * The default option for {@link #setSystemBarsBehavior(int)}. System bars will be forcibly
+     * shown on any user interaction on the corresponding display if navigation bars are hidden by
+     * {@link #hide(int)} or {@link WindowInsetsAnimationController#changeInsets(Insets)}.
      */
-    int BEHAVIOR_SHOW_SIDE_BARS_BY_TOUCH = 0;
+    int BEHAVIOR_SHOW_BARS_BY_TOUCH = 0;
 
     /**
      * Option for {@link #setSystemBarsBehavior(int)}: Window would like to remain interactive when
-     * hiding the side bars by calling {@link #hide(int)} or
+     * hiding navigation bars by calling {@link #hide(int)} or
      * {@link WindowInsetsAnimationController#changeInsets(Insets)}.
      *
      * <p>When system bars are hidden in this mode, they can be revealed with system gestures, such
@@ -90,7 +91,7 @@
 
     /**
      * Option for {@link #setSystemBarsBehavior(int)}: Window would like to remain interactive when
-     * hiding the side bars by calling {@link #hide(int)} or
+     * hiding navigation bars by calling {@link #hide(int)} or
      * {@link WindowInsetsAnimationController#changeInsets(Insets)}.
      *
      * <p>When system bars are hidden in this mode, they can be revealed temporarily with system
@@ -102,7 +103,7 @@
 
     /** Determines the behavior of system bars when hiding them by calling {@link #hide}. */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {BEHAVIOR_SHOW_SIDE_BARS_BY_TOUCH, BEHAVIOR_SHOW_BARS_BY_SWIPE,
+    @IntDef(value = {BEHAVIOR_SHOW_BARS_BY_TOUCH, BEHAVIOR_SHOW_BARS_BY_SWIPE,
             BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE})
     @interface Behavior {
     }
@@ -114,11 +115,11 @@
      * change as soon as the window gains control. The app can listen to the event by observing
      * {@link View#onApplyWindowInsets} and checking visibility with {@link WindowInsets#isVisible}.
      *
-     * @param types A bitmask of {@link WindowInsets.Type.InsetType} specifying what windows the app
+     * @param types A bitmask of {@link InsetsType} specifying what windows the app
      *              would like to make appear on screen.
      * @hide
      */
-    void show(@InsetType int types);
+    void show(@InsetsType int types);
 
     /**
      * Makes a set of windows causing insets disappear.
@@ -127,22 +128,22 @@
      * change as soon as the window gains control. The app can listen to the event by observing
      * {@link View#onApplyWindowInsets} and checking visibility with {@link WindowInsets#isVisible}.
      *
-     * @param types A bitmask of {@link WindowInsets.Type.InsetType} specifying what windows the app
+     * @param types A bitmask of {@link InsetsType} specifying what windows the app
      *              would like to make disappear.
      * @hide
      */
-    void hide(@InsetType int types);
+    void hide(@InsetsType int types);
 
     /**
      * Lets the application control window inset animations in a frame-by-frame manner by modifying
      * the position of the windows in the system causing insets directly.
      *
-     * @param types The {@link InsetType}s the application has requested to control.
+     * @param types The {@link InsetsType}s the application has requested to control.
      * @param listener The {@link WindowInsetsAnimationControlListener} that gets called when the
      *                 windows are ready to be controlled, among other callbacks.
      * @hide
      */
-    void controlWindowInsetsAnimation(@InsetType int types,
+    void controlWindowInsetsAnimation(@InsetsType int types,
             @NonNull WindowInsetsAnimationControlListener listener);
 
     /**
diff --git a/core/java/com/android/internal/app/LocaleHelper.java b/core/java/com/android/internal/app/LocaleHelper.java
index aef4dbf..e3d07aa 100644
--- a/core/java/com/android/internal/app/LocaleHelper.java
+++ b/core/java/com/android/internal/app/LocaleHelper.java
@@ -208,7 +208,7 @@
      * @return the maximized Locale instance.
      */
     public static Locale addLikelySubtags(Locale locale) {
-        return libcore.icu.ICU.addLikelySubtags(locale);
+        return ULocale.addLikelySubtags(ULocale.forLocale(locale)).toLocale();
     }
 
     /**
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index c7cdc3b..57bfcac 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -30,7 +30,7 @@
 import android.view.InsetsSourceControl;
 import android.view.InsetsState;
 import android.view.PointerIcon;
-import android.view.WindowInsets.Type.InsetType;
+import android.view.WindowInsets.Type.InsetsType;
 
 import com.android.internal.os.IResultReceiver;
 
@@ -72,15 +72,15 @@
 
     @Override
     public void insetsControlChanged(InsetsState insetsState,
-            InsetsSourceControl[] activeControls) throws RemoteException {
+            InsetsSourceControl[] activeControls) {
     }
 
     @Override
-    public void showInsets(@InsetType int types, boolean fromIme)  throws RemoteException {
+    public void showInsets(@InsetsType int types, boolean fromIme) {
     }
 
     @Override
-    public void hideInsets(@InsetType int types, boolean fromIme)  throws RemoteException {
+    public void hideInsets(@InsetsType int types, boolean fromIme) {
     }
 
     @Override
diff --git a/core/jni/android_os_SystemProperties.cpp b/core/jni/android_os_SystemProperties.cpp
index cfdf26a..7f8bec6 100644
--- a/core/jni/android_os_SystemProperties.cpp
+++ b/core/jni/android_os_SystemProperties.cpp
@@ -17,7 +17,12 @@
 
 #define LOG_TAG "SysPropJNI"
 
+#include <utility>
+#include <optional>
+
 #include "android-base/logging.h"
+#include "android-base/parsebool.h"
+#include "android-base/parseint.h"
 #include "android-base/properties.h"
 #include "utils/misc.h"
 #include <utils/Log.h>
@@ -27,86 +32,171 @@
 #include <nativehelper/ScopedPrimitiveArray.h>
 #include <nativehelper/ScopedUtfChars.h>
 
-namespace android
-{
+#if defined(__BIONIC__)
+# include <sys/system_properties.h>
+#else
+struct prop_info;
+#endif
 
+namespace android {
 namespace {
 
-template <typename T, typename Handler>
-T ConvertKeyAndForward(JNIEnv *env, jstring keyJ, T defJ, Handler handler) {
-    std::string key;
-    {
-        // Scope the String access. If the handler can throw an exception,
-        // releasing the string characters late would trigger an abort.
-        ScopedUtfChars key_utf(env, keyJ);
-        if (key_utf.c_str() == nullptr) {
-            return defJ;
-        }
-        key = key_utf.c_str();  // This will make a copy, but we can't avoid
-                                // with the existing interface in
-                                // android::base.
-    }
-    return handler(key, defJ);
+using android::base::ParseBoolResult;
+
+template<typename Functor>
+void ReadProperty(const prop_info* prop, Functor&& functor)
+{
+#if defined(__BIONIC__)
+    auto thunk = [](void* cookie,
+                    const char* /*name*/,
+                    const char* value,
+                    uint32_t /*serial*/) {
+        std::forward<Functor>(*static_cast<Functor*>(cookie))(value);
+    };
+    __system_property_read_callback(prop, thunk, &functor);
+#else
+    LOG(FATAL) << "fast property access supported only on device";
+#endif
 }
 
-jstring SystemProperties_getSS(JNIEnv *env, jclass clazz, jstring keyJ,
+template<typename Functor>
+void ReadProperty(JNIEnv* env, jstring keyJ, Functor&& functor)
+{
+    ScopedUtfChars key(env, keyJ);
+    if (!key.c_str()) {
+        return;
+    }
+#if defined(__BIONIC__)
+    const prop_info* prop = __system_property_find(key.c_str());
+    if (!prop) {
+        return;
+    }
+    ReadProperty(prop, std::forward<Functor>(functor));
+#else
+    std::forward<Functor>(functor)(
+        android::base::GetProperty(key.c_str(), "").c_str());
+#endif
+}
+
+jstring SystemProperties_getSS(JNIEnv* env, jclass clazz, jstring keyJ,
                                jstring defJ)
 {
-    // Using ConvertKeyAndForward is sub-optimal for copying the key string,
-    // but improves reuse and reasoning over code.
-    auto handler = [&](const std::string& key, jstring defJ) {
-        std::string prop_val = android::base::GetProperty(key, "");
-        if (!prop_val.empty()) {
-            return env->NewStringUTF(prop_val.c_str());
-        };
-        if (defJ != nullptr) {
-            return defJ;
+    jstring ret = defJ;
+    ReadProperty(env, keyJ, [&](const char* value) {
+        if (value[0]) {
+            ret = env->NewStringUTF(value);
         }
-        // This function is specified to never return null (or have an
-        // exception pending).
-        return env->NewStringUTF("");
-    };
-    return ConvertKeyAndForward(env, keyJ, defJ, handler);
-}
-
-jstring SystemProperties_getS(JNIEnv *env, jclass clazz, jstring keyJ)
-{
-    return SystemProperties_getSS(env, clazz, keyJ, nullptr);
+    });
+    if (ret == nullptr && !env->ExceptionCheck()) {
+      ret = env->NewStringUTF("");  // Legacy behavior
+    }
+    return ret;
 }
 
 template <typename T>
 T SystemProperties_get_integral(JNIEnv *env, jclass, jstring keyJ,
                                        T defJ)
 {
-    auto handler = [](const std::string& key, T defV) {
-        return android::base::GetIntProperty<T>(key, defV);
-    };
-    return ConvertKeyAndForward(env, keyJ, defJ, handler);
+    T ret = defJ;
+    ReadProperty(env, keyJ, [&](const char* value) {
+        android::base::ParseInt<T>(value, &ret);
+    });
+    return ret;
+}
+
+static jboolean jbooleanFromParseBoolResult(ParseBoolResult parseResult, jboolean defJ) {
+    jboolean ret;
+    switch (parseResult) {
+        case ParseBoolResult::kError:
+            ret = defJ;
+            break;
+        case ParseBoolResult::kFalse:
+            ret = JNI_FALSE;
+            break;
+        case ParseBoolResult::kTrue:
+            ret = JNI_TRUE;
+            break;
+    }
+    return ret;
 }
 
 jboolean SystemProperties_get_boolean(JNIEnv *env, jclass, jstring keyJ,
                                       jboolean defJ)
 {
-    auto handler = [](const std::string& key, jboolean defV) -> jboolean {
-        bool result = android::base::GetBoolProperty(key, defV);
-        return result ? JNI_TRUE : JNI_FALSE;
-    };
-    return ConvertKeyAndForward(env, keyJ, defJ, handler);
+    ParseBoolResult parseResult;
+    ReadProperty(env, keyJ, [&](const char* value) {
+        parseResult = android::base::ParseBool(value);
+    });
+    return jbooleanFromParseBoolResult(parseResult, defJ);
+}
+
+jlong SystemProperties_find(JNIEnv* env, jclass, jstring keyJ)
+{
+#if defined(__BIONIC__)
+    ScopedUtfChars key(env, keyJ);
+    if (!key.c_str()) {
+        return 0;
+    }
+    const prop_info* prop = __system_property_find(key.c_str());
+    return reinterpret_cast<jlong>(prop);
+#else
+    LOG(FATAL) << "fast property access supported only on device";
+    __builtin_unreachable();  // Silence warning
+#endif
+}
+
+jstring SystemProperties_getH(JNIEnv* env, jclass clazz, jlong propJ)
+{
+    jstring ret;
+    auto prop = reinterpret_cast<const prop_info*>(propJ);
+    ReadProperty(prop, [&](const char* value) {
+        ret = env->NewStringUTF(value);
+    });
+    return ret;
+}
+
+template <typename T>
+T SystemProperties_get_integralH(CRITICAL_JNI_PARAMS_COMMA jlong propJ, T defJ)
+{
+    T ret = defJ;
+    auto prop = reinterpret_cast<const prop_info*>(propJ);
+    ReadProperty(prop, [&](const char* value) {
+        android::base::ParseInt<T>(value, &ret);
+    });
+    return ret;
+}
+
+jboolean SystemProperties_get_booleanH(CRITICAL_JNI_PARAMS_COMMA jlong propJ, jboolean defJ)
+{
+    ParseBoolResult parseResult;
+    auto prop = reinterpret_cast<const prop_info*>(propJ);
+    ReadProperty(prop, [&](const char* value) {
+        parseResult = android::base::ParseBool(value);
+    });
+    return jbooleanFromParseBoolResult(parseResult, defJ);
 }
 
 void SystemProperties_set(JNIEnv *env, jobject clazz, jstring keyJ,
                           jstring valJ)
 {
-    auto handler = [&](const std::string& key, bool) {
-        std::string val;
-        if (valJ != nullptr) {
-            ScopedUtfChars key_utf(env, valJ);
-            val = key_utf.c_str();
+    ScopedUtfChars key(env, keyJ);
+    if (!key.c_str()) {
+        return;
+    }
+    std::optional<ScopedUtfChars> value;
+    if (valJ != nullptr) {
+        value.emplace(env, valJ);
+        if (!value->c_str()) {
+            return;
         }
-        return android::base::SetProperty(key, val);
-    };
-    if (!ConvertKeyAndForward(env, keyJ, true, handler)) {
-        // Must have been a failure in SetProperty.
+    }
+    bool success;
+#if defined(__BIONIC__)
+    success = !__system_property_set(key.c_str(), value ? value->c_str() : "");
+#else
+    success = android::base::SetProperty(key.c_str(), value ? value->c_str() : "");
+#endif
+    if (!success) {
         jniThrowException(env, "java/lang/RuntimeException",
                           "failed to set system property (check logcat for reason)");
     }
@@ -156,8 +246,6 @@
 int register_android_os_SystemProperties(JNIEnv *env)
 {
     const JNINativeMethod method_table[] = {
-        { "native_get", "(Ljava/lang/String;)Ljava/lang/String;",
-          (void*) SystemProperties_getS },
         { "native_get",
           "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
           (void*) SystemProperties_getSS },
@@ -167,6 +255,18 @@
           (void*) SystemProperties_get_integral<jlong> },
         { "native_get_boolean", "(Ljava/lang/String;Z)Z",
           (void*) SystemProperties_get_boolean },
+        { "native_find",
+          "(Ljava/lang/String;)J",
+          (void*) SystemProperties_find },
+        { "native_get",
+          "(J)Ljava/lang/String;",
+          (void*) SystemProperties_getH },
+        { "native_get_int", "(JI)I",
+          (void*) SystemProperties_get_integralH<jint> },
+        { "native_get_long", "(JJ)J",
+          (void*) SystemProperties_get_integralH<jlong> },
+        { "native_get_boolean", "(JZ)Z",
+          (void*) SystemProperties_get_booleanH },
         { "native_set", "(Ljava/lang/String;Ljava/lang/String;)V",
           (void*) SystemProperties_set },
         { "native_add_change_callback", "()V",
@@ -178,4 +278,4 @@
                                 method_table, NELEM(method_table));
 }
 
-};
+}  // namespace android
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 898e2f0..6cf9424 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -369,7 +369,7 @@
     ];
 
     // Dropbox entries split by tags.
-    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_data_app_crashes = 3027 [
+    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_data_app_crash = 3027 [
         (section).type = SECTION_DUMPSYS,
         (section).args = "dropbox --proto data_app_crash"
     ];
@@ -384,6 +384,91 @@
         (section).args = "dropbox --proto data_app_native_crash"
     ];
 
+    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_data_app_strictmode = 3030 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "dropbox --proto data_app_strictmode"
+    ];
+
+    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_data_app_wtf = 3031 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "dropbox --proto data_app_wtf"
+    ];
+
+    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_system_app_crash = 3032 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "dropbox --proto system_app_crash"
+    ];
+
+    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_system_app_anr = 3033 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "dropbox --proto system_app_anr"
+    ];
+
+    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_system_app_native_crash = 3034 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "dropbox --proto system_app_native_crash"
+    ];
+
+    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_system_app_strictmode = 3035 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "dropbox --proto system_app_strictmode"
+    ];
+
+    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_system_app_wtf = 3036 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "dropbox --proto system_app_wtf"
+    ];
+
+    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_system_server_crashes = 3037 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "dropbox --proto system_server_crash"
+    ];
+
+    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_system_server_anr = 3038 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "dropbox --proto system_server_anr"
+    ];
+
+    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_system_server_native_crash = 3039 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "dropbox --proto system_server_native_crash"
+    ];
+
+    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_system_server_lowmem= 3040 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "dropbox --proto system_server_lowmem"
+    ];
+
+    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_system_server_strictmode = 3041 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "dropbox --proto system_server_strictmode"
+    ];
+
+    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_system_server_watchdog = 3042 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "dropbox --proto system_server_watchdog"
+    ];
+
+    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_system_server_wtf = 3043 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "dropbox --proto system_server_wtf"
+    ];
+
+    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_system_recovery_log = 3044 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "dropbox --proto SYSTEM_RECOVERY_LOG"
+    ];
+
+    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_system_tombstone = 3045 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "dropbox --proto SYSTEM_TOMBSTONE"
+    ];
+
+    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_subsystem_restart = 3046 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "dropbox --proto SubsystemRestart"
+    ];
+
     // Reserved for OEMs.
     extensions 50000 to 100000;
 }
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 56e8790..1a4a7ce 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -235,7 +235,7 @@
     optional WindowContainerThumbnailProto thumbnail = 6;
     optional bool fills_parent = 7;
     optional bool app_stopped = 8;
-    optional bool hidden_requested = 9;
+    optional bool visible_requested = 9;
     optional bool client_hidden = 10;
     optional bool defer_hiding_client = 11;
     optional bool reported_drawn = 12;
diff --git a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
index 80b1f9c..0e19ca8 100644
--- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
@@ -17,9 +17,9 @@
 package android.view;
 
 import static android.view.ImeInsetsSourceConsumer.areEditorsSimilar;
-import static android.view.InsetsState.TYPE_IME;
-
+import static android.view.InsetsState.ITYPE_IME;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
+
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 
@@ -82,7 +82,7 @@
 
     @Test
     public void testImeVisibility() {
-        final InsetsSourceControl ime = new InsetsSourceControl(TYPE_IME, mLeash, new Point());
+        final InsetsSourceControl ime = new InsetsSourceControl(ITYPE_IME, mLeash, new Point());
         mController.onControlsChanged(new InsetsSourceControl[] { ime });
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
index be2c4e96..1a48260 100644
--- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
+++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
@@ -16,10 +16,10 @@
 
 package android.view;
 
-import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.TYPE_TOP_BAR;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
-import static android.view.WindowInsets.Type.sideBars;
+import static android.view.WindowInsets.Type.navigationBars;
 import static android.view.WindowInsets.Type.systemBars;
 
 import static org.junit.Assert.assertEquals;
@@ -100,21 +100,22 @@
                 .setName("testSurface")
                 .build();
         mInsetsState = new InsetsState();
-        mInsetsState.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 500, 100));
-        mInsetsState.getSource(TYPE_NAVIGATION_BAR).setFrame(new Rect(400, 0, 500, 500));
-        InsetsSourceConsumer topConsumer = new InsetsSourceConsumer(TYPE_TOP_BAR, mInsetsState,
+        mInsetsState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 500, 100));
+        mInsetsState.getSource(ITYPE_NAVIGATION_BAR).setFrame(new Rect(400, 0, 500, 500));
+        InsetsSourceConsumer topConsumer = new InsetsSourceConsumer(ITYPE_STATUS_BAR, mInsetsState,
                 () -> mMockTransaction, mMockController);
-        topConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mTopLeash, new Point(0, 0)));
+        topConsumer.setControl(
+                new InsetsSourceControl(ITYPE_STATUS_BAR, mTopLeash, new Point(0, 0)));
 
-        InsetsSourceConsumer navConsumer = new InsetsSourceConsumer(TYPE_NAVIGATION_BAR,
+        InsetsSourceConsumer navConsumer = new InsetsSourceConsumer(ITYPE_NAVIGATION_BAR,
                 mInsetsState, () -> mMockTransaction, mMockController);
         navConsumer.hide();
-        navConsumer.setControl(new InsetsSourceControl(TYPE_NAVIGATION_BAR, mNavLeash,
+        navConsumer.setControl(new InsetsSourceControl(ITYPE_NAVIGATION_BAR, mNavLeash,
                 new Point(400, 0)));
 
         SparseArray<InsetsSourceConsumer> consumers = new SparseArray<>();
-        consumers.put(TYPE_TOP_BAR, topConsumer);
-        consumers.put(TYPE_NAVIGATION_BAR, navConsumer);
+        consumers.put(ITYPE_STATUS_BAR, topConsumer);
+        consumers.put(ITYPE_NAVIGATION_BAR, navConsumer);
         mController = new InsetsAnimationControlImpl(consumers,
                 new Rect(0, 0, 500, 500), mInsetsState, mMockListener, systemBars(),
                 () -> mMockTransactionApplier, mMockController);
@@ -149,12 +150,12 @@
     @Test
     public void testFinishing() {
         when(mMockController.getState()).thenReturn(mInsetsState);
-        mController.finish(sideBars());
+        mController.finish(navigationBars());
         mController.applyChangeInsets(mInsetsState);
-        assertFalse(mInsetsState.getSource(TYPE_TOP_BAR).isVisible());
-        assertTrue(mInsetsState.getSource(TYPE_NAVIGATION_BAR).isVisible());
+        assertFalse(mInsetsState.getSource(ITYPE_STATUS_BAR).isVisible());
+        assertTrue(mInsetsState.getSource(ITYPE_NAVIGATION_BAR).isVisible());
         assertEquals(Insets.of(0, 0, 100, 0), mController.getCurrentInsets());
-        verify(mMockController).notifyFinished(eq(mController), eq(sideBars()));
+        verify(mMockController).notifyFinished(eq(mController), eq(navigationBars()));
     }
 
     @Test
@@ -166,7 +167,7 @@
         } catch (IllegalStateException ignored) {
         }
         verify(mMockListener).onCancelled();
-        mController.finish(sideBars());
+        mController.finish(navigationBars());
     }
 
     private void assertPosition(Matrix m, Rect original, Rect transformed) {
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index 337663e..e4d8279 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -16,10 +16,10 @@
 
 package android.view;
 
-import static android.view.InsetsState.TYPE_IME;
-import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.TYPE_TOP_BAR;
-import static android.view.WindowInsets.Type.topBar;
+import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
+import static android.view.WindowInsets.Type.statusBars;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 
 import static org.junit.Assert.assertEquals;
@@ -99,28 +99,31 @@
 
     @Test
     public void testControlsChanged() {
-        InsetsSourceControl control = new InsetsSourceControl(TYPE_TOP_BAR, mLeash, new Point());
+        InsetsSourceControl control =
+                new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point());
         mController.onControlsChanged(new InsetsSourceControl[] { control });
         assertEquals(mLeash,
-                mController.getSourceConsumer(TYPE_TOP_BAR).getControl().getLeash());
+                mController.getSourceConsumer(ITYPE_STATUS_BAR).getControl().getLeash());
     }
 
     @Test
     public void testControlsRevoked() {
-        InsetsSourceControl control = new InsetsSourceControl(TYPE_TOP_BAR, mLeash, new Point());
+        InsetsSourceControl control =
+                new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point());
         mController.onControlsChanged(new InsetsSourceControl[] { control });
         mController.onControlsChanged(new InsetsSourceControl[0]);
-        assertNull(mController.getSourceConsumer(TYPE_TOP_BAR).getControl());
+        assertNull(mController.getSourceConsumer(ITYPE_STATUS_BAR).getControl());
     }
 
     @Test
     public void testControlsRevoked_duringAnim() {
-        InsetsSourceControl control = new InsetsSourceControl(TYPE_TOP_BAR, mLeash, new Point());
+        InsetsSourceControl control =
+                new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point());
         mController.onControlsChanged(new InsetsSourceControl[] { control });
 
         WindowInsetsAnimationControlListener mockListener =
                 mock(WindowInsetsAnimationControlListener.class);
-        mController.controlWindowInsetsAnimation(topBar(), mockListener);
+        mController.controlWindowInsetsAnimation(statusBars(), mockListener);
         verify(mockListener).onReady(any(), anyInt());
         mController.onControlsChanged(new InsetsSourceControl[0]);
         verify(mockListener).onCancelled();
@@ -141,47 +144,47 @@
     public void testAnimationEndState() {
         InsetsSourceControl[] controls = prepareControls();
         InsetsSourceControl navBar = controls[0];
-        InsetsSourceControl topBar = controls[1];
+        InsetsSourceControl statusBar = controls[1];
         InsetsSourceControl ime = controls[2];
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            mController.getSourceConsumer(TYPE_IME).onWindowFocusGained();
+            mController.getSourceConsumer(ITYPE_IME).onWindowFocusGained();
             // since there is no focused view, forcefully make IME visible.
             mController.applyImeVisibility(true /* setVisible */);
             mController.show(Type.all());
             // quickly jump to final state by cancelling it.
             mController.cancelExistingAnimation();
             assertTrue(mController.getSourceConsumer(navBar.getType()).isVisible());
-            assertTrue(mController.getSourceConsumer(topBar.getType()).isVisible());
+            assertTrue(mController.getSourceConsumer(statusBar.getType()).isVisible());
             assertTrue(mController.getSourceConsumer(ime.getType()).isVisible());
 
             mController.applyImeVisibility(false /* setVisible */);
             mController.hide(Type.all());
             mController.cancelExistingAnimation();
             assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
-            assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+            assertFalse(mController.getSourceConsumer(statusBar.getType()).isVisible());
             assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
-            mController.getSourceConsumer(TYPE_IME).onWindowFocusLost();
+            mController.getSourceConsumer(ITYPE_IME).onWindowFocusLost();
         });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
     @Test
     public void testApplyImeVisibility() {
-        final InsetsSourceControl ime = new InsetsSourceControl(TYPE_IME, mLeash, new Point());
+        final InsetsSourceControl ime = new InsetsSourceControl(ITYPE_IME, mLeash, new Point());
 
         InsetsSourceControl[] controls = new InsetsSourceControl[3];
         controls[0] = ime;
         mController.onControlsChanged(controls);
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            mController.getSourceConsumer(TYPE_IME).onWindowFocusGained();
+            mController.getSourceConsumer(ITYPE_IME).onWindowFocusGained();
             mController.applyImeVisibility(true);
             mController.cancelExistingAnimation();
             assertTrue(mController.getSourceConsumer(ime.getType()).isVisible());
             mController.applyImeVisibility(false);
             mController.cancelExistingAnimation();
             assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
-            mController.getSourceConsumer(TYPE_IME).onWindowFocusLost();
+            mController.getSourceConsumer(ITYPE_IME).onWindowFocusLost();
         });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
@@ -190,23 +193,23 @@
     public void testShowHideSelectively() {
         InsetsSourceControl[] controls = prepareControls();
         InsetsSourceControl navBar = controls[0];
-        InsetsSourceControl topBar = controls[1];
+        InsetsSourceControl statusBar = controls[1];
         InsetsSourceControl ime = controls[2];
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            int types = Type.sideBars() | Type.systemBars();
+            int types = Type.navigationBars() | Type.systemBars();
             // test show select types.
             mController.show(types);
             mController.cancelExistingAnimation();
             assertTrue(mController.getSourceConsumer(navBar.getType()).isVisible());
-            assertTrue(mController.getSourceConsumer(topBar.getType()).isVisible());
+            assertTrue(mController.getSourceConsumer(statusBar.getType()).isVisible());
             assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
 
             // test hide all
             mController.hide(types);
             mController.cancelExistingAnimation();
             assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
-            assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+            assertFalse(mController.getSourceConsumer(statusBar.getType()).isVisible());
             assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
         });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
@@ -216,36 +219,36 @@
     public void testShowHideSingle() {
         InsetsSourceControl[] controls = prepareControls();
         InsetsSourceControl navBar = controls[0];
-        InsetsSourceControl topBar = controls[1];
+        InsetsSourceControl statusBar = controls[1];
         InsetsSourceControl ime = controls[2];
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            int types = Type.sideBars() | Type.systemBars();
+            int types = Type.navigationBars() | Type.systemBars();
             // test show select types.
             mController.show(types);
             mController.cancelExistingAnimation();
             assertTrue(mController.getSourceConsumer(navBar.getType()).isVisible());
-            assertTrue(mController.getSourceConsumer(topBar.getType()).isVisible());
+            assertTrue(mController.getSourceConsumer(statusBar.getType()).isVisible());
             assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
 
             // test hide all
             mController.hide(Type.all());
             mController.cancelExistingAnimation();
             assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
-            assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+            assertFalse(mController.getSourceConsumer(statusBar.getType()).isVisible());
             assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
 
             // test single show
-            mController.show(Type.sideBars());
+            mController.show(Type.navigationBars());
             mController.cancelExistingAnimation();
             assertTrue(mController.getSourceConsumer(navBar.getType()).isVisible());
-            assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+            assertFalse(mController.getSourceConsumer(statusBar.getType()).isVisible());
             assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
 
             // test single hide
-            mController.hide(Type.sideBars());
+            mController.hide(Type.navigationBars());
             assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
-            assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+            assertFalse(mController.getSourceConsumer(statusBar.getType()).isVisible());
             assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
 
         });
@@ -256,38 +259,38 @@
     public void testShowHideMultiple() {
         InsetsSourceControl[] controls = prepareControls();
         InsetsSourceControl navBar = controls[0];
-        InsetsSourceControl topBar = controls[1];
+        InsetsSourceControl statusBar = controls[1];
         InsetsSourceControl ime = controls[2];
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             // start two animations and see if previous is cancelled and final state is reached.
-            mController.show(Type.sideBars());
+            mController.show(Type.navigationBars());
             mController.show(Type.systemBars());
             mController.cancelExistingAnimation();
             assertTrue(mController.getSourceConsumer(navBar.getType()).isVisible());
-            assertTrue(mController.getSourceConsumer(topBar.getType()).isVisible());
+            assertTrue(mController.getSourceConsumer(statusBar.getType()).isVisible());
             assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
 
-            mController.hide(Type.sideBars());
+            mController.hide(Type.navigationBars());
             mController.hide(Type.systemBars());
             mController.cancelExistingAnimation();
             assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
-            assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+            assertFalse(mController.getSourceConsumer(statusBar.getType()).isVisible());
             assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
 
-            int types = Type.sideBars() | Type.systemBars();
+            int types = Type.navigationBars() | Type.systemBars();
             // show two at a time and hide one by one.
             mController.show(types);
-            mController.hide(Type.sideBars());
+            mController.hide(Type.navigationBars());
             mController.cancelExistingAnimation();
             assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
-            assertTrue(mController.getSourceConsumer(topBar.getType()).isVisible());
+            assertTrue(mController.getSourceConsumer(statusBar.getType()).isVisible());
             assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
 
             mController.hide(Type.systemBars());
             mController.cancelExistingAnimation();
             assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
-            assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+            assertFalse(mController.getSourceConsumer(statusBar.getType()).isVisible());
             assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
         });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
@@ -297,23 +300,23 @@
     public void testShowMultipleHideOneByOne() {
         InsetsSourceControl[] controls = prepareControls();
         InsetsSourceControl navBar = controls[0];
-        InsetsSourceControl topBar = controls[1];
+        InsetsSourceControl statusBar = controls[1];
         InsetsSourceControl ime = controls[2];
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            int types = Type.sideBars() | Type.systemBars();
+            int types = Type.navigationBars() | Type.systemBars();
             // show two at a time and hide one by one.
             mController.show(types);
-            mController.hide(Type.sideBars());
+            mController.hide(Type.navigationBars());
             mController.cancelExistingAnimation();
             assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
-            assertTrue(mController.getSourceConsumer(topBar.getType()).isVisible());
+            assertTrue(mController.getSourceConsumer(statusBar.getType()).isVisible());
             assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
 
             mController.hide(Type.systemBars());
             mController.cancelExistingAnimation();
             assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
-            assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+            assertFalse(mController.getSourceConsumer(statusBar.getType()).isVisible());
             assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
         });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
@@ -321,13 +324,14 @@
 
     @Test
     public void testAnimationEndState_controller() throws Exception {
-        InsetsSourceControl control = new InsetsSourceControl(TYPE_TOP_BAR, mLeash, new Point());
+        InsetsSourceControl control =
+                new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point());
         mController.onControlsChanged(new InsetsSourceControl[] { control });
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             WindowInsetsAnimationControlListener mockListener =
                     mock(WindowInsetsAnimationControlListener.class);
-            mController.controlWindowInsetsAnimation(topBar(), mockListener);
+            mController.controlWindowInsetsAnimation(statusBars(), mockListener);
 
             ArgumentCaptor<WindowInsetsAnimationController> controllerCaptor =
                     ArgumentCaptor.forClass(WindowInsetsAnimationController.class);
@@ -336,7 +340,7 @@
         });
         waitUntilNextFrame();
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            assertFalse(mController.getSourceConsumer(TYPE_TOP_BAR).isVisible());
+            assertFalse(mController.getSourceConsumer(ITYPE_STATUS_BAR).isVisible());
         });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
@@ -349,15 +353,15 @@
     }
 
     private InsetsSourceControl[] prepareControls() {
-        final InsetsSourceControl navBar = new InsetsSourceControl(TYPE_NAVIGATION_BAR, mLeash,
+        final InsetsSourceControl navBar = new InsetsSourceControl(ITYPE_NAVIGATION_BAR, mLeash,
                 new Point());
-        final InsetsSourceControl topBar = new InsetsSourceControl(TYPE_TOP_BAR, mLeash,
+        final InsetsSourceControl statusBar = new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash,
                 new Point());
-        final InsetsSourceControl ime = new InsetsSourceControl(TYPE_IME, mLeash, new Point());
+        final InsetsSourceControl ime = new InsetsSourceControl(ITYPE_IME, mLeash, new Point());
 
         InsetsSourceControl[] controls = new InsetsSourceControl[3];
         controls[0] = navBar;
-        controls[1] = topBar;
+        controls[1] = statusBar;
         controls[2] = ime;
         mController.onControlsChanged(controls);
         return controls;
diff --git a/core/tests/coretests/src/android/view/InsetsFlagsTest.java b/core/tests/coretests/src/android/view/InsetsFlagsTest.java
index 7d4445b..b4302e7 100644
--- a/core/tests/coretests/src/android/view/InsetsFlagsTest.java
+++ b/core/tests/coretests/src/android/view/InsetsFlagsTest.java
@@ -25,11 +25,11 @@
 import static android.view.View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
 import static android.view.View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
 import static android.view.View.SYSTEM_UI_FLAG_LOW_PROFILE;
-import static android.view.WindowInsetsController.APPEARANCE_LIGHT_SIDE_BARS;
-import static android.view.WindowInsetsController.APPEARANCE_LIGHT_TOP_BAR;
+import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
 import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
-import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_SIDE_BARS;
-import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_TOP_BAR;
+import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_NAVIGATION_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_STATUS_BARS;
 
 import static org.junit.Assert.assertTrue;
 
@@ -57,11 +57,12 @@
     @Test
     public void testGetAppearance() {
         assertContainsAppearance(APPEARANCE_LOW_PROFILE_BARS, SYSTEM_UI_FLAG_LOW_PROFILE);
-        assertContainsAppearance(APPEARANCE_LIGHT_TOP_BAR, SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
-        assertContainsAppearance(APPEARANCE_LIGHT_SIDE_BARS, SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
-        assertContainsAppearance(APPEARANCE_OPAQUE_TOP_BAR,
+        assertContainsAppearance(APPEARANCE_LIGHT_STATUS_BARS, SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
+        assertContainsAppearance(APPEARANCE_LIGHT_NAVIGATION_BARS,
+                SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
+        assertContainsAppearance(APPEARANCE_OPAQUE_STATUS_BARS,
                 0xffffffff & ~(STATUS_BAR_TRANSLUCENT | STATUS_BAR_TRANSPARENT));
-        assertContainsAppearance(APPEARANCE_OPAQUE_SIDE_BARS,
+        assertContainsAppearance(APPEARANCE_OPAQUE_NAVIGATION_BARS,
                 0xffffffff & ~(NAVIGATION_BAR_TRANSLUCENT | NAVIGATION_BAR_TRANSPARENT));
     }
 
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
index e5fe2d0..2cf6ff3 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -16,7 +16,7 @@
 
 package android.view;
 
-import static android.view.InsetsState.TYPE_TOP_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
 
 import static junit.framework.TestCase.assertFalse;
 import static junit.framework.TestCase.assertTrue;
@@ -82,15 +82,15 @@
                 // activity isn't running, lets ignore BadTokenException.
             }
             InsetsState state = new InsetsState();
-            mSpyInsetsSource = Mockito.spy(new InsetsSource(TYPE_TOP_BAR));
+            mSpyInsetsSource = Mockito.spy(new InsetsSource(ITYPE_STATUS_BAR));
             state.addSource(mSpyInsetsSource);
 
-            mConsumer = new InsetsSourceConsumer(TYPE_TOP_BAR, state,
+            mConsumer = new InsetsSourceConsumer(ITYPE_STATUS_BAR, state,
                     () -> mMockTransaction, new InsetsController(viewRootImpl));
         });
         instrumentation.waitForIdleSync();
 
-        mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash, new Point()));
+        mConsumer.setControl(new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point()));
     }
 
     @Test
@@ -113,7 +113,7 @@
         reset(mMockTransaction);
         mConsumer.hide();
         verifyZeroInteractions(mMockTransaction);
-        mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash, new Point()));
+        mConsumer.setControl(new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point()));
         verify(mMockTransaction).hide(eq(mLeash));
     }
 }
diff --git a/core/tests/coretests/src/android/view/InsetsSourceTest.java b/core/tests/coretests/src/android/view/InsetsSourceTest.java
index 533a58e..d7f50ba 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceTest.java
@@ -16,7 +16,7 @@
 
 package android.view;
 
-import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 
 import static org.junit.Assert.assertEquals;
 
@@ -43,7 +43,7 @@
 @RunWith(AndroidJUnit4.class)
 public class InsetsSourceTest {
 
-    private InsetsSource mSource = new InsetsSource(TYPE_NAVIGATION_BAR);
+    private InsetsSource mSource = new InsetsSource(ITYPE_NAVIGATION_BAR);
 
     @Before
     public void setUp() {
diff --git a/core/tests/coretests/src/android/view/InsetsStateTest.java b/core/tests/coretests/src/android/view/InsetsStateTest.java
index a73269a..6062088 100644
--- a/core/tests/coretests/src/android/view/InsetsStateTest.java
+++ b/core/tests/coretests/src/android/view/InsetsStateTest.java
@@ -16,14 +16,12 @@
 
 package android.view;
 
-import static android.view.InsetsState.INSET_SIDE_BOTTOM;
-import static android.view.InsetsState.INSET_SIDE_TOP;
-import static android.view.InsetsState.TYPE_IME;
-import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.TYPE_SIDE_BAR_1;
-import static android.view.InsetsState.TYPE_SIDE_BAR_2;
-import static android.view.InsetsState.TYPE_SIDE_BAR_3;
-import static android.view.InsetsState.TYPE_TOP_BAR;
+import static android.view.InsetsState.ISIDE_BOTTOM;
+import static android.view.InsetsState.ISIDE_TOP;
+import static android.view.InsetsState.ITYPE_CAPTION_BAR;
+import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 
@@ -65,18 +63,18 @@
     public void testCalculateInsets() throws Exception {
         try (final InsetsModeSession session =
                      new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_FULL)) {
-            mState.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 100, 100));
-            mState.getSource(TYPE_TOP_BAR).setVisible(true);
-            mState.getSource(TYPE_IME).setFrame(new Rect(0, 200, 100, 300));
-            mState.getSource(TYPE_IME).setVisible(true);
+            mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
+            mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
+            mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300));
+            mState.getSource(ITYPE_IME).setVisible(true);
             SparseIntArray typeSideMap = new SparseIntArray();
             WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
                     DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_RESIZE, typeSideMap);
             assertEquals(Insets.of(0, 100, 0, 100), insets.getSystemWindowInsets());
             assertEquals(Insets.of(0, 100, 0, 100), insets.getInsets(Type.all()));
-            assertEquals(INSET_SIDE_TOP, typeSideMap.get(TYPE_TOP_BAR));
-            assertEquals(INSET_SIDE_BOTTOM, typeSideMap.get(TYPE_IME));
-            assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(Type.topBar()));
+            assertEquals(ISIDE_TOP, typeSideMap.get(ITYPE_STATUS_BAR));
+            assertEquals(ISIDE_BOTTOM, typeSideMap.get(ITYPE_IME));
+            assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(Type.statusBars()));
             assertEquals(Insets.of(0, 0, 0, 100), insets.getInsets(Type.ime()));
         }
     }
@@ -85,17 +83,17 @@
     public void testCalculateInsets_imeAndNav() throws Exception{
         try (final InsetsModeSession session =
                      new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_FULL)) {
-            mState.getSource(TYPE_NAVIGATION_BAR).setFrame(new Rect(0, 200, 100, 300));
-            mState.getSource(TYPE_NAVIGATION_BAR).setVisible(true);
-            mState.getSource(TYPE_IME).setFrame(new Rect(0, 100, 100, 300));
-            mState.getSource(TYPE_IME).setVisible(true);
+            mState.getSource(ITYPE_NAVIGATION_BAR).setFrame(new Rect(0, 200, 100, 300));
+            mState.getSource(ITYPE_NAVIGATION_BAR).setVisible(true);
+            mState.getSource(ITYPE_IME).setFrame(new Rect(0, 100, 100, 300));
+            mState.getSource(ITYPE_IME).setVisible(true);
             WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
                     DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_RESIZE, null);
             assertEquals(100, insets.getStableInsetBottom());
             assertEquals(Insets.of(0, 0, 0, 100), insets.getMaxInsets(Type.systemBars()));
             assertEquals(Insets.of(0, 0, 0, 200), insets.getSystemWindowInsets());
             assertEquals(Insets.of(0, 0, 0, 200), insets.getInsets(Type.all()));
-            assertEquals(Insets.of(0, 0, 0, 100), insets.getInsets(Type.sideBars()));
+            assertEquals(Insets.of(0, 0, 0, 100), insets.getInsets(Type.navigationBars()));
             assertEquals(Insets.of(0, 0, 0, 200), insets.getInsets(Type.ime()));
         }
     }
@@ -104,24 +102,24 @@
     public void testCalculateInsets_navRightStatusTop() throws Exception {
         try (final InsetsModeSession session =
                      new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_FULL)) {
-            mState.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 100, 100));
-            mState.getSource(TYPE_TOP_BAR).setVisible(true);
-            mState.getSource(TYPE_NAVIGATION_BAR).setFrame(new Rect(80, 0, 100, 300));
-            mState.getSource(TYPE_NAVIGATION_BAR).setVisible(true);
+            mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
+            mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
+            mState.getSource(ITYPE_NAVIGATION_BAR).setFrame(new Rect(80, 0, 100, 300));
+            mState.getSource(ITYPE_NAVIGATION_BAR).setVisible(true);
             WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
                     DisplayCutout.NO_CUTOUT, null, null, 0, null);
             assertEquals(Insets.of(0, 100, 20, 0), insets.getSystemWindowInsets());
-            assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(Type.topBar()));
-            assertEquals(Insets.of(0, 0, 20, 0), insets.getInsets(Type.sideBars()));
+            assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(Type.statusBars()));
+            assertEquals(Insets.of(0, 0, 20, 0), insets.getInsets(Type.navigationBars()));
         }
     }
 
     @Test
     public void testCalculateInsets_imeIgnoredWithoutAdjustResize() {
-        mState.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(TYPE_TOP_BAR).setVisible(true);
-        mState.getSource(TYPE_IME).setFrame(new Rect(0, 200, 100, 300));
-        mState.getSource(TYPE_IME).setVisible(true);
+        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
+        mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
+        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300));
+        mState.getSource(ITYPE_IME).setVisible(true);
         WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
                 DisplayCutout.NO_CUTOUT, null, null, 0, null);
         assertEquals(0, insets.getSystemWindowInsetBottom());
@@ -130,11 +128,11 @@
 
     @Test
     public void testStripForDispatch() {
-        mState.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(TYPE_TOP_BAR).setVisible(true);
-        mState.getSource(TYPE_IME).setFrame(new Rect(0, 200, 100, 300));
-        mState.getSource(TYPE_IME).setVisible(true);
-        mState.removeSource(TYPE_IME);
+        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
+        mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
+        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300));
+        mState.getSource(ITYPE_IME).setVisible(true);
+        mState.removeSource(ITYPE_IME);
         WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
                 DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_RESIZE, null);
         assertEquals(0, insets.getSystemWindowInsetBottom());
@@ -142,32 +140,32 @@
 
     @Test
     public void testEquals_differentRect() {
-        mState.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState2.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 10, 10));
+        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
+        mState2.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 10, 10));
         assertNotEqualsAndHashCode();
     }
 
     @Test
     public void testEquals_differentSource() {
-        mState.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState2.getSource(TYPE_IME).setFrame(new Rect(0, 0, 100, 100));
+        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
+        mState2.getSource(ITYPE_IME).setFrame(new Rect(0, 0, 100, 100));
         assertNotEqualsAndHashCode();
     }
 
     @Test
     public void testEquals_sameButDifferentInsertOrder() {
-        mState.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(TYPE_IME).setFrame(new Rect(0, 0, 100, 100));
-        mState2.getSource(TYPE_IME).setFrame(new Rect(0, 0, 100, 100));
-        mState2.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 100, 100));
+        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
+        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 0, 100, 100));
+        mState2.getSource(ITYPE_IME).setFrame(new Rect(0, 0, 100, 100));
+        mState2.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
         assertEqualsAndHashCode();
     }
 
     @Test
     public void testEquals_visibility() {
-        mState.getSource(TYPE_IME).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(TYPE_IME).setVisible(true);
-        mState2.getSource(TYPE_IME).setFrame(new Rect(0, 0, 100, 100));
+        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 0, 100, 100));
+        mState.getSource(ITYPE_IME).setVisible(true);
+        mState2.getSource(ITYPE_IME).setFrame(new Rect(0, 0, 100, 100));
         assertNotEqualsAndHashCode();
     }
 
@@ -187,9 +185,9 @@
 
     @Test
     public void testParcelUnparcel() {
-        mState.getSource(TYPE_IME).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(TYPE_IME).setVisible(true);
-        mState.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 100, 100));
+        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 0, 100, 100));
+        mState.getSource(ITYPE_IME).setVisible(true);
+        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
         Parcel p = Parcel.obtain();
         mState.writeToParcel(p, 0 /* flags */);
         p.setDataPosition(0);
@@ -200,11 +198,10 @@
 
     @Test
     public void testGetDefaultVisibility() {
-        assertTrue(InsetsState.getDefaultVisibility(TYPE_TOP_BAR));
-        assertTrue(InsetsState.getDefaultVisibility(TYPE_SIDE_BAR_1));
-        assertTrue(InsetsState.getDefaultVisibility(TYPE_SIDE_BAR_2));
-        assertTrue(InsetsState.getDefaultVisibility(TYPE_SIDE_BAR_3));
-        assertFalse(InsetsState.getDefaultVisibility(TYPE_IME));
+        assertTrue(InsetsState.getDefaultVisibility(ITYPE_STATUS_BAR));
+        assertTrue(InsetsState.getDefaultVisibility(ITYPE_NAVIGATION_BAR));
+        assertTrue(InsetsState.getDefaultVisibility(ITYPE_CAPTION_BAR));
+        assertFalse(InsetsState.getDefaultVisibility(ITYPE_IME));
     }
 
     private void assertEqualsAndHashCode() {
diff --git a/core/tests/coretests/src/android/view/WindowInsetsTest.java b/core/tests/coretests/src/android/view/WindowInsetsTest.java
index 6a83c29b..8c7b28a 100644
--- a/core/tests/coretests/src/android/view/WindowInsetsTest.java
+++ b/core/tests/coretests/src/android/view/WindowInsetsTest.java
@@ -17,8 +17,9 @@
 package android.view;
 
 import static android.view.WindowInsets.Type.ime;
-import static android.view.WindowInsets.Type.sideBars;
-import static android.view.WindowInsets.Type.topBar;
+import static android.view.WindowInsets.Type.navigationBars;
+import static android.view.WindowInsets.Type.statusBars;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -59,7 +60,7 @@
     @Test
     public void typeMap() {
         Builder b = new WindowInsets.Builder();
-        b.setInsets(sideBars(), Insets.of(0, 0, 0, 100));
+        b.setInsets(navigationBars(), Insets.of(0, 0, 0, 100));
         b.setInsets(ime(), Insets.of(0, 0, 0, 300));
         WindowInsets insets = b.build();
         assertEquals(300, insets.getSystemWindowInsets().bottom);
@@ -71,22 +72,22 @@
         Builder b = new WindowInsets.Builder();
         b.setSystemWindowInsets(Insets.of(0, 50, 30, 10));
         WindowInsets insets = b.build();
-        assertEquals(Insets.of(0, 50, 0, 0), insets.getInsets(topBar()));
-        assertEquals(Insets.of(0, 0, 30, 10), insets.getInsets(sideBars()));
+        assertEquals(Insets.of(0, 50, 0, 0), insets.getInsets(statusBars()));
+        assertEquals(Insets.of(0, 0, 30, 10), insets.getInsets(navigationBars()));
     }
 
     // TODO: Move this to CTS once API made public
     @Test
     public void visibility() {
         Builder b = new WindowInsets.Builder();
-        b.setInsets(sideBars(), Insets.of(0, 0, 0, 100));
+        b.setInsets(navigationBars(), Insets.of(0, 0, 0, 100));
         b.setInsets(ime(), Insets.of(0, 0, 0, 300));
-        b.setVisible(sideBars(), true);
+        b.setVisible(navigationBars(), true);
         b.setVisible(ime(), true);
         WindowInsets insets = b.build();
-        assertTrue(insets.isVisible(sideBars()));
-        assertTrue(insets.isVisible(sideBars() | ime()));
-        assertFalse(insets.isVisible(sideBars() | topBar()));
+        assertTrue(insets.isVisible(navigationBars()));
+        assertTrue(insets.isVisible(navigationBars() | ime()));
+        assertFalse(insets.isVisible(navigationBars() | statusBars()));
     }
 
     // TODO: Move this to CTS once API made public
diff --git a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
index 928351e..b48ac33 100644
--- a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
+++ b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
@@ -93,6 +93,27 @@
     }
 
     @SmallTest
+    private static void testHandle() throws Exception {
+        String value;
+        SystemProperties.Handle handle = SystemProperties.find("doesnotexist_2341431");
+        assertNull(handle);
+        SystemProperties.set(KEY, "abc");
+        handle = SystemProperties.find(KEY);
+        assertNotNull(handle);
+        value = handle.get();
+        assertEquals("abc", value);
+        SystemProperties.set(KEY, "blarg");
+        value = handle.get();
+        assertEquals("blarg", value);
+        SystemProperties.set(KEY, "1");
+        assertEquals(1, handle.getInt(-1));
+        assertEquals(1, handle.getLong(-1));
+        assertEquals(true, handle.getBoolean(false));
+        SystemProperties.set(KEY, "");
+        assertEquals(12345, handle.getInt(12345));
+    }
+
+    @SmallTest
     public void testIntegralProperties() throws Exception {
         testInt("", 123, 123);
         testInt("", 0, 0);
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index ed19a37..5c48d91 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -73,6 +73,12 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "-1972506791": {
+      "message": "Set freezing of %s: hidden=%b freezing=%b visibleRequested=%b. %s",
+      "level": "INFO",
+      "group": "WM_DEBUG_ORIENTATION",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "-1963461591": {
       "message": "Removing %s from %s",
       "level": "VERBOSE",
@@ -877,6 +883,12 @@
       "group": "WM_DEBUG_ORIENTATION",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "-229838822": {
+      "message": "setAppVisibility(%s, visible=%b): %s hidden=%b mVisibleRequested=%b Callers=%s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_APP_TRANSITIONS",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "-198463978": {
       "message": "updateRotationUnchecked: alwaysSendConfiguration=%b forceRelayout=%b",
       "level": "VERBOSE",
@@ -1201,12 +1213,6 @@
       "group": "WM_DEBUG_ORIENTATION",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
-    "358613119": {
-      "message": "setAppVisibility(%s, visible=%b): %s hidden=%b hiddenRequested=%b Callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
     "371641947": {
       "message": "Window Manager Crash %s",
       "level": "WTF",
@@ -1489,12 +1495,6 @@
       "group": "WM_DEBUG_RECENTS_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RecentsAnimation.java"
     },
-    "857751535": {
-      "message": "commitVisibility: %s: hidden=%b hiddenRequested=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
     "873914452": {
       "message": "goodToGo()",
       "level": "DEBUG",
@@ -1987,10 +1987,10 @@
       "group": "WM_DEBUG_REMOTE_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
     },
-    "1966564525": {
-      "message": "Set freezing of %s: hidden=%b freezing=%b hiddenRequested=%b. %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_ORIENTATION",
+    "1965198071": {
+      "message": "commitVisibility: %s: hidden=%b visibleRequested=%b",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_APP_TRANSITIONS",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
     "1984470582": {
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
index 2cdd000..d033294 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
@@ -400,6 +400,12 @@
      *
      * <p>Note: the returned {@code KeyStore} is already initialized/loaded. Thus, there is
      * no need to invoke {@code load} on it.
+     *
+     * @param uid Uid for which the keystore provider is requested.
+     * @throws KeyStoreException if a KeyStoreSpi implementation for the specified type is not
+     * available from the specified provider.
+     * @throws NoSuchProviderException If the specified provider is not registered in the security
+     * provider list.
      * @hide
      */
     @SystemApi
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/ActivityTile.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/ActivityTile.java
index 06a4a45..8cd33a5 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/ActivityTile.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/ActivityTile.java
@@ -53,15 +53,6 @@
     }
 
     @Override
-    protected CharSequence getComponentLabel(Context context) {
-        final PackageManager pm = context.getPackageManager();
-        final ComponentInfo info = getComponentInfo(context);
-        return info == null
-                ? null
-                : info.loadLabel(pm);
-    }
-
-    @Override
     protected ComponentInfo getComponentInfo(Context context) {
         if (mComponentInfo == null) {
             final PackageManager pm = context.getApplicationContext().getPackageManager();
@@ -78,4 +69,18 @@
         }
         return mComponentInfo;
     }
+
+    @Override
+    protected CharSequence getComponentLabel(Context context) {
+        final PackageManager pm = context.getPackageManager();
+        final ComponentInfo info = getComponentInfo(context);
+        return info == null
+                ? null
+                : info.loadLabel(pm);
+    }
+
+    @Override
+    protected int getComponentIcon(ComponentInfo componentInfo) {
+        return componentInfo.icon;
+    }
 }
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/DynamicSummary.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/DynamicSummary.java
new file mode 100644
index 0000000..c9d9b57
--- /dev/null
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/DynamicSummary.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2019 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.settingslib.drawer;
+
+/** Interface for {@link SwitchController} whose instances support dynamic summary */
+public interface DynamicSummary {
+    /** @return the dynamic summary text */
+    String getDynamicSummary();
+}
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/DynamicTitle.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/DynamicTitle.java
new file mode 100644
index 0000000..af711dd
--- /dev/null
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/DynamicTitle.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2019 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.settingslib.drawer;
+
+/** Interface for {@link SwitchController} whose instances support dynamic title */
+public interface DynamicTitle {
+    /** @return the dynamic title text */
+    String getDynamicTitle();
+}
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/ProviderIcon.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/ProviderIcon.java
new file mode 100644
index 0000000..2945d5c
--- /dev/null
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/ProviderIcon.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 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.settingslib.drawer;
+
+import android.os.Bundle;
+
+/**
+ *  Interface for {@link SwitchController} whose instances support icon provided from the content
+ *  provider
+ */
+public interface ProviderIcon {
+    /**
+     * @return the bundle of icon info including {@link TileUtils#EXTRA_PREFERENCE_ICON_PACKAGE} and
+     * {@link TileUtils#META_DATA_PREFERENCE_ICON}.
+     */
+    Bundle getProviderIcon();
+}
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/ProviderTile.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/ProviderTile.java
new file mode 100644
index 0000000..b2ba5de
--- /dev/null
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/ProviderTile.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2019 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.settingslib.drawer;
+
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ComponentInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.util.Log;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Description of a single dashboard tile which is generated from a content provider.
+ */
+public class ProviderTile extends Tile {
+    private static final String TAG = "ProviderTile";
+
+    private static final boolean DEBUG_TIMING = false;
+
+    private String mAuthority;
+    private String mKey;
+
+    public ProviderTile(ComponentInfo info, String category, Bundle metaData) {
+        super(info, category);
+        setMetaData(metaData);
+        mAuthority = ((ProviderInfo) info).authority;
+        mKey = metaData.getString(META_DATA_PREFERENCE_KEYHINT);
+    }
+
+    ProviderTile(Parcel in) {
+        super(in);
+        mAuthority = ((ProviderInfo) mComponentInfo).authority;
+        mKey = getMetaData().getString(META_DATA_PREFERENCE_KEYHINT);
+    }
+
+    @Override
+    public int getId() {
+        return Objects.hash(mAuthority, mKey);
+    }
+
+    @Override
+    public String getDescription() {
+        return mAuthority + "/" + mKey;
+    }
+
+    @Override
+    protected ComponentInfo getComponentInfo(Context context) {
+        if (mComponentInfo == null) {
+            final long startTime = System.currentTimeMillis();
+            final PackageManager pm = context.getApplicationContext().getPackageManager();
+            final Intent intent = getIntent();
+            final List<ResolveInfo> infoList =
+                    pm.queryIntentContentProviders(intent, 0 /* flags */);
+            if (infoList != null && !infoList.isEmpty()) {
+                final ProviderInfo providerInfo = infoList.get(0).providerInfo;
+                mComponentInfo = providerInfo;
+                setMetaData(TileUtils.getSwitchDataFromProvider(context, providerInfo.authority,
+                        mKey));
+            } else {
+                Log.e(TAG, "Cannot find package info for "
+                        + intent.getComponent().flattenToString());
+            }
+
+            if (DEBUG_TIMING) {
+                Log.d(TAG, "getComponentInfo took "
+                        + (System.currentTimeMillis() - startTime) + " ms");
+            }
+        }
+        return mComponentInfo;
+    }
+
+    @Override
+    protected CharSequence getComponentLabel(Context context) {
+        // Getting provider label for a tile title isn't supported.
+        return null;
+    }
+
+    @Override
+    protected int getComponentIcon(ComponentInfo info) {
+        // Getting provider icon for a tile title isn't supported.
+        return 0;
+    }
+}
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/SwitchController.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/SwitchController.java
new file mode 100644
index 0000000..e48da86
--- /dev/null
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/SwitchController.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2019 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.settingslib.drawer;
+
+import static com.android.settingslib.drawer.SwitchesProvider.METHOD_GET_DYNAMIC_SUMMARY;
+import static com.android.settingslib.drawer.SwitchesProvider.METHOD_GET_DYNAMIC_TITLE;
+import static com.android.settingslib.drawer.SwitchesProvider.METHOD_IS_CHECKED;
+import static com.android.settingslib.drawer.TileUtils.EXTRA_CATEGORY_KEY;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_KEY_ORDER;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_URI;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY_URI;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SWITCH_URI;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE_URI;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.StringRes;
+
+/**
+ * A controller that manages events for switch.
+ */
+public abstract class SwitchController {
+
+    private String mAuthority;
+
+    /**
+     * Returns the key for this switch.
+     */
+    public abstract String getSwitchKey();
+
+    /**
+     * Returns the {@link MetaData} for this switch.
+     */
+    protected abstract MetaData getMetaData();
+
+    /**
+     * Returns the checked state of this switch.
+     */
+    protected abstract boolean isChecked();
+
+    /**
+     * Called when the checked state of this switch is changed.
+     *
+     * @return true if the checked state was successfully changed, otherwise false
+     */
+    protected abstract boolean onCheckedChanged(boolean checked);
+
+    /**
+     * Returns the error message which will be toasted when {@link #onCheckedChanged} returns false.
+     */
+    protected abstract String getErrorMessage(boolean attemptedChecked);
+
+    /**
+     * Notify registered observers that title was updated and attempt to sync changes.
+     */
+    public void notifyTitleChanged(Context context) {
+        if (this instanceof DynamicTitle) {
+            notifyChanged(context, METHOD_GET_DYNAMIC_TITLE);
+        }
+    }
+
+    /**
+     * Notify registered observers that summary was updated and attempt to sync changes.
+     */
+    public void notifySummaryChanged(Context context) {
+        if (this instanceof DynamicSummary) {
+            notifyChanged(context, METHOD_GET_DYNAMIC_SUMMARY);
+        }
+    }
+
+    /**
+     * Notify registered observers that checked state was updated and attempt to sync changes.
+     */
+    public void notifyCheckedChanged(Context context) {
+        notifyChanged(context, METHOD_IS_CHECKED);
+    }
+
+    void setAuthority(String authority) {
+        mAuthority = authority;
+    }
+
+    Bundle getBundle() {
+        final MetaData metaData = getMetaData();
+        if (metaData == null) {
+            throw new IllegalArgumentException("Should not return null in getMetaData()");
+        }
+
+        final Bundle bundle = metaData.build();
+        final String uriString = new Uri.Builder()
+                .scheme(ContentResolver.SCHEME_CONTENT)
+                .authority(mAuthority)
+                .build()
+                .toString();
+        bundle.putString(META_DATA_PREFERENCE_KEYHINT, getSwitchKey());
+        bundle.putString(META_DATA_PREFERENCE_SWITCH_URI, uriString);
+        if (this instanceof ProviderIcon) {
+            bundle.putString(META_DATA_PREFERENCE_ICON_URI, uriString);
+        }
+        if (this instanceof DynamicTitle) {
+            bundle.putString(META_DATA_PREFERENCE_TITLE_URI, uriString);
+        }
+        if (this instanceof DynamicSummary) {
+            bundle.putString(META_DATA_PREFERENCE_SUMMARY_URI, uriString);
+        }
+        return bundle;
+    }
+
+    private void notifyChanged(Context context, String method) {
+        final Uri uri = TileUtils.buildUri(mAuthority, method, getSwitchKey());
+        context.getContentResolver().notifyChange(uri, null);
+    }
+
+    /**
+     * Collects all meta data of the item.
+     */
+    protected static class MetaData {
+        private String mCategory;
+        private int mOrder;
+        @DrawableRes
+        private int mIcon;
+        private int mIconBackgroundHint;
+        private int mIconBackgroundArgb;
+        private Boolean mIconTintable;
+        @StringRes
+        private int mTitleId;
+        private String mTitle;
+        @StringRes
+        private int mSummaryId;
+        private String mSummary;
+
+        /**
+         * @param category the category of the switch. This value must be from {@link CategoryKey}.
+         */
+        public MetaData(@NonNull String category) {
+            mCategory = category;
+        }
+
+        /**
+         * Set the order of the item that should be displayed on screen. Bigger value items displays
+         * closer on top.
+         */
+        public MetaData setOrder(int order) {
+            mOrder = order;
+            return this;
+        }
+
+        /** Set the icon that should be displayed for the item. */
+        public MetaData setIcon(@DrawableRes int icon) {
+            mIcon = icon;
+            return this;
+        }
+
+        /** Set the icon background color. The value may or may not be used by Settings app. */
+        public MetaData setIconBackgoundHint(int hint) {
+            mIconBackgroundHint = hint;
+            return this;
+        }
+
+        /** Set the icon background color as raw ARGB. */
+        public MetaData setIconBackgoundArgb(int argb) {
+            mIconBackgroundArgb = argb;
+            return this;
+        }
+
+        /** Specify whether the icon is tintable. */
+        public MetaData setIconTintable(boolean tintable) {
+            mIconTintable = tintable;
+            return this;
+        }
+
+        /** Set the title that should be displayed for the item. */
+        public MetaData setTitle(@StringRes int id) {
+            mTitleId = id;
+            return this;
+        }
+
+        /** Set the title that should be displayed for the item. */
+        public MetaData setTitle(String title) {
+            mTitle = title;
+            return this;
+        }
+
+        /** Set the summary text that should be displayed for the item. */
+        public MetaData setSummary(@StringRes int id) {
+            mSummaryId = id;
+            return this;
+        }
+
+        /** Set the summary text that should be displayed for the item. */
+        public MetaData setSummary(String summary) {
+            mSummary = summary;
+            return this;
+        }
+
+        private Bundle build() {
+            final Bundle bundle = new Bundle();
+            bundle.putString(EXTRA_CATEGORY_KEY, mCategory);
+
+            if (mOrder != 0) {
+                bundle.putInt(META_DATA_KEY_ORDER, mOrder);
+            }
+
+            if (mIcon != 0) {
+                bundle.putInt(META_DATA_PREFERENCE_ICON, mIcon);
+            }
+            if (mIconBackgroundHint != 0) {
+                bundle.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT, mIconBackgroundHint);
+            }
+            if (mIconBackgroundArgb != 0) {
+                bundle.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, mIconBackgroundArgb);
+            }
+            if (mIconTintable != null) {
+                bundle.putBoolean(META_DATA_PREFERENCE_ICON_TINTABLE, mIconTintable);
+            }
+
+            if (mTitleId != 0) {
+                bundle.putInt(META_DATA_PREFERENCE_TITLE, mTitleId);
+            } else if (mTitle != null) {
+                bundle.putString(META_DATA_PREFERENCE_TITLE, mTitle);
+            }
+
+            if (mSummaryId != 0) {
+                bundle.putInt(META_DATA_PREFERENCE_SUMMARY, mSummaryId);
+            } else if (mSummary != null) {
+                bundle.putString(META_DATA_PREFERENCE_SUMMARY, mSummary);
+            }
+            return bundle;
+        }
+    }
+}
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/SwitchesProvider.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/SwitchesProvider.java
new file mode 100644
index 0000000..a05c7d5
--- /dev/null
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/SwitchesProvider.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2019 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.settingslib.drawer;
+
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.pm.ProviderInfo;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An abstract class for injecting switches to Settings.
+ */
+public abstract class SwitchesProvider extends ContentProvider {
+    private static final String TAG = "SwitchesProvider";
+
+    public static final String METHOD_GET_SWITCH_DATA = "getSwitchData";
+    public static final String METHOD_GET_PROVIDER_ICON = "getProviderIcon";
+    public static final String METHOD_GET_DYNAMIC_TITLE = "getDynamicTitle";
+    public static final String METHOD_GET_DYNAMIC_SUMMARY = "getDynamicSummary";
+    public static final String METHOD_IS_CHECKED = "isChecked";
+    public static final String METHOD_ON_CHECKED_CHANGED = "onCheckedChanged";
+
+    public static final String EXTRA_SWITCH_DATA = "switch_data";
+    public static final String EXTRA_SWITCH_CHECKED_STATE = "checked_state";
+    public static final String EXTRA_SWITCH_SET_CHECKED_ERROR = "set_checked_error";
+    public static final String EXTRA_SWITCH_SET_CHECKED_ERROR_MESSAGE = "set_checked_error_message";
+
+    private String mAuthority;
+    private final Map<String, SwitchController> mControllerMap = new LinkedHashMap<>();
+    private final List<Bundle> mSwitchList = new ArrayList<>();
+
+    /**
+     * Get a list of {@link SwitchController} for this provider.
+     */
+    protected abstract List<SwitchController> createSwitchControllers();
+
+    @Override
+    public void attachInfo(Context context, ProviderInfo info) {
+        mAuthority = info.authority;
+        Log.i(TAG, mAuthority);
+        super.attachInfo(context, info);
+    }
+
+    @Override
+    public boolean onCreate() {
+        final List<SwitchController> controllers = createSwitchControllers();
+        if (controllers == null || controllers.isEmpty()) {
+            throw new IllegalArgumentException();
+        }
+
+        controllers.forEach(controller -> {
+            final String key = controller.getSwitchKey();
+            if (TextUtils.isEmpty(key)) {
+                throw new NullPointerException("Switch key cannot be null: "
+                        + controller.getClass().getSimpleName());
+            } else if (mControllerMap.containsKey(key)) {
+                throw new IllegalArgumentException("Switch key " + key + " is duplicated by: "
+                        + controller.getClass().getSimpleName());
+            }
+
+            controller.setAuthority(mAuthority);
+            mControllerMap.put(key, controller);
+            mSwitchList.add(controller.getBundle());
+        });
+        return true;
+    }
+
+    @Override
+    public Bundle call(String method, String uriString, Bundle extras) {
+        final Bundle bundle = new Bundle();
+        final String key = extras != null
+                ? extras.getString(META_DATA_PREFERENCE_KEYHINT)
+                : null;
+        if (TextUtils.isEmpty(key)) {
+            if (METHOD_GET_SWITCH_DATA.equals(method)) {
+                bundle.putParcelableList(EXTRA_SWITCH_DATA, mSwitchList);
+                return bundle;
+            }
+            return null;
+        }
+
+        final SwitchController controller = mControllerMap.get(key);
+        if (controller == null) {
+            return null;
+        }
+
+        switch (method) {
+            case METHOD_GET_SWITCH_DATA:
+                return controller.getBundle();
+            case METHOD_GET_PROVIDER_ICON:
+                if (controller instanceof ProviderIcon) {
+                    return ((ProviderIcon) controller).getProviderIcon();
+                }
+                break;
+            case METHOD_GET_DYNAMIC_TITLE:
+                if (controller instanceof DynamicTitle) {
+                    bundle.putString(META_DATA_PREFERENCE_TITLE,
+                            ((DynamicTitle) controller).getDynamicTitle());
+                    return bundle;
+                }
+                break;
+            case METHOD_GET_DYNAMIC_SUMMARY:
+                if (controller instanceof DynamicSummary) {
+                    bundle.putString(META_DATA_PREFERENCE_SUMMARY,
+                            ((DynamicSummary) controller).getDynamicSummary());
+                    return bundle;
+                }
+                break;
+            case METHOD_IS_CHECKED:
+                bundle.putBoolean(EXTRA_SWITCH_CHECKED_STATE, controller.isChecked());
+                return bundle;
+            case METHOD_ON_CHECKED_CHANGED:
+                return onCheckedChanged(extras.getBoolean(EXTRA_SWITCH_CHECKED_STATE), controller);
+        }
+        return null;
+    }
+
+    private Bundle onCheckedChanged(boolean checked, SwitchController controller) {
+        final boolean success = controller.onCheckedChanged(checked);
+        final Bundle bundle = new Bundle();
+        bundle.putBoolean(EXTRA_SWITCH_SET_CHECKED_ERROR, !success);
+        if (success) {
+            if (controller instanceof DynamicSummary) {
+                controller.notifySummaryChanged(getContext());
+            }
+        } else {
+            bundle.putString(EXTRA_SWITCH_SET_CHECKED_ERROR_MESSAGE,
+                    controller.getErrorMessage(checked));
+        }
+        return bundle;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
index 722f734..1e4c7ca 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
@@ -23,6 +23,7 @@
 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY;
 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY_URI;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SWITCH_URI;
 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE;
 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE_URI;
 import static com.android.settingslib.drawer.TileUtils.PROFILE_ALL;
@@ -79,6 +80,7 @@
     }
 
     Tile(Parcel in) {
+        final boolean isProviderTile = in.readBoolean();
         mComponentPackage = in.readString();
         mComponentName = in.readString();
         mIntent = new Intent().setClassName(mComponentPackage, mComponentName);
@@ -97,6 +99,7 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
+        dest.writeBoolean(this instanceof ProviderTile);
         dest.writeString(mComponentPackage);
         dest.writeString(mComponentName);
         final int size = userHandle.size();
@@ -118,6 +121,12 @@
      */
     public abstract String getDescription();
 
+    protected abstract ComponentInfo getComponentInfo(Context context);
+
+    protected abstract CharSequence getComponentLabel(Context context);
+
+    protected abstract int getComponentIcon(ComponentInfo info);
+
     public String getPackageName() {
         return mComponentPackage;
     }
@@ -164,6 +173,13 @@
     }
 
     /**
+     * Check whether tile has a switch.
+     */
+    public boolean hasSwitch() {
+        return mMetaData != null && mMetaData.containsKey(META_DATA_PREFERENCE_SWITCH_URI);
+    }
+
+    /**
      * Title of the tile that is shown to the user.
      */
     public CharSequence getTitle(Context context) {
@@ -195,8 +211,6 @@
         return title;
     }
 
-    protected abstract CharSequence getComponentLabel(Context context);
-
     /**
      * Overrides the summary. This can happen when injected tile wants to provide dynamic summary.
      */
@@ -293,7 +307,7 @@
             // ICON_URI should be loaded in app UI when need the icon object. Handling IPC at this
             // level is too complex because we don't have a strong threading contract for this class
             if (!mMetaData.containsKey(META_DATA_PREFERENCE_ICON_URI)) {
-                iconResId = componentInfo.icon;
+                iconResId = getComponentIcon(componentInfo);
             }
         }
         if (iconResId != 0) {
@@ -345,11 +359,12 @@
         }
     }
 
-    protected abstract ComponentInfo getComponentInfo(Context context);
-
     public static final Creator<Tile> CREATOR = new Creator<Tile>() {
         public Tile createFromParcel(Parcel source) {
-            return new ActivityTile(source);
+            final boolean isProviderTile = source.readBoolean();
+            // reset the Parcel pointer before delegating to the real constructor.
+            source.setDataPosition(0);
+            return isProviderTile ? new ProviderTile(source) : new ActivityTile(source);
         }
 
         public Tile[] newArray(int size) {
@@ -358,7 +373,7 @@
     };
 
     /**
-     * Check whether title is only have primary profile
+     * Check whether tile only has primary profile.
      */
     public boolean isPrimaryProfileOnly() {
         String profile = mMetaData != null
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
index b9daf7f..71ffff7 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
@@ -16,12 +16,14 @@
 package com.android.settingslib.drawer;
 
 import android.app.ActivityManager;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.IContentProvider;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ComponentInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
 import android.os.Bundle;
@@ -30,6 +32,7 @@
 import android.os.UserManager;
 import android.provider.Settings.Global;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Pair;
 
@@ -96,13 +99,12 @@
      * {@link #EXTRA_SETTINGS_ACTION}
      * The value must be from {@link CategoryKey}.
      */
-    private static final String EXTRA_CATEGORY_KEY = "com.android.settings.category";
+    static final String EXTRA_CATEGORY_KEY = "com.android.settings.category";
 
     /**
      * The key used to get the package name of the icon resource for the preference.
      */
-    private static final String EXTRA_PREFERENCE_ICON_PACKAGE =
-            "com.android.settings.icon_package";
+    static final String EXTRA_PREFERENCE_ICON_PACKAGE = "com.android.settings.icon_package";
 
     /**
      * Name of the meta-data item that should be set in the AndroidManifest.xml
@@ -189,6 +191,17 @@
             "com.android.settings.summary_uri";
 
     /**
+     * Name of the meta-data item that should be set in the AndroidManifest.xml
+     * to specify the content provider providing the switch that should be displayed for the
+     * preference.
+     *
+     * This works with {@link #META_DATA_PREFERENCE_KEYHINT} which should also be set in the
+     * AndroidManifest.xml
+     */
+    public static final String META_DATA_PREFERENCE_SWITCH_URI =
+            "com.android.settings.switch_uri";
+
+    /**
      * Value for {@link #META_DATA_KEY_PROFILE}. When the device has a managed profile,
      * the app will always be run in the primary profile.
      *
@@ -279,6 +292,7 @@
             intent.setPackage(SETTING_PKG);
         }
         getActivityTiles(context, user, addedCache, defaultCategory, outTiles, intent);
+        getProviderTiles(context, user, addedCache, defaultCategory, outTiles, intent);
     }
 
     private static void getActivityTiles(Context context,
@@ -298,6 +312,30 @@
         }
     }
 
+    private static void getProviderTiles(Context context,
+            UserHandle user, Map<Pair<String, String>, Tile> addedCache,
+            String defaultCategory, List<Tile> outTiles, Intent intent) {
+        final PackageManager pm = context.getPackageManager();
+        final List<ResolveInfo> results = pm.queryIntentContentProvidersAsUser(intent,
+                0 /* flags */, user.getIdentifier());
+        for (ResolveInfo resolved : results) {
+            if (!resolved.system) {
+                // Do not allow any app to add to settings, only system ones.
+                continue;
+            }
+            final ProviderInfo providerInfo = resolved.providerInfo;
+            final List<Bundle> switchData = getSwitchDataFromProvider(context,
+                    providerInfo.authority);
+            if (switchData == null || switchData.isEmpty()) {
+                continue;
+            }
+            for (Bundle metaData : switchData) {
+                getTile(user, addedCache, defaultCategory, outTiles, intent, metaData,
+                        providerInfo);
+            }
+        }
+    }
+
     private static void getTile(UserHandle user, Map<Pair<String, String>, Tile> addedCache,
             String defaultCategory, List<Tile> outTiles, Intent intent, Bundle metaData,
             ComponentInfo componentInfo) {
@@ -313,10 +351,16 @@
             categoryKey = metaData.getString(EXTRA_CATEGORY_KEY);
         }
 
-        final Pair<String, String> key = new Pair<>(componentInfo.packageName, componentInfo.name);
+        final boolean isProvider = componentInfo instanceof ProviderInfo;
+        final Pair<String, String> key = isProvider
+                ? new Pair<>(((ProviderInfo) componentInfo).authority,
+                        metaData.getString(META_DATA_PREFERENCE_KEYHINT))
+                : new Pair<>(componentInfo.packageName, componentInfo.name);
         Tile tile = addedCache.get(key);
         if (tile == null) {
-            tile = new ActivityTile(componentInfo, categoryKey);
+            tile = isProvider
+                    ? new ProviderTile(componentInfo, categoryKey, metaData)
+                    : new ActivityTile(componentInfo, categoryKey);
             addedCache.put(key, tile);
         } else {
             tile.setMetaData(metaData);
@@ -330,20 +374,75 @@
         }
     }
 
+    /** Returns the switch data of the key specified from the provider */
+    // TODO(b/144732809): rearrange methods by access level modifiers
+    static Bundle getSwitchDataFromProvider(Context context, String authority, String key) {
+        final Map<String, IContentProvider> providerMap = new ArrayMap<>();
+        final Uri uri = buildUri(authority, SwitchesProvider.METHOD_GET_SWITCH_DATA, key);
+        return getBundleFromUri(context, uri, providerMap, null /* bundle */);
+    }
+
+    /** Returns all switch data from the provider */
+    private static List<Bundle> getSwitchDataFromProvider(Context context, String authority) {
+        final Map<String, IContentProvider> providerMap = new ArrayMap<>();
+        final Uri uri = buildUri(authority, SwitchesProvider.METHOD_GET_SWITCH_DATA);
+        final Bundle result = getBundleFromUri(context, uri, providerMap, null /* bundle */);
+        return result != null
+                ? result.getParcelableArrayList(SwitchesProvider.EXTRA_SWITCH_DATA)
+                : null;
+    }
+
     /**
      * Returns the complete uri from the meta data key of the tile.
-
+     *
+     * A complete uri should contain at least one path segment and be one of the following types:
+     *      content://authority/method
+     *      content://authority/method/key
+     *
+     * If the uri from the tile is not complete, build a uri by the default method and the
+     * preference key.
+     *
      * @param tile          Tile which contains meta data
      * @param metaDataKey   Key mapping to the uri in meta data
+     * @param defaultMethod Method to be attached to the uri by default if it has no path segment
      * @return Uri associated with the key
      */
-    public static Uri getCompleteUri(Tile tile, String metaDataKey) {
+    public static Uri getCompleteUri(Tile tile, String metaDataKey, String defaultMethod) {
         final String uriString = tile.getMetaData().getString(metaDataKey);
         if (TextUtils.isEmpty(uriString)) {
             return null;
         }
 
-        return Uri.parse(uriString);
+        final Uri uri = Uri.parse(uriString);
+        final List<String> pathSegments = uri.getPathSegments();
+        if (pathSegments != null && !pathSegments.isEmpty()) {
+            return uri;
+        }
+
+        final String key = tile.getMetaData().getString(META_DATA_PREFERENCE_KEYHINT);
+        if (TextUtils.isEmpty(key)) {
+            Log.w(LOG_TAG, "Please specify the meta-data " + META_DATA_PREFERENCE_KEYHINT
+                    + " in AndroidManifest.xml for " + uriString);
+            return buildUri(uri.getAuthority(), defaultMethod);
+        }
+        return buildUri(uri.getAuthority(), defaultMethod, key);
+    }
+
+    static Uri buildUri(String authority, String method, String key) {
+        return new Uri.Builder()
+                .scheme(ContentResolver.SCHEME_CONTENT)
+                .authority(authority)
+                .appendPath(method)
+                .appendPath(key)
+                .build();
+    }
+
+    private static Uri buildUri(String authority, String method) {
+        return new Uri.Builder()
+                .scheme(ContentResolver.SCHEME_CONTENT)
+                .authority(authority)
+                .appendPath(method)
+                .build();
     }
 
     /**
@@ -357,7 +456,7 @@
      */
     public static Pair<String, Integer> getIconFromUri(Context context, String packageName,
             Uri uri, Map<String, IContentProvider> providerMap) {
-        final Bundle bundle = getBundleFromUri(context, uri, providerMap, null);
+        final Bundle bundle = getBundleFromUri(context, uri, providerMap, null /* bundle */);
         if (bundle == null) {
             return null;
         }
@@ -388,16 +487,50 @@
      */
     public static String getTextFromUri(Context context, Uri uri,
             Map<String, IContentProvider> providerMap, String key) {
-        final Bundle bundle = getBundleFromUri(context, uri, providerMap, null);
+        final Bundle bundle = getBundleFromUri(context, uri, providerMap, null /* bundle */);
         return (bundle != null) ? bundle.getString(key) : null;
     }
 
+    /**
+     * Gets boolean associated with the input key from the content provider.
+     *
+     * @param context     context
+     * @param uri         URI for the content provider
+     * @param providerMap Maps URI authorities to providers
+     * @param key         Key mapping to the text in bundle returned by the content provider
+     * @return Boolean associated with the key, if returned by the content provider
+     */
+    public static boolean getBooleanFromUri(Context context, Uri uri,
+            Map<String, IContentProvider> providerMap, String key) {
+        final Bundle bundle = getBundleFromUri(context, uri, providerMap, null /* bundle */);
+        return (bundle != null) ? bundle.getBoolean(key) : false;
+    }
+
+    /**
+     * Puts boolean associated with the input key to the content provider.
+     *
+     * @param context     context
+     * @param uri         URI for the content provider
+     * @param providerMap Maps URI authorities to providers
+     * @param key         Key mapping to the text in bundle returned by the content provider
+     * @param value       Boolean associated with the key
+     * @return Bundle associated with the action, if returned by the content provider
+     */
+    public static Bundle putBooleanToUri(Context context, Uri uri,
+            Map<String, IContentProvider> providerMap, String key, boolean value) {
+        final Bundle bundle = new Bundle();
+        bundle.putBoolean(key, value);
+        return getBundleFromUri(context, uri, providerMap, bundle);
+    }
+
     private static Bundle getBundleFromUri(Context context, Uri uri,
             Map<String, IContentProvider> providerMap, Bundle bundle) {
-        if (uri == null) {
+        final Pair<String, String> args = getMethodAndKey(uri);
+        if (args == null) {
             return null;
         }
-        final String method = getMethodFromUri(uri);
+        final String method = args.first;
+        final String key = args.second;
         if (TextUtils.isEmpty(method)) {
             return null;
         }
@@ -405,6 +538,12 @@
         if (provider == null) {
             return null;
         }
+        if (!TextUtils.isEmpty(key)) {
+            if (bundle == null) {
+                bundle = new Bundle();
+            }
+            bundle.putString(META_DATA_PREFERENCE_KEYHINT, key);
+        }
         try {
             return provider.call(context.getPackageName(), context.getFeatureId(),
                     uri.getAuthority(), method, uri.toString(), bundle);
@@ -428,15 +567,17 @@
         return providerMap.get(authority);
     }
 
-    /** Returns the first path segment of the uri if it exists as the method, otherwise null. */
-    private static String getMethodFromUri(Uri uri) {
+    /** Returns method and key of the complete uri. */
+    private static Pair<String, String> getMethodAndKey(Uri uri) {
         if (uri == null) {
             return null;
         }
-        List<String> pathSegments = uri.getPathSegments();
-        if ((pathSegments == null) || pathSegments.isEmpty()) {
+        final List<String> pathSegments = uri.getPathSegments();
+        if (pathSegments == null || pathSegments.isEmpty()) {
             return null;
         }
-        return pathSegments.get(0);
+        final String method = pathSegments.get(0);
+        final String key = pathSegments.size() > 1 ? pathSegments.get(1) : null;
+        return Pair.create(method, key);
     }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/ActivityTileTest.java
similarity index 90%
rename from packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java
rename to packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/ActivityTileTest.java
index 2664ecd..4f8ecf8 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/ActivityTileTest.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2019 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.settingslib.drawer;
 
 import static com.android.settingslib.drawer.TileUtils.META_DATA_KEY_ORDER;
@@ -25,7 +40,7 @@
 import org.robolectric.shadows.ShadowPackageManager;
 
 @RunWith(RobolectricTestRunner.class)
-public class TileTest {
+public class ActivityTileTest {
 
     private Context mContext;
     private ActivityInfo mActivityInfo;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/ProviderTileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/ProviderTileTest.java
new file mode 100644
index 0000000..abfb407
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/ProviderTileTest.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2019 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.settingslib.drawer;
+
+import static com.android.settingslib.drawer.TileUtils.META_DATA_KEY_ORDER;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_KEY_PROFILE;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE;
+import static com.android.settingslib.drawer.TileUtils.PROFILE_ALL;
+import static com.android.settingslib.drawer.TileUtils.PROFILE_PRIMARY;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowPackageManager;
+
+@RunWith(RobolectricTestRunner.class)
+public class ProviderTileTest {
+
+    @Rule
+    public final ExpectedException thrown = ExpectedException.none();
+
+    private Context mContext;
+    private ProviderInfo mProviderInfo;
+    private Bundle mMetaData;
+    private Tile mTile;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mProviderInfo = new ProviderInfo();
+        mProviderInfo.applicationInfo = new ApplicationInfo();
+        mProviderInfo.packageName = mContext.getPackageName();
+        mProviderInfo.name = "abc";
+        mProviderInfo.authority = "authority";
+        mMetaData = new Bundle();
+        mMetaData.putString(META_DATA_PREFERENCE_KEYHINT, "key");
+        mMetaData.putString(META_DATA_PREFERENCE_TITLE, "title");
+        mMetaData.putInt(META_DATA_PREFERENCE_ICON, com.android.internal.R.drawable.ic_plus);
+        mTile = new ProviderTile(mProviderInfo, "category", mMetaData);
+    }
+
+    @Test
+    public void isPrimaryProfileOnly_profilePrimary_shouldReturnTrue() {
+        mMetaData.putString(META_DATA_KEY_PROFILE, PROFILE_PRIMARY);
+        assertThat(mTile.isPrimaryProfileOnly()).isTrue();
+    }
+
+    @Test
+    public void isPrimaryProfileOnly_profileAll_shouldReturnFalse() {
+        mMetaData.putString(META_DATA_KEY_PROFILE, PROFILE_ALL);
+        assertThat(mTile.isPrimaryProfileOnly()).isFalse();
+    }
+
+    @Test
+    public void isPrimaryProfileOnly_noExplicitValue_shouldReturnFalse() {
+        assertThat(mTile.isPrimaryProfileOnly()).isFalse();
+    }
+
+    @Test
+    public void getIcon_noContextOrMetadata_shouldThrowNullPointerException() {
+        thrown.expect(NullPointerException.class);
+
+        final Tile tile = new ProviderTile(mProviderInfo, "category", null);
+    }
+
+    @Test
+    public void getIcon_hasIconMetadata_returnIcon() {
+        mMetaData.putInt(META_DATA_PREFERENCE_ICON, android.R.drawable.ic_info);
+
+        assertThat(mTile.getIcon(RuntimeEnvironment.application).getResId())
+                .isEqualTo(android.R.drawable.ic_info);
+    }
+
+    @Test
+    public void isIconTintable_hasMetadata_shouldReturnIconTintableMetadata() {
+        final Tile tile = new ProviderTile(mProviderInfo, "category", mMetaData);
+
+        mMetaData.putBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE, false);
+        assertThat(tile.isIconTintable(RuntimeEnvironment.application)).isFalse();
+
+        mMetaData.putBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE, true);
+        assertThat(tile.isIconTintable(RuntimeEnvironment.application)).isTrue();
+    }
+
+    @Test
+    public void isIconTintable_noIcon_shouldReturnFalse() {
+        final Tile tile = new ProviderTile(mProviderInfo, "category", mMetaData);
+
+        assertThat(tile.isIconTintable(RuntimeEnvironment.application)).isFalse();
+    }
+
+    @Test
+    public void isIconTintable_noTintableMetadata_shouldReturnFalse() {
+        final Tile tile = new ProviderTile(mProviderInfo, "category", mMetaData);
+        mMetaData.putInt(META_DATA_PREFERENCE_ICON, android.R.drawable.ic_info);
+
+        assertThat(tile.isIconTintable(RuntimeEnvironment.application)).isFalse();
+    }
+
+    @Test
+    public void getPriority_noMetadata_return0() {
+        final Tile tile = new ProviderTile(mProviderInfo, "category", mMetaData);
+
+        assertThat(tile.getOrder()).isEqualTo(0);
+    }
+
+    @Test
+    public void getPriority_badMetadata_return0() {
+        mMetaData.putString(META_DATA_KEY_ORDER, "1");
+
+        final Tile tile = new ProviderTile(mProviderInfo, "category", mMetaData);
+
+        assertThat(tile.getOrder()).isEqualTo(0);
+    }
+
+    @Test
+    public void getPriority_validMetadata_returnMetadataValue() {
+        mMetaData.putInt(META_DATA_KEY_ORDER, 1);
+
+        final Tile tile = new ProviderTile(mProviderInfo, "category", mMetaData);
+
+        assertThat(tile.getOrder()).isEqualTo(1);
+    }
+
+    @Test
+    @Config(shadows = ShadowTileUtils.class)
+    public void getTitle_shouldEnsureMetadataNotStale() {
+        final ResolveInfo info = new ResolveInfo();
+        info.providerInfo = mProviderInfo;
+        final ShadowPackageManager spm = Shadow.extract(mContext.getPackageManager());
+        spm.addResolveInfoForIntent(
+                new Intent().setClassName(mProviderInfo.packageName, mProviderInfo.name), info);
+        ShadowTileUtils.setMetaData(mMetaData);
+
+        final Tile tile = new ProviderTile(mProviderInfo, "category", mMetaData);
+        final long staleTimeStamp = -10000;
+        tile.mLastUpdateTime = staleTimeStamp;
+
+        tile.getTitle(RuntimeEnvironment.application);
+
+        assertThat(tile.mLastUpdateTime).isNotEqualTo(staleTimeStamp);
+    }
+
+    @Implements(TileUtils.class)
+    private static class ShadowTileUtils {
+
+        private static Bundle sMetaData;
+
+        @Implementation
+        protected static Bundle getSwitchDataFromProvider(Context context, String authority,
+                String key) {
+            return sMetaData;
+        }
+
+        private static void setMetaData(Bundle metaData) {
+            sMetaData = metaData;
+        }
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/SwitchesProviderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/SwitchesProviderTest.java
new file mode 100644
index 0000000..27b3697
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/SwitchesProviderTest.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) 2019 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.settingslib.drawer;
+
+import static com.android.settingslib.drawer.SwitchesProvider.EXTRA_SWITCH_CHECKED_STATE;
+import static com.android.settingslib.drawer.SwitchesProvider.EXTRA_SWITCH_DATA;
+import static com.android.settingslib.drawer.SwitchesProvider.EXTRA_SWITCH_SET_CHECKED_ERROR;
+import static com.android.settingslib.drawer.SwitchesProvider.EXTRA_SWITCH_SET_CHECKED_ERROR_MESSAGE;
+import static com.android.settingslib.drawer.SwitchesProvider.METHOD_GET_DYNAMIC_SUMMARY;
+import static com.android.settingslib.drawer.SwitchesProvider.METHOD_GET_DYNAMIC_TITLE;
+import static com.android.settingslib.drawer.SwitchesProvider.METHOD_GET_PROVIDER_ICON;
+import static com.android.settingslib.drawer.SwitchesProvider.METHOD_GET_SWITCH_DATA;
+import static com.android.settingslib.drawer.SwitchesProvider.METHOD_IS_CHECKED;
+import static com.android.settingslib.drawer.SwitchesProvider.METHOD_ON_CHECKED_CHANGED;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.content.pm.ProviderInfo;
+import android.os.Bundle;
+
+import com.android.settingslib.drawer.SwitchController.MetaData;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public class SwitchesProviderTest {
+
+    @Rule
+    public final ExpectedException thrown = ExpectedException.none();
+
+    private Context mContext;
+    private ProviderInfo mProviderInfo;
+
+    private TestSwitchesProvider mSwitchesProvider;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mSwitchesProvider = new TestSwitchesProvider();
+        mProviderInfo = new ProviderInfo();
+        mProviderInfo.authority = "auth";
+    }
+
+    @Test
+    public void attachInfo_noController_shouldThrowIllegalArgumentException() {
+        thrown.expect(IllegalArgumentException.class);
+
+        mSwitchesProvider.attachInfo(mContext, mProviderInfo);
+    }
+
+    @Test
+    public void attachInfo_NoSwitchKeyInController_shouldThrowNullPointerException() {
+        thrown.expect(NullPointerException.class);
+        final TestSwitchController controller = new TestSwitchController();
+        mSwitchesProvider.addSwitchController(controller);
+
+        mSwitchesProvider.attachInfo(mContext, mProviderInfo);
+    }
+
+    @Test
+    public void attachInfo_NoMetaDataInController_shouldThrowIllegalArgumentException() {
+        thrown.expect(IllegalArgumentException.class);
+        final TestSwitchController controller = new TestSwitchController();
+        controller.setKey("123");
+        mSwitchesProvider.addSwitchController(controller);
+
+        mSwitchesProvider.attachInfo(mContext, mProviderInfo);
+    }
+
+    @Test
+    public void attachInfo_duplicateSwitchKey_shouldThrowIllegalArgumentException() {
+        thrown.expect(IllegalArgumentException.class);
+        final TestSwitchController controller1 = new TestSwitchController();
+        final TestSwitchController controller2 = new TestSwitchController();
+        controller1.setKey("123");
+        controller2.setKey("123");
+        controller1.setMetaData(new MetaData("category"));
+        controller2.setMetaData(new MetaData("category"));
+        mSwitchesProvider.addSwitchController(controller1);
+        mSwitchesProvider.addSwitchController(controller2);
+
+        mSwitchesProvider.attachInfo(mContext, mProviderInfo);
+    }
+
+    @Test
+    public void attachInfo_hasDifferentControllers_shouldNotThrowException() {
+        final TestSwitchController controller1 = new TestSwitchController();
+        final TestSwitchController controller2 = new TestSwitchController();
+        controller1.setKey("123");
+        controller2.setKey("456");
+        controller1.setMetaData(new MetaData("category"));
+        controller2.setMetaData(new MetaData("category"));
+        mSwitchesProvider.addSwitchController(controller1);
+        mSwitchesProvider.addSwitchController(controller2);
+
+        mSwitchesProvider.attachInfo(mContext, mProviderInfo);
+    }
+
+    @Test
+    public void getSwitchData_shouldReturnDataList() {
+        final TestSwitchController controller = new TestSwitchController();
+        controller.setKey("123");
+        controller.setMetaData(new MetaData("category"));
+        mSwitchesProvider.addSwitchController(controller);
+        mSwitchesProvider.attachInfo(mContext, mProviderInfo);
+
+        final Bundle switchData = mSwitchesProvider.call(METHOD_GET_SWITCH_DATA, "uri" ,
+                null /* extras*/);
+
+        final ArrayList<Bundle> dataList = switchData.getParcelableArrayList(EXTRA_SWITCH_DATA);
+        assertThat(dataList).hasSize(1);
+        assertThat(dataList.get(0).getString(META_DATA_PREFERENCE_KEYHINT)).isEqualTo("123");
+    }
+
+    @Test
+    public void getSwitchDataByKey_shouldReturnData() {
+        final Bundle extras = new Bundle();
+        extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
+        final TestSwitchController controller = new TestSwitchController();
+        controller.setKey("123");
+        controller.setMetaData(new MetaData("category"));
+        mSwitchesProvider.addSwitchController(controller);
+        mSwitchesProvider.attachInfo(mContext, mProviderInfo);
+
+        final Bundle switchData = mSwitchesProvider.call(METHOD_GET_SWITCH_DATA, "uri" , extras);
+
+        assertThat(switchData.getString(META_DATA_PREFERENCE_KEYHINT)).isEqualTo("123");
+    }
+
+    @Test
+    public void isChecked_shouldReturnCheckedState() {
+        final Bundle extras = new Bundle();
+        extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
+        final TestSwitchController controller = new TestSwitchController();
+        controller.setKey("123");
+        controller.setMetaData(new MetaData("category"));
+        mSwitchesProvider.addSwitchController(controller);
+        mSwitchesProvider.attachInfo(mContext, mProviderInfo);
+
+        controller.setChecked(true);
+        Bundle result = mSwitchesProvider.call(METHOD_IS_CHECKED, "uri" , extras);
+
+        assertThat(result.getBoolean(EXTRA_SWITCH_CHECKED_STATE)).isTrue();
+
+        controller.setChecked(false);
+        result = mSwitchesProvider.call(METHOD_IS_CHECKED, "uri" , extras);
+
+        assertThat(result.getBoolean(EXTRA_SWITCH_CHECKED_STATE)).isFalse();
+    }
+
+    @Test
+    public void getProviderIcon_noImplementInterface_shouldReturnNull() {
+        final Bundle extras = new Bundle();
+        extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
+        final TestSwitchController controller = new TestSwitchController();
+        controller.setKey("123");
+        controller.setMetaData(new MetaData("category"));
+        mSwitchesProvider.addSwitchController(controller);
+        mSwitchesProvider.attachInfo(mContext, mProviderInfo);
+
+        final Bundle iconBundle = mSwitchesProvider.call(METHOD_GET_PROVIDER_ICON, "uri" , extras);
+
+        assertThat(iconBundle).isNull();
+    }
+
+    @Test
+    public void getProviderIcon_implementInterface_shouldReturnIcon() {
+        final Bundle extras = new Bundle();
+        extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
+        final TestSwitchController controller = new TestDynamicSwitchController();
+        controller.setKey("123");
+        controller.setMetaData(new MetaData("category"));
+        mSwitchesProvider.addSwitchController(controller);
+        mSwitchesProvider.attachInfo(mContext, mProviderInfo);
+
+        final Bundle iconBundle = mSwitchesProvider.call(METHOD_GET_PROVIDER_ICON, "uri" , extras);
+
+        assertThat(iconBundle).isEqualTo(TestDynamicSwitchController.ICON_BUNDLE);
+    }
+
+    @Test
+    public void getDynamicTitle_noImplementInterface_shouldReturnNull() {
+        final Bundle extras = new Bundle();
+        extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
+        final TestSwitchController controller = new TestSwitchController();
+        controller.setKey("123");
+        controller.setMetaData(new MetaData("category"));
+        mSwitchesProvider.addSwitchController(controller);
+        mSwitchesProvider.attachInfo(mContext, mProviderInfo);
+
+        final Bundle result = mSwitchesProvider.call(METHOD_GET_DYNAMIC_TITLE, "uri" , extras);
+
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void getDynamicTitle_implementInterface_shouldReturnTitle() {
+        final Bundle extras = new Bundle();
+        extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
+        final TestSwitchController controller = new TestDynamicSwitchController();
+        controller.setKey("123");
+        controller.setMetaData(new MetaData("category"));
+        mSwitchesProvider.addSwitchController(controller);
+        mSwitchesProvider.attachInfo(mContext, mProviderInfo);
+
+        final Bundle result = mSwitchesProvider.call(METHOD_GET_DYNAMIC_TITLE, "uri" , extras);
+
+        assertThat(result.getString(META_DATA_PREFERENCE_TITLE))
+                .isEqualTo(TestDynamicSwitchController.TITLE);
+    }
+
+    @Test
+    public void getDynamicSummary_noImplementInterface_shouldReturnNull() {
+        final Bundle extras = new Bundle();
+        extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
+        final TestSwitchController controller = new TestSwitchController();
+        controller.setKey("123");
+        controller.setMetaData(new MetaData("category"));
+        mSwitchesProvider.addSwitchController(controller);
+        mSwitchesProvider.attachInfo(mContext, mProviderInfo);
+
+        final Bundle result = mSwitchesProvider.call(METHOD_GET_DYNAMIC_SUMMARY, "uri" , extras);
+
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void getDynamicSummary_implementInterface_shouldReturnSummary() {
+        final Bundle extras = new Bundle();
+        extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
+        final TestSwitchController controller = new TestDynamicSwitchController();
+        controller.setKey("123");
+        controller.setMetaData(new MetaData("category"));
+        mSwitchesProvider.addSwitchController(controller);
+        mSwitchesProvider.attachInfo(mContext, mProviderInfo);
+
+        final Bundle result = mSwitchesProvider.call(METHOD_GET_DYNAMIC_SUMMARY, "uri" , extras);
+
+        assertThat(result.getString(META_DATA_PREFERENCE_SUMMARY))
+                .isEqualTo(TestDynamicSwitchController.SUMMARY);
+    }
+
+    @Test
+    public void onCheckedChangedSuccess_shouldReturnNoError() {
+        final Bundle extras = new Bundle();
+        extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
+        final TestSwitchController controller = new TestSwitchController();
+        controller.setKey("123");
+        controller.setMetaData(new MetaData("category"));
+        mSwitchesProvider.addSwitchController(controller);
+        mSwitchesProvider.attachInfo(mContext, mProviderInfo);
+
+        final Bundle result = mSwitchesProvider.call(METHOD_ON_CHECKED_CHANGED, "uri" , extras);
+
+        assertThat(result.getBoolean(EXTRA_SWITCH_SET_CHECKED_ERROR)).isFalse();
+    }
+
+    @Test
+    public void onCheckedChangedFailed_shouldReturnErrorMessage() {
+        final Bundle extras = new Bundle();
+        extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
+        final TestSwitchController controller = new TestSwitchController();
+        controller.setKey("123");
+        controller.setMetaData(new MetaData("category"));
+        controller.setErrorMessage("error");
+        mSwitchesProvider.addSwitchController(controller);
+        mSwitchesProvider.attachInfo(mContext, mProviderInfo);
+
+        final Bundle result = mSwitchesProvider.call(METHOD_ON_CHECKED_CHANGED, "uri" , extras);
+
+        assertThat(result.getBoolean(EXTRA_SWITCH_SET_CHECKED_ERROR)).isTrue();
+        assertThat(result.getString(EXTRA_SWITCH_SET_CHECKED_ERROR_MESSAGE)).isEqualTo("error");
+    }
+
+    private class TestSwitchesProvider extends SwitchesProvider {
+
+        private List<SwitchController> mControllers;
+
+        @Override
+        protected List<SwitchController> createSwitchControllers() {
+            return mControllers;
+        }
+
+        void addSwitchController(SwitchController controller) {
+            if (mControllers == null) {
+                mControllers = new ArrayList<>();
+            }
+            mControllers.add(controller);
+        }
+    }
+
+    private static class TestSwitchController extends SwitchController {
+
+        private String mKey;
+        private MetaData mMetaData;
+        private boolean mChecked;
+        private String mErrorMsg;
+
+        @Override
+        public String getSwitchKey() {
+            return mKey;
+        }
+
+        @Override
+        protected MetaData getMetaData() {
+            return mMetaData;
+        }
+
+        @Override
+        protected boolean isChecked() {
+            return mChecked;
+        }
+
+        @Override
+        protected boolean onCheckedChanged(boolean checked) {
+            return mErrorMsg == null ? true : false;
+        }
+
+        @Override
+        protected String getErrorMessage(boolean attemptedChecked) {
+            return mErrorMsg;
+        }
+
+        void setKey(String key) {
+            mKey = key;
+        }
+
+        void setMetaData(MetaData metaData) {
+            mMetaData = metaData;
+        }
+
+        void setChecked(boolean checked) {
+            mChecked = checked;
+        }
+
+        void setErrorMessage(String errorMsg) {
+            mErrorMsg = errorMsg;
+        }
+    }
+
+    private static class TestDynamicSwitchController extends TestSwitchController
+            implements ProviderIcon, DynamicTitle, DynamicSummary {
+
+        static final String TITLE = "title";
+        static final String SUMMARY = "summary";
+        static final Bundle ICON_BUNDLE = new Bundle();
+
+        @Override
+        public Bundle getProviderIcon() {
+            return ICON_BUNDLE;
+        }
+
+        @Override
+        public String getDynamicTitle() {
+            return TITLE;
+        }
+
+        @Override
+        public String getDynamicSummary() {
+            return SUMMARY;
+        }
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
index aa1ac4e..b36eb49 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
@@ -44,6 +44,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.os.Bundle;
@@ -60,12 +61,17 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = TileUtilsTest.ShadowTileUtils.class)
 public class TileUtilsTest {
 
     private Context mContext;
@@ -104,12 +110,15 @@
         info.add(newInfo(true, testCategory));
         when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
                 .thenReturn(info);
+        when(mPackageManager.queryIntentContentProvidersAsUser(any(Intent.class), anyInt(),
+                anyInt())).thenReturn(info);
 
         TileUtils.getTilesForAction(mContext, UserHandle.CURRENT, IA_SETTINGS_ACTION, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */);
 
-        assertThat(outTiles.size()).isEqualTo(1);
+        assertThat(outTiles).hasSize(2);
         assertThat(outTiles.get(0).getCategory()).isEqualTo(testCategory);
+        assertThat(outTiles.get(1).getCategory()).isEqualTo(testCategory);
     }
 
     @Test
@@ -123,12 +132,15 @@
 
         when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
                 .thenReturn(info);
+        when(mPackageManager.queryIntentContentProvidersAsUser(any(Intent.class), anyInt(),
+                anyInt())).thenReturn(info);
 
         TileUtils.getTilesForAction(mContext, UserHandle.CURRENT, IA_SETTINGS_ACTION, addedCache,
                 null /* defaultCategory */, outTiles, false /* requiresSettings */);
 
-        assertThat(outTiles).hasSize(1);
+        assertThat(outTiles).hasSize(2);
         assertThat(outTiles.get(0).getKey(mContext)).isEqualTo(keyHint);
+        assertThat(outTiles.get(1).getKey(mContext)).isEqualTo(keyHint);
     }
 
     @Test
@@ -141,6 +153,8 @@
 
         when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
                 .thenReturn(info);
+        when(mPackageManager.queryIntentContentProvidersAsUser(any(Intent.class), anyInt(),
+                anyInt())).thenReturn(info);
 
         TileUtils.getTilesForAction(mContext, UserHandle.CURRENT, IA_SETTINGS_ACTION,
                 addedCache, null /* defaultCategory */, outTiles, false /* requiresSettings */);
@@ -162,6 +176,8 @@
         TileUtils.getCategories(mContext, cache);
         verify(mPackageManager, atLeastOnce()).queryIntentActivitiesAsUser(
                 intentCaptor.capture(), anyInt(), anyInt());
+        verify(mPackageManager, atLeastOnce()).queryIntentContentProvidersAsUser(
+                intentCaptor.capture(), anyInt(), anyInt());
 
         assertThat(intentCaptor.getAllValues().get(0).getPackage())
                 .isEqualTo(TileUtils.SETTING_PKG);
@@ -178,12 +194,15 @@
 
         when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
                 .thenReturn(info);
+        when(mPackageManager.queryIntentContentProvidersAsUser(any(Intent.class), anyInt(),
+                anyInt())).thenReturn(info);
 
         TileUtils.getTilesForAction(mContext, UserHandle.CURRENT, IA_SETTINGS_ACTION, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */);
 
-        assertThat(outTiles.size()).isEqualTo(1);
+        assertThat(outTiles).hasSize(2);
         assertThat(outTiles.get(0).getTitle(mContext)).isEqualTo("my title");
+        assertThat(outTiles.get(1).getTitle(mContext)).isEqualTo("my title");
     }
 
     @Test
@@ -197,14 +216,17 @@
 
         when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
                 .thenReturn(info);
+        when(mPackageManager.queryIntentContentProvidersAsUser(any(Intent.class), anyInt(),
+                anyInt())).thenReturn(info);
 
         when(mResources.getString(eq(123)))
                 .thenReturn("my localized title");
 
         TileUtils.getTilesForAction(mContext, UserHandle.CURRENT, IA_SETTINGS_ACTION, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */);
-        assertThat(outTiles.size()).isEqualTo(1);
+        assertThat(outTiles).hasSize(2);
         assertThat(outTiles.get(0).getTitle(mContext)).isEqualTo("my localized title");
+        assertThat(outTiles.get(1).getTitle(mContext)).isEqualTo("my localized title");
     }
 
     @Test
@@ -220,11 +242,14 @@
 
         when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
                 .thenReturn(info);
+        when(mPackageManager.queryIntentContentProvidersAsUser(any(Intent.class), anyInt(),
+                anyInt())).thenReturn(info);
 
         TileUtils.getTilesForAction(mContext, UserHandle.CURRENT, IA_SETTINGS_ACTION, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */);
 
         assertThat(outTiles.get(0).isIconTintable(mContext)).isFalse();
+        assertThat(outTiles.get(1).isIconTintable(mContext)).isFalse();
     }
 
     @Test
@@ -259,7 +284,6 @@
         assertThat(newMetaData).isNotSameAs(oldMetadata);
     }
 
-
     @Test
     public void getTilesForIntent_shouldMarkIconTintableIfMetadataSet() {
         Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
@@ -273,11 +297,14 @@
 
         when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
                 .thenReturn(info);
+        when(mPackageManager.queryIntentContentProvidersAsUser(any(Intent.class), anyInt(),
+                anyInt())).thenReturn(info);
 
         TileUtils.getTilesForAction(mContext, UserHandle.CURRENT, IA_SETTINGS_ACTION, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */);
 
         assertThat(outTiles.get(0).isIconTintable(mContext)).isTrue();
+        assertThat(outTiles.get(1).isIconTintable(mContext)).isTrue();
     }
 
     @Test
@@ -291,11 +318,13 @@
 
         when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
                 .thenReturn(info);
+        when(mPackageManager.queryIntentContentProvidersAsUser(any(Intent.class), anyInt(),
+                anyInt())).thenReturn(info);
 
         TileUtils.getTilesForAction(mContext, UserHandle.CURRENT, IA_SETTINGS_ACTION, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */);
 
-        assertThat(outTiles.size()).isEqualTo(1);
+        assertThat(outTiles).hasSize(2);
     }
 
     public static ResolveInfo newInfo(boolean systemApp, String category) {
@@ -314,33 +343,66 @@
     private static ResolveInfo newInfo(boolean systemApp, String category, String keyHint,
             String iconUri, String summaryUri, String title, int titleResId) {
 
-        ResolveInfo info = new ResolveInfo();
+        final Bundle metaData = newMetaData(category, keyHint, iconUri, summaryUri, title,
+                titleResId);
+        final ResolveInfo info = new ResolveInfo();
         info.system = systemApp;
+
         info.activityInfo = new ActivityInfo();
         info.activityInfo.packageName = "abc";
         info.activityInfo.name = "123";
-        info.activityInfo.metaData = new Bundle();
-        info.activityInfo.metaData.putString("com.android.settings.category", category);
-        info.activityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON, 314159);
-        info.activityInfo.metaData.putString(META_DATA_PREFERENCE_SUMMARY, "static-summary");
-        if (keyHint != null) {
-            info.activityInfo.metaData.putString(META_DATA_PREFERENCE_KEYHINT, keyHint);
-        }
-        if (iconUri != null) {
-            info.activityInfo.metaData.putString(META_DATA_PREFERENCE_ICON_URI, iconUri);
-        }
-        if (summaryUri != null) {
-            info.activityInfo.metaData.putString(META_DATA_PREFERENCE_SUMMARY_URI, summaryUri);
-        }
-        if (titleResId != 0) {
-            info.activityInfo.metaData.putInt(TileUtils.META_DATA_PREFERENCE_TITLE, titleResId);
-        } else if (title != null) {
-            info.activityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_TITLE, title);
-        }
+        info.activityInfo.metaData = metaData;
         info.activityInfo.applicationInfo = new ApplicationInfo();
+
+        info.providerInfo = new ProviderInfo();
+        info.providerInfo.packageName = "abc";
+        info.providerInfo.name = "456";
+        info.providerInfo.authority = "auth";
+        ShadowTileUtils.setMetaData(metaData);
+        info.providerInfo.applicationInfo = new ApplicationInfo();
+
         if (systemApp) {
             info.activityInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+            info.providerInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
         }
         return info;
     }
+
+    private static Bundle newMetaData(String category, String keyHint, String iconUri,
+            String summaryUri, String title, int titleResId) {
+        final Bundle metaData = new Bundle();
+        metaData.putString("com.android.settings.category", category);
+        metaData.putInt(META_DATA_PREFERENCE_ICON, 314159);
+        metaData.putString(META_DATA_PREFERENCE_SUMMARY, "static-summary");
+        if (keyHint != null) {
+            metaData.putString(META_DATA_PREFERENCE_KEYHINT, keyHint);
+        }
+        if (iconUri != null) {
+            metaData.putString(META_DATA_PREFERENCE_ICON_URI, iconUri);
+        }
+        if (summaryUri != null) {
+            metaData.putString(META_DATA_PREFERENCE_SUMMARY_URI, summaryUri);
+        }
+        if (titleResId != 0) {
+            metaData.putInt(TileUtils.META_DATA_PREFERENCE_TITLE, titleResId);
+        } else if (title != null) {
+            metaData.putString(TileUtils.META_DATA_PREFERENCE_TITLE, title);
+        }
+        return metaData;
+    }
+
+    @Implements(TileUtils.class)
+    static class ShadowTileUtils {
+
+        private static Bundle sMetaData;
+
+        @Implementation
+        protected static List<Bundle> getSwitchDataFromProvider(Context context, String authority) {
+            return Arrays.asList(sMetaData);
+        }
+
+        private static void setMetaData(Bundle metaData) {
+            sMetaData = metaData;
+        }
+    }
 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
index 1e75fe7..fdbbc39 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
@@ -196,7 +196,9 @@
                 case LIST:
                     if (namespace != null) {
                         DeviceConfig.Properties properties = DeviceConfig.getProperties(namespace);
-                        for (String name : properties.getKeyset()) {
+                        List<String> keys = new ArrayList<>(properties.getKeyset());
+                        Collections.sort(keys);
+                        for (String name : keys) {
                             pout.println(name + "=" + properties.getString(name, null));
                         }
                     } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index ca11430..7c0f4f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -42,7 +42,7 @@
 import android.os.Message;
 import android.util.Pair;
 import android.util.SparseArray;
-import android.view.InsetsState.InternalInsetType;
+import android.view.InsetsState.InternalInsetsType;
 import android.view.WindowInsetsController.Appearance;
 
 import com.android.internal.os.SomeArgs;
@@ -284,12 +284,12 @@
         /**
          * @see IStatusBar#showTransient(int, int[]).
          */
-        default void showTransient(int displayId, @InternalInsetType int[] types) { }
+        default void showTransient(int displayId, @InternalInsetsType int[] types) { }
 
         /**
          * @see IStatusBar#abortTransient(int, int[]).
          */
-        default void abortTransient(int displayId, @InternalInsetType int[] types) { }
+        default void abortTransient(int displayId, @InternalInsetsType int[] types) { }
 
         /**
          * @see IStatusBar#topAppWindowChanged(int, boolean, boolean).
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 4d8abff..5abca6b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -18,7 +18,6 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
-import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
@@ -118,11 +117,11 @@
     private int mChargingSpeed;
     private int mChargingWattage;
     private int mBatteryLevel;
+    private long mChargingTimeRemaining;
     private String mMessageToShowOnScreenOn;
 
     private KeyguardUpdateMonitorCallback mUpdateMonitorCallback;
 
-    private final DevicePolicyManager mDevicePolicyManager;
     private boolean mDozing;
     private final ViewClippingUtil.ClippingParameters mClippingParams =
             new ViewClippingUtil.ClippingParameters() {
@@ -144,7 +143,9 @@
                 Dependency.get(KeyguardStateController.class),
                 Dependency.get(StatusBarStateController.class),
                 Dependency.get(KeyguardUpdateMonitor.class),
-                Dependency.get(DockManager.class));
+                Dependency.get(DockManager.class),
+                IBatteryStats.Stub.asInterface(
+                        ServiceManager.getService(BatteryStats.SERVICE_NAME)));
     }
 
     /**
@@ -157,7 +158,8 @@
             KeyguardStateController keyguardStateController,
             StatusBarStateController statusBarStateController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
-            DockManager dockManager) {
+            DockManager dockManager,
+            IBatteryStats iBatteryStats) {
         mContext = context;
         mLockIcon = lockIcon;
         mShadeController = shadeController;
@@ -180,11 +182,8 @@
         mFastThreshold = res.getInteger(R.integer.config_chargingFastThreshold);
 
         mUserManager = context.getSystemService(UserManager.class);
-        mBatteryInfo = IBatteryStats.Stub.asInterface(
-                ServiceManager.getService(BatteryStats.SERVICE_NAME));
+        mBatteryInfo = iBatteryStats;
 
-        mDevicePolicyManager = (DevicePolicyManager) context.getSystemService(
-                Context.DEVICE_POLICY_SERVICE);
         setIndicationArea(indicationArea);
 
         mKeyguardUpdateMonitor.registerCallback(getKeyguardCallback());
@@ -480,16 +479,7 @@
             return mContext.getResources().getString(R.string.keyguard_charged);
         }
 
-        // Try fetching charging time from battery stats.
-        long chargingTimeRemaining = 0;
-        try {
-            chargingTimeRemaining = mBatteryInfo.computeChargeTimeRemaining();
-
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error calling IBatteryStats: ", e);
-        }
-        final boolean hasChargingTime = chargingTimeRemaining > 0;
-
+        final boolean hasChargingTime = mChargingTimeRemaining > 0;
         int chargingId;
         if (mPowerPluggedInWired) {
             switch (mChargingSpeed) {
@@ -522,7 +512,7 @@
             // locales will also have it in the future. For now, we still have to support the old
             // format until all languages get the new translations.
             String chargingTimeFormatted = Formatter.formatShortElapsedTimeRoundingUpToMinutes(
-                    mContext, chargingTimeRemaining);
+                    mContext, mChargingTimeRemaining);
             try {
                 return mContext.getResources().getString(chargingId, chargingTimeFormatted,
                         percentage);
@@ -639,6 +629,13 @@
             mChargingWattage = status.maxChargingWattage;
             mChargingSpeed = status.getChargingSpeed(mSlowThreshold, mFastThreshold);
             mBatteryLevel = status.level;
+            try {
+                mChargingTimeRemaining = mPowerPluggedIn
+                        ? mBatteryInfo.computeChargeTimeRemaining() : -1;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error calling IBatteryStats: ", e);
+                mChargingTimeRemaining = -1;
+            }
             updateIndication(!wasPluggedIn && mPowerPluggedInWired);
             if (mDozing) {
                 if (!wasPluggedIn && mPowerPluggedIn) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
index 1532c4f..d35e1e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
@@ -16,8 +16,8 @@
 
 package com.android.systemui.statusbar.phone;
 
-import static android.view.WindowInsetsController.APPEARANCE_LIGHT_SIDE_BARS;
-import static android.view.WindowInsetsController.APPEARANCE_LIGHT_TOP_BAR;
+import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
 
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
@@ -123,10 +123,10 @@
     void onNavigationBarAppearanceChanged(@Appearance int appearance, boolean nbModeChanged,
             int navigationBarMode, boolean navbarColorManagedByIme) {
         int diff = appearance ^ mAppearance;
-        if ((diff & APPEARANCE_LIGHT_SIDE_BARS) != 0 || nbModeChanged) {
+        if ((diff & APPEARANCE_LIGHT_NAVIGATION_BARS) != 0 || nbModeChanged) {
             final boolean last = mNavigationLight;
             mHasLightNavigationBar = isLight(appearance, navigationBarMode,
-                    APPEARANCE_LIGHT_SIDE_BARS);
+                    APPEARANCE_LIGHT_NAVIGATION_BARS);
             mNavigationLight = mHasLightNavigationBar
                     && (mDirectReplying && mNavbarColorManagedByIme || !mForceDarkForScrim)
                     && !mQsCustomizing;
@@ -140,7 +140,7 @@
     }
 
     void onNavigationBarModeChanged(int newBarMode) {
-        mHasLightNavigationBar = isLight(mAppearance, newBarMode, APPEARANCE_LIGHT_SIDE_BARS);
+        mHasLightNavigationBar = isLight(mAppearance, newBarMode, APPEARANCE_LIGHT_NAVIGATION_BARS);
     }
 
     private void reevaluate() {
@@ -206,7 +206,7 @@
 
         for (int i = 0; i < numStacks; i++) {
             if (isLight(mAppearanceRegions[i].getAppearance(), mStatusBarMode,
-                    APPEARANCE_LIGHT_TOP_BAR)) {
+                    APPEARANCE_LIGHT_STATUS_BARS)) {
                 numLightStacks++;
                 indexLightStack = i;
             }
@@ -252,7 +252,7 @@
         final int numStacks = mAppearanceRegions.length;
         for (int i = 0; i < numStacks; i++) {
             final boolean isLight = isLight(mAppearanceRegions[i].getAppearance(), mStatusBarMode,
-                    APPEARANCE_LIGHT_TOP_BAR);
+                    APPEARANCE_LIGHT_STATUS_BARS);
             pw.print(" stack #"); pw.print(i); pw.print(": ");
             pw.print(mAppearanceRegions[i].toString()); pw.print(" isLight="); pw.println(isLight);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 116162d..0703d8c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -21,10 +21,10 @@
 import static android.app.StatusBarManager.WindowType;
 import static android.app.StatusBarManager.WindowVisibleState;
 import static android.app.StatusBarManager.windowStateToString;
-import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.containsType;
 import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
-import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_SIDE_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_NAVIGATION_BARS;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
 
 import static com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
@@ -69,7 +69,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.Display;
-import android.view.InsetsState.InternalInsetType;
+import android.view.InsetsState.InternalInsetsType;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -567,11 +567,11 @@
     }
 
     @Override
-    public void showTransient(int displayId, @InternalInsetType int[] types) {
+    public void showTransient(int displayId, @InternalInsetsType int[] types) {
         if (displayId != mDisplayId) {
             return;
         }
-        if (!containsType(types, TYPE_NAVIGATION_BAR)) {
+        if (!containsType(types, ITYPE_NAVIGATION_BAR)) {
             return;
         }
         if (!mTransientShown) {
@@ -581,11 +581,11 @@
     }
 
     @Override
-    public void abortTransient(int displayId, @InternalInsetType int[] types) {
+    public void abortTransient(int displayId, @InternalInsetsType int[] types) {
         if (displayId != mDisplayId) {
             return;
         }
-        if (!containsType(types, TYPE_NAVIGATION_BAR)) {
+        if (!containsType(types, ITYPE_NAVIGATION_BAR)) {
             return;
         }
         clearTransient();
@@ -627,14 +627,14 @@
     }
 
     private static @TransitionMode int barMode(boolean isTransient, int appearance) {
-        final int lightsOutOpaque = APPEARANCE_LOW_PROFILE_BARS | APPEARANCE_OPAQUE_SIDE_BARS;
+        final int lightsOutOpaque = APPEARANCE_LOW_PROFILE_BARS | APPEARANCE_OPAQUE_NAVIGATION_BARS;
         if (isTransient) {
             return MODE_SEMI_TRANSPARENT;
         } else if ((appearance & lightsOutOpaque) == lightsOutOpaque) {
             return MODE_LIGHTS_OUT;
         } else if ((appearance & APPEARANCE_LOW_PROFILE_BARS) != 0) {
             return MODE_LIGHTS_OUT_TRANSPARENT;
-        } else if ((appearance & APPEARANCE_OPAQUE_SIDE_BARS) != 0) {
+        } else if ((appearance & APPEARANCE_OPAQUE_NAVIGATION_BARS) != 0) {
             return MODE_OPAQUE;
         } else {
             return MODE_TRANSPARENT;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 06183b7..170261e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -24,10 +24,10 @@
 import static android.app.StatusBarManager.WindowVisibleState;
 import static android.app.StatusBarManager.windowStateToString;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
-import static android.view.InsetsState.TYPE_TOP_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.InsetsState.containsType;
 import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
-import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_TOP_BAR;
+import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_STATUS_BARS;
 
 import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
@@ -100,7 +100,7 @@
 import android.util.Slog;
 import android.view.Display;
 import android.view.IWindowManager;
-import android.view.InsetsState.InternalInsetType;
+import android.view.InsetsState.InternalInsetsType;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.RemoteAnimationAdapter;
@@ -839,7 +839,7 @@
         // Set up the initial notification state. This needs to happen before CommandQueue.disable()
         setUpPresenter();
 
-        if (containsType(result.mTransientBarTypes, TYPE_TOP_BAR)) {
+        if (containsType(result.mTransientBarTypes, ITYPE_STATUS_BAR)) {
             showTransientUnchecked();
         }
         onSystemBarAppearanceChanged(mDisplayId, result.mAppearance, result.mAppearanceRegions,
@@ -2239,11 +2239,11 @@
     }
 
     @Override
-    public void showTransient(int displayId, @InternalInsetType int[] types) {
+    public void showTransient(int displayId, @InternalInsetsType int[] types) {
         if (displayId != mDisplayId) {
             return;
         }
-        if (!containsType(types, TYPE_TOP_BAR)) {
+        if (!containsType(types, ITYPE_STATUS_BAR)) {
             return;
         }
         showTransientUnchecked();
@@ -2258,11 +2258,11 @@
     }
 
     @Override
-    public void abortTransient(int displayId, @InternalInsetType int[] types) {
+    public void abortTransient(int displayId, @InternalInsetsType int[] types) {
         if (displayId != mDisplayId) {
             return;
         }
-        if (!containsType(types, TYPE_TOP_BAR)) {
+        if (!containsType(types, ITYPE_STATUS_BAR)) {
             return;
         }
         clearTransient();
@@ -2293,14 +2293,14 @@
     }
 
     private static @TransitionMode int barMode(boolean isTransient, int appearance) {
-        final int lightsOutOpaque = APPEARANCE_LOW_PROFILE_BARS | APPEARANCE_OPAQUE_TOP_BAR;
+        final int lightsOutOpaque = APPEARANCE_LOW_PROFILE_BARS | APPEARANCE_OPAQUE_STATUS_BARS;
         if (isTransient) {
             return MODE_SEMI_TRANSPARENT;
         } else if ((appearance & lightsOutOpaque) == lightsOutOpaque) {
             return MODE_LIGHTS_OUT;
         } else if ((appearance & APPEARANCE_LOW_PROFILE_BARS) != 0) {
             return MODE_LIGHTS_OUT_TRANSPARENT;
-        } else if ((appearance & APPEARANCE_OPAQUE_TOP_BAR) != 0) {
+        } else if ((appearance & APPEARANCE_OPAQUE_STATUS_BARS) != 0) {
             return MODE_OPAQUE;
         } else {
             return MODE_TRANSPARENT;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
index 8c9ae71..24c372c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
@@ -15,8 +15,8 @@
 package com.android.systemui.statusbar;
 
 import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.TYPE_TOP_BAR;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
 
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Matchers.eq;
@@ -136,7 +136,7 @@
 
     @Test
     public void testShowTransient() {
-        int[] types = new int[]{ TYPE_TOP_BAR, TYPE_NAVIGATION_BAR };
+        int[] types = new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR};
         mCommandQueue.showTransient(DEFAULT_DISPLAY, types);
         waitForIdleSync();
         verify(mCallbacks).showTransient(eq(DEFAULT_DISPLAY), eq(types));
@@ -144,7 +144,7 @@
 
     @Test
     public void testShowTransientForSecondaryDisplay() {
-        int[] types = new int[]{ TYPE_TOP_BAR, TYPE_NAVIGATION_BAR };
+        int[] types = new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR};
         mCommandQueue.showTransient(SECONDARY_DISPLAY, types);
         waitForIdleSync();
         verify(mCallbacks).showTransient(eq(SECONDARY_DISPLAY), eq(types));
@@ -152,7 +152,7 @@
 
     @Test
     public void testAbortTransient() {
-        int[] types = new int[]{ TYPE_TOP_BAR, TYPE_NAVIGATION_BAR };
+        int[] types = new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR};
         mCommandQueue.abortTransient(DEFAULT_DISPLAY, types);
         waitForIdleSync();
         verify(mCallbacks).abortTransient(eq(DEFAULT_DISPLAY), eq(types));
@@ -160,7 +160,7 @@
 
     @Test
     public void testAbortTransientForSecondaryDisplay() {
-        int[] types = new int[]{ TYPE_TOP_BAR, TYPE_NAVIGATION_BAR };
+        int[] types = new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR};
         mCommandQueue.abortTransient(SECONDARY_DISPLAY, types);
         waitForIdleSync();
         verify(mCallbacks).abortTransient(eq(SECONDARY_DISPLAY), eq(types));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index a0a3679..48169ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -23,7 +23,9 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -37,7 +39,9 @@
 import android.hardware.biometrics.BiometricSourceType;
 import android.hardware.face.FaceManager;
 import android.hardware.fingerprint.FingerprintManager;
+import android.os.BatteryManager;
 import android.os.Looper;
+import android.os.RemoteException;
 import android.os.UserManager;
 import android.view.View;
 import android.view.ViewGroup;
@@ -46,8 +50,10 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.app.IBatteryStats;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitor.BatteryStatus;
 import com.android.settingslib.Utils;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
@@ -96,6 +102,8 @@
     @Mock
     private UserManager mUserManager;
     @Mock
+    private IBatteryStats mIBatteryStats;
+    @Mock
     private DockManager mDockManager;
     @Captor
     private ArgumentCaptor<DockManager.AlignmentStateListener> mAlignmentListener;
@@ -131,8 +139,9 @@
         mController = new KeyguardIndicationController(mContext, mIndicationArea, mLockIcon,
                 mLockPatternUtils, mWakeLock, mShadeController, mAccessibilityController,
                 mKeyguardStateController, mStatusBarStateController, mKeyguardUpdateMonitor,
-                mDockManager);
+                mDockManager, mIBatteryStats);
         mController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
+        clearInvocations(mIBatteryStats);
     }
 
     @Test
@@ -341,6 +350,42 @@
     }
 
     @Test
+    public void onRefreshBatteryInfo_computesChargingTime() throws RemoteException {
+        createController();
+        BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_CHARGING,
+                80 /* level */, BatteryManager.BATTERY_PLUGGED_WIRELESS, 100 /* health */,
+                0 /* maxChargingWattage */);
+
+        mController.getKeyguardCallback().onRefreshBatteryInfo(status);
+        verify(mIBatteryStats).computeChargeTimeRemaining();
+    }
+
+    @Test
+    public void onRefreshBatteryInfo_computesChargingTime_onlyWhenCharging()
+            throws RemoteException {
+        createController();
+        BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_CHARGING,
+                80 /* level */, 0 /* plugged */, 100 /* health */,
+                0 /* maxChargingWattage */);
+
+        mController.getKeyguardCallback().onRefreshBatteryInfo(status);
+        verify(mIBatteryStats, never()).computeChargeTimeRemaining();
+    }
+
+    /**
+     * Regression test.
+     * We should not make calls to the system_process when updating the doze state.
+     */
+    @Test
+    public void setDozing_noIBatteryCalls() throws RemoteException {
+        createController();
+        mController.setVisible(true);
+        mController.setDozing(true);
+        mController.setDozing(false);
+        verify(mIBatteryStats, never()).computeChargeTimeRemaining();
+    }
+
+    @Test
     public void updateMonitor_listener() {
         createController();
         verify(mKeyguardStateController).addCallback(eq(mController));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
index 6260d53..8ab660c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.statusbar.phone;
 
-import static android.view.WindowInsetsController.APPEARANCE_LIGHT_TOP_BAR;
+import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
 
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
 
@@ -64,8 +64,8 @@
         final Rect firstBounds = new Rect(0, 0, 1, 1);
         final Rect secondBounds = new Rect(1, 0, 2, 1);
         final AppearanceRegion[] appearanceRegions = new AppearanceRegion[]{
-                new AppearanceRegion(APPEARANCE_LIGHT_TOP_BAR, firstBounds),
-                new AppearanceRegion(APPEARANCE_LIGHT_TOP_BAR, secondBounds)
+                new AppearanceRegion(APPEARANCE_LIGHT_STATUS_BARS, firstBounds),
+                new AppearanceRegion(APPEARANCE_LIGHT_STATUS_BARS, secondBounds)
         };
         mLightBarController.onStatusBarAppearanceChanged(
                 appearanceRegions, true /* sbModeChanged */, MODE_TRANSPARENT,
@@ -79,7 +79,7 @@
         final Rect firstBounds = new Rect(0, 0, 1, 1);
         final Rect secondBounds = new Rect(1, 0, 2, 1);
         final AppearanceRegion[] appearanceRegions = new AppearanceRegion[]{
-                new AppearanceRegion(APPEARANCE_LIGHT_TOP_BAR, firstBounds),
+                new AppearanceRegion(APPEARANCE_LIGHT_STATUS_BARS, firstBounds),
                 new AppearanceRegion(0 /* appearance */, secondBounds)
         };
         mLightBarController.onStatusBarAppearanceChanged(
@@ -95,7 +95,7 @@
         final Rect secondBounds = new Rect(1, 0, 2, 1);
         final AppearanceRegion[] appearanceRegions = new AppearanceRegion[]{
                 new AppearanceRegion(0 /* appearance */, firstBounds),
-                new AppearanceRegion(APPEARANCE_LIGHT_TOP_BAR, secondBounds)
+                new AppearanceRegion(APPEARANCE_LIGHT_STATUS_BARS, secondBounds)
         };
         mLightBarController.onStatusBarAppearanceChanged(
                 appearanceRegions, true /* sbModeChanged */, MODE_TRANSPARENT,
@@ -121,7 +121,7 @@
     @Test
     public void testOnStatusBarAppearanceChanged_singleStack_light() {
         final AppearanceRegion[] appearanceRegions = new AppearanceRegion[]{
-                new AppearanceRegion(APPEARANCE_LIGHT_TOP_BAR, new Rect(0, 0, 1, 1))
+                new AppearanceRegion(APPEARANCE_LIGHT_STATUS_BARS, new Rect(0, 0, 1, 1))
         };
         mLightBarController.onStatusBarAppearanceChanged(
                 appearanceRegions, true /* sbModeChanged */, MODE_TRANSPARENT,
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 457f410..3b2da91 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -1112,6 +1112,14 @@
 
     // AutoFillUiCallback
     @Override
+    public void cancelSession() {
+        synchronized (mLock) {
+            removeSelfLocked();
+        }
+    }
+
+    // AutoFillUiCallback
+    @Override
     public void startIntentSenderAndFinishSession(IntentSender intentSender) {
         startIntentSender(intentSender, null);
     }
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 1ab985b..7e8edf2 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -89,6 +89,7 @@
         void startIntentSenderAndFinishSession(IntentSender intentSender);
         void startIntentSender(IntentSender intentSender, Intent intent);
         void dispatchUnhandledKey(AutofillId id, KeyEvent keyEvent);
+        void cancelSession();
     }
 
     public AutoFillUI(@NonNull Context context) {
@@ -272,6 +273,13 @@
                         mCallback.dispatchUnhandledKey(focusedId, keyEvent);
                     }
                 }
+
+                @Override
+                public void cancelSession() {
+                    if (mCallback != null) {
+                        mCallback.cancelSession();
+                    }
+                }
             });
         };
 
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 dbd4d8c..70fb535 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -88,6 +88,7 @@
         void requestHideFillUi();
         void startIntentSender(IntentSender intentSender);
         void dispatchUnhandledKey(KeyEvent keyEvent);
+        void cancelSession();
     }
 
     private final @NonNull Point mTempPoint = new Point();
@@ -263,6 +264,7 @@
                 mHeader = headerPresentation.applyWithTheme(mContext, null, clickBlocker, mThemeId);
                 final LinearLayout headerContainer =
                         decor.findViewById(R.id.autofill_dataset_header);
+                applyCancelAction(mHeader, response.getCancelIds());
                 if (sVerbose) Slog.v(TAG, "adding header");
                 headerContainer.addView(mHeader);
                 headerContainer.setVisibility(View.VISIBLE);
@@ -279,6 +281,7 @@
                     }
                     mFooter = footerPresentation.applyWithTheme(
                             mContext, null, clickBlocker, mThemeId);
+                    applyCancelAction(mFooter, response.getCancelIds());
                     // Footer not supported on some platform e.g. TV
                     if (sVerbose) Slog.v(TAG, "adding footer");
                     footerContainer.addView(mFooter);
@@ -330,6 +333,7 @@
                         }
                     }
 
+                    applyCancelAction(view, response.getCancelIds());
                     items.add(new ViewItem(dataset, filterPattern, filterable, valueText, view));
                 }
             }
@@ -355,6 +359,37 @@
         }
     }
 
+    private void applyCancelAction(View rootView, int[] ids) {
+        if (ids == null) {
+            return;
+        }
+
+        if (sDebug) Slog.d(TAG, "fill UI has " + ids.length + " actions");
+        if (!(rootView instanceof ViewGroup)) {
+            Slog.w(TAG, "cannot apply actions because fill UI root is not a "
+                    + "ViewGroup: " + rootView);
+            return;
+        }
+
+        // Apply click actions.
+        final ViewGroup root = (ViewGroup) rootView;
+        for (int i = 0; i < ids.length; i++) {
+            final int id = ids[i];
+            final View child = root.findViewById(id);
+            if (child == null) {
+                Slog.w(TAG, "Ignoring cancel action for view " + id
+                        + " because it's not on " + root);
+                continue;
+            }
+            child.setOnClickListener((v) -> {
+                if (sVerbose) {
+                    Slog.v(TAG, "Applying " + id + " after " + v + " was clicked");
+                }
+                mCallback.cancelSession();
+            });
+        }
+    }
+
     void requestShowFillUi() {
         mCallback.requestShowFillUi(mContentWidth, mContentHeight, mWindowPresenter);
     }
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 81eb4b3..a75d5d69 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -146,6 +146,7 @@
 import android.security.KeyStore;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.LocalLog;
 import android.util.Log;
@@ -3050,7 +3051,8 @@
     }
 
     private void handleAsyncChannelHalfConnect(Message msg) {
-        AsyncChannel ac = (AsyncChannel) msg.obj;
+        ensureRunningOnConnectivityServiceThread();
+        final AsyncChannel ac = (AsyncChannel) msg.obj;
         if (mNetworkFactoryInfos.containsKey(msg.replyTo)) {
             if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
                 if (VDBG) log("NetworkFactory connected");
@@ -3060,7 +3062,8 @@
                 // A network factory has connected.  Send it all current NetworkRequests.
                 for (NetworkRequestInfo nri : mNetworkRequests.values()) {
                     if (nri.request.isListen()) continue;
-                    NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId);
+                    ensureRunningOnConnectivityServiceThread();
+                    NetworkAgentInfo nai = nri.mSatisfier;
                     final int score;
                     final int serial;
                     if (nai != null) {
@@ -3116,6 +3119,7 @@
     // ConnectivityService, free its interfaces and clean up.
     // Must be called on the Handler thread.
     private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) {
+        ensureRunningOnConnectivityServiceThread();
         if (DBG) {
             log(nai.name() + " got DISCONNECTED, was satisfying " + nai.numNetworkRequests());
         }
@@ -3162,14 +3166,17 @@
         // Remove all previously satisfied requests.
         for (int i = 0; i < nai.numNetworkRequests(); i++) {
             NetworkRequest request = nai.requestAt(i);
-            NetworkAgentInfo currentNetwork = getNetworkForRequest(request.requestId);
+            final NetworkRequestInfo nri = mNetworkRequests.get(request);
+            ensureRunningOnConnectivityServiceThread();
+            final NetworkAgentInfo currentNetwork = nri.mSatisfier;
             if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) {
-                clearNetworkForRequest(request.requestId);
+                nri.mSatisfier = null;
                 sendUpdatedScoreToFactories(request, null);
             }
         }
         nai.clearLingerState();
         if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) {
+            mDefaultNetworkNai = null;
             updateDataActivityTracking(null /* newNetwork */, nai);
             notifyLockdownVpn(nai);
             ensureNetworkTransitionWakelock(nai.name());
@@ -3253,6 +3260,7 @@
     }
 
     private void handleRegisterNetworkRequest(NetworkRequestInfo nri) {
+        ensureRunningOnConnectivityServiceThread();
         mNetworkRequests.put(nri.request, nri);
         mNetworkRequestInfoLogs.log("REGISTER " + nri);
         if (nri.request.isListen()) {
@@ -3264,7 +3272,8 @@
             }
         }
         rematchAllNetworksAndRequests(null, 0);
-        if (nri.request.isRequest() && getNetworkForRequest(nri.request.requestId) == null) {
+        ensureRunningOnConnectivityServiceThread();
+        if (nri.request.isRequest() && nri.mSatisfier == null) {
             sendUpdatedScoreToFactories(nri.request, null);
         }
     }
@@ -3286,6 +3295,7 @@
     // - UnneededFor.LINGER: foreground NetworkRequests. If a network is unneeded for this reason,
     //   then it should be lingered.
     private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) {
+        ensureRunningOnConnectivityServiceThread();
         final int numRequests;
         switch (reason) {
             case TEARDOWN:
@@ -3310,6 +3320,7 @@
 
             // If this Network is already the highest scoring Network for a request, or if
             // there is hope for it to become one if it validated, then it is needed.
+            ensureRunningOnConnectivityServiceThread();
             if (nri.request.isRequest() && nai.satisfies(nri.request) &&
                     (nai.isSatisfyingRequest(nri.request.requestId) ||
                     // Note that this catches two important cases:
@@ -3319,8 +3330,8 @@
                     // 2. Unvalidated WiFi will not be reaped when validated cellular
                     //    is currently satisfying the request.  This is desirable when
                     //    WiFi ends up validating and out scoring cellular.
-                    getNetworkForRequest(nri.request.requestId).getCurrentScore() <
-                            nai.getCurrentScoreAsValidated())) {
+                    nri.mSatisfier.getCurrentScore()
+                            < nai.getCurrentScoreAsValidated())) {
                 return false;
             }
         }
@@ -3344,10 +3355,12 @@
     }
 
     private void handleTimedOutNetworkRequest(final NetworkRequestInfo nri) {
+        ensureRunningOnConnectivityServiceThread();
         if (mNetworkRequests.get(nri.request) == null) {
             return;
         }
-        if (getNetworkForRequest(nri.request.requestId) != null) {
+        ensureRunningOnConnectivityServiceThread();
+        if (nri.mSatisfier != null) {
             return;
         }
         if (VDBG || (DBG && nri.request.isRequest())) {
@@ -3374,6 +3387,8 @@
     }
 
     private void handleRemoveNetworkRequest(final NetworkRequestInfo nri) {
+        ensureRunningOnConnectivityServiceThread();
+
         nri.unlinkDeathRecipient();
         mNetworkRequests.remove(nri.request);
 
@@ -3393,7 +3408,8 @@
         mNetworkRequestInfoLogs.log("RELEASE " + nri);
         if (nri.request.isRequest()) {
             boolean wasKept = false;
-            NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId);
+            ensureRunningOnConnectivityServiceThread();
+            final NetworkAgentInfo nai = nri.mSatisfier;
             if (nai != null) {
                 boolean wasBackgroundNetwork = nai.isBackgroundNetwork();
                 nai.removeRequest(nri.request.requestId);
@@ -3410,7 +3426,7 @@
                 } else {
                     wasKept = true;
                 }
-                clearNetworkForRequest(nri.request.requestId);
+                nri.mSatisfier = null;
                 if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) {
                     // Went from foreground to background.
                     updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities);
@@ -5093,6 +5109,11 @@
      */
     private class NetworkRequestInfo implements IBinder.DeathRecipient {
         final NetworkRequest request;
+        // The network currently satisfying this request, or null if none. Must only be touched
+        // on the handler thread. This only makes sense for network requests and not for listens,
+        // as defined by NetworkRequest#isRequest(). For listens, this is always null.
+        @Nullable
+        NetworkAgentInfo mSatisfier;
         final PendingIntent mPendingIntent;
         boolean mPendingIntentSent;
         private final IBinder mBinder;
@@ -5479,16 +5500,6 @@
         if (DBG) log("unregisterNetworkFactory for " + nfi.name);
     }
 
-    /**
-     * NetworkAgentInfo supporting a request by requestId.
-     * These have already been vetted (their Capabilities satisfy the request)
-     * and the are the highest scored network available.
-     * the are keyed off the Requests requestId.
-     */
-    // NOTE: Accessed on multiple threads, must be synchronized on itself.
-    @GuardedBy("mNetworkForRequestId")
-    private final SparseArray<NetworkAgentInfo> mNetworkForRequestId = new SparseArray<>();
-
     // NOTE: Accessed on multiple threads, must be synchronized on itself.
     @GuardedBy("mNetworkForNetId")
     private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>();
@@ -5506,7 +5517,11 @@
     private final HashSet<Integer> mBlockedAppUids = new HashSet<>();
 
     // Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated.
+    @NonNull
     private final NetworkRequest mDefaultRequest;
+    // The NetworkAgentInfo currently satisfying the default request, if any.
+    @Nullable
+    private volatile NetworkAgentInfo mDefaultNetworkNai = null;
 
     // Request used to optionally keep mobile data active even when higher
     // priority networks like Wi-Fi are active.
@@ -5516,26 +5531,8 @@
     // priority networks like ethernet are active.
     private final NetworkRequest mDefaultWifiRequest;
 
-    private NetworkAgentInfo getNetworkForRequest(int requestId) {
-        synchronized (mNetworkForRequestId) {
-            return mNetworkForRequestId.get(requestId);
-        }
-    }
-
-    private void clearNetworkForRequest(int requestId) {
-        synchronized (mNetworkForRequestId) {
-            mNetworkForRequestId.remove(requestId);
-        }
-    }
-
-    private void setNetworkForRequest(int requestId, NetworkAgentInfo nai) {
-        synchronized (mNetworkForRequestId) {
-            mNetworkForRequestId.put(requestId, nai);
-        }
-    }
-
     private NetworkAgentInfo getDefaultNetwork() {
-        return getNetworkForRequest(mDefaultRequest.requestId);
+        return mDefaultNetworkNai;
     }
 
     @Nullable
@@ -6253,7 +6250,7 @@
         }
     }
 
-    private void makeDefault(NetworkAgentInfo newNetwork) {
+    private void makeDefault(@NonNull final NetworkAgentInfo newNetwork) {
         if (DBG) log("Switching to new default network: " + newNetwork);
 
         try {
@@ -6262,6 +6259,7 @@
             loge("Exception setting default network :" + e);
         }
 
+        mDefaultNetworkNai = newNetwork;
         notifyLockdownVpn(newNetwork);
         handleApplyDefaultProxy(newNetwork.linkProperties.getHttpProxy());
         updateTcpBufferSizes(newNetwork.linkProperties.getTcpBufferSizes());
@@ -6325,6 +6323,7 @@
     //               validated) of becoming the highest scoring network.
     private void rematchNetworkAndRequests(NetworkAgentInfo newNetwork,
             ReapUnvalidatedNetworks reapUnvalidatedNetworks, long now) {
+        ensureRunningOnConnectivityServiceThread();
         if (!newNetwork.everConnected) return;
         boolean keep = newNetwork.isVPN();
         boolean isNewDefault = false;
@@ -6335,10 +6334,8 @@
 
         if (VDBG || DDBG) log("rematching " + newNetwork.name());
 
-        // Find and migrate to this Network any NetworkRequests for
-        // which this network is now the best.
-        ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<>();
-        ArrayList<NetworkRequestInfo> addedRequests = new ArrayList<>();
+        final ArrayMap<NetworkRequestInfo, NetworkAgentInfo> reassignedRequests = new ArrayMap<>();
+
         NetworkCapabilities nc = newNetwork.networkCapabilities;
         if (VDBG) log(" network has: " + nc);
         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
@@ -6348,16 +6345,10 @@
             // requests or not, and doesn't affect the network's score.
             if (nri.request.isListen()) continue;
 
-            final NetworkAgentInfo currentNetwork = getNetworkForRequest(nri.request.requestId);
+            ensureRunningOnConnectivityServiceThread();
+            final NetworkAgentInfo currentNetwork = nri.mSatisfier;
             final boolean satisfies = newNetwork.satisfies(nri.request);
-            if (newNetwork == currentNetwork && satisfies) {
-                if (VDBG) {
-                    log("Network " + newNetwork.name() + " was already satisfying" +
-                            " request " + nri.request.requestId + ". No change.");
-                }
-                keep = true;
-                continue;
-            }
+            if (newNetwork == currentNetwork && satisfies) continue;
 
             // check if it satisfies the NetworkCapabilities
             if (VDBG) log("  checking if request is satisfied: " + nri.request);
@@ -6370,39 +6361,55 @@
                             ", newScore = " + score);
                 }
                 if (currentNetwork == null || currentNetwork.getCurrentScore() < score) {
-                    if (VDBG) log("rematch for " + newNetwork.name());
-                    if (currentNetwork != null) {
-                        if (VDBG || DDBG){
-                            log("   accepting network in place of " + currentNetwork.name());
-                        }
-                        currentNetwork.removeRequest(nri.request.requestId);
-                        currentNetwork.lingerRequest(nri.request, now, mLingerDelayMs);
-                        affectedNetworks.add(currentNetwork);
-                    } else {
-                        if (VDBG || DDBG) log("   accepting network in place of null");
-                    }
-                    newNetwork.unlingerRequest(nri.request);
-                    setNetworkForRequest(nri.request.requestId, newNetwork);
-                    if (!newNetwork.addRequest(nri.request)) {
-                        Slog.wtf(TAG, "BUG: " + newNetwork.name() + " already has " + nri.request);
-                    }
-                    addedRequests.add(nri);
-                    keep = true;
-                    // Tell NetworkFactories about the new score, so they can stop
-                    // trying to connect if they know they cannot match it.
-                    // TODO - this could get expensive if we have a lot of requests for this
-                    // network.  Think about if there is a way to reduce this.  Push
-                    // netid->request mapping to each factory?
-                    sendUpdatedScoreToFactories(nri.request, newNetwork);
-                    if (isDefaultRequest(nri)) {
-                        isNewDefault = true;
-                        oldDefaultNetwork = currentNetwork;
-                        if (currentNetwork != null) {
-                            mLingerMonitor.noteLingerDefaultNetwork(currentNetwork, newNetwork);
-                        }
-                    }
+                    reassignedRequests.put(nri, newNetwork);
                 }
             } else if (newNetwork.isSatisfyingRequest(nri.request.requestId)) {
+                reassignedRequests.put(nri, null);
+            }
+        }
+
+        // Find and migrate to this Network any NetworkRequests for
+        // which this network is now the best.
+        final ArrayList<NetworkAgentInfo> removedRequests = new ArrayList<>();
+        final ArrayList<NetworkRequestInfo> addedRequests = new ArrayList<>();
+        for (final Map.Entry<NetworkRequestInfo, NetworkAgentInfo> entry :
+                reassignedRequests.entrySet()) {
+            final NetworkRequestInfo nri = entry.getKey();
+            final NetworkAgentInfo previousSatisfier = nri.mSatisfier;
+            final NetworkAgentInfo newSatisfier = entry.getValue();
+            if (newSatisfier != null) {
+                if (VDBG) log("rematch for " + newSatisfier.name());
+                if (previousSatisfier != null) {
+                    if (VDBG || DDBG) {
+                        log("   accepting network in place of " + previousSatisfier.name());
+                    }
+                    previousSatisfier.removeRequest(nri.request.requestId);
+                    previousSatisfier.lingerRequest(nri.request, now, mLingerDelayMs);
+                    removedRequests.add(previousSatisfier);
+                } else {
+                    if (VDBG || DDBG) log("   accepting network in place of null");
+                }
+                newSatisfier.unlingerRequest(nri.request);
+                nri.mSatisfier = newSatisfier;
+                if (!newSatisfier.addRequest(nri.request)) {
+                    Slog.wtf(TAG, "BUG: " + newSatisfier.name() + " already has " + nri.request);
+                }
+                addedRequests.add(nri);
+                keep = true;
+                // Tell NetworkFactories about the new score, so they can stop
+                // trying to connect if they know they cannot match it.
+                // TODO - this could get expensive if we have a lot of requests for this
+                // network.  Think about if there is a way to reduce this.  Push
+                // netid->request mapping to each factory?
+                sendUpdatedScoreToFactories(nri.request, newSatisfier);
+                if (isDefaultRequest(nri)) {
+                    isNewDefault = true;
+                    oldDefaultNetwork = previousSatisfier;
+                    if (previousSatisfier != null) {
+                        mLingerMonitor.noteLingerDefaultNetwork(previousSatisfier, newSatisfier);
+                    }
+                }
+            } else {
                 // If "newNetwork" is listed as satisfying "nri" but no longer satisfies "nri",
                 // mark it as no longer satisfying "nri".  Because networks are processed by
                 // rematchAllNetworksAndRequests() in descending score order, "currentNetwork" will
@@ -6415,13 +6422,14 @@
                             " request " + nri.request.requestId);
                 }
                 newNetwork.removeRequest(nri.request.requestId);
-                if (currentNetwork == newNetwork) {
-                    clearNetworkForRequest(nri.request.requestId);
+                if (previousSatisfier == newNetwork) {
+                    nri.mSatisfier = null;
+                    if (isDefaultRequest(nri)) mDefaultNetworkNai = null;
                     sendUpdatedScoreToFactories(nri.request, null);
                 } else {
                     Slog.wtf(TAG, "BUG: Removing request " + nri.request.requestId + " from " +
                             newNetwork.name() +
-                            " without updating mNetworkForRequestId or factories!");
+                            " without updating mSatisfier or factories!");
                 }
                 // TODO: Technically, sending CALLBACK_LOST here is
                 // incorrect if there is a replacement network currently
@@ -6433,6 +6441,7 @@
                 callCallbackForRequest(nri, newNetwork, ConnectivityManager.CALLBACK_LOST, 0);
             }
         }
+
         if (isNewDefault) {
             updateDataActivityTracking(newNetwork, oldDefaultNetwork);
             // Notify system services that this network is up.
@@ -6472,7 +6481,7 @@
 
         // Linger any networks that are no longer needed. This should be done after sending the
         // available callback for newNetwork.
-        for (NetworkAgentInfo nai : affectedNetworks) {
+        for (NetworkAgentInfo nai : removedRequests) {
             updateLingerState(nai, now);
         }
         // Possibly unlinger newNetwork. Unlingering a network does not send any callbacks so it
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 41c323c..a09657b 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -132,6 +132,7 @@
 
     private static final int MSG_COMMIT = 1;
     private static final int MSG_ON_PACKAGE_INSTALLED = 2;
+    private static final int MSG_SEAL = 3;
 
     /** XML constants used for persisting a session */
     static final String TAG_SESSION = "session";
@@ -332,6 +333,9 @@
         @Override
         public boolean handleMessage(Message msg) {
             switch (msg.what) {
+                case MSG_SEAL:
+                    handleSeal((IntentSender) msg.obj);
+                    break;
                 case MSG_COMMIT:
                     handleCommit();
                     break;
@@ -848,7 +852,21 @@
                     "Session " + sessionId + " is a child of multi-package session "
                             + mParentSessionId +  " and may not be committed directly.");
         }
-        if (!markAsCommitted(statusReceiver, forTransfer)) {
+
+        assertCanBeCommitted(forTransfer);
+
+        if (isMultiPackage()) {
+            for (int i = mChildSessionIds.size() - 1; i >= 0; --i) {
+                final int childSessionId = mChildSessionIds.keyAt(i);
+                mSessionProvider.getSession(childSessionId).assertCanBeCommitted(forTransfer);
+            }
+        }
+
+        mHandler.obtainMessage(MSG_SEAL, statusReceiver).sendToTarget();
+    }
+
+    private void handleSeal(@NonNull IntentSender statusReceiver) {
+        if (!markAsCommitted(statusReceiver)) {
             return;
         }
         if (isMultiPackage()) {
@@ -856,24 +874,16 @@
             final IntentSender childIntentSender =
                     new ChildStatusIntentReceiver(remainingSessions, statusReceiver)
                             .getIntentSender();
-            RuntimeException commitException = null;
             boolean commitFailed = false;
             for (int i = mChildSessionIds.size() - 1; i >= 0; --i) {
                 final int childSessionId = mChildSessionIds.keyAt(i);
-                try {
-                    // commit all children, regardless if any of them fail; we'll throw/return
-                    // as appropriate once all children have been processed
-                    if (!mSessionProvider.getSession(childSessionId)
-                            .markAsCommitted(childIntentSender, forTransfer)) {
-                        commitFailed = true;
-                    }
-                } catch (RuntimeException e) {
-                    commitException = e;
+                // commit all children, regardless if any of them fail; we'll throw/return
+                // as appropriate once all children have been processed
+                if (!mSessionProvider.getSession(childSessionId)
+                        .markAsCommitted(childIntentSender)) {
+                    commitFailed = true;
                 }
             }
-            if (commitException != null) {
-                throw commitException;
-            }
             if (commitFailed) {
                 return;
             }
@@ -940,27 +950,14 @@
         }
     }
 
-
     /**
-     * Do everything but actually commit the session. If this was not already called, the session
-     * will be sealed and marked as committed. The caller of this method is responsible for
-     * subsequently submitting this session for processing.
-     *
-     * This method may be called multiple times to update the status receiver validate caller
-     * permissions.
+     * Sanity checks to make sure it's ok to commit the session.
      */
-    private boolean markAsCommitted(
-            @NonNull IntentSender statusReceiver, boolean forTransfer) {
-        Preconditions.checkNotNull(statusReceiver);
-
-        List<PackageInstallerSession> childSessions = getChildSessions();
-
-        final boolean wasSealed;
+    private void assertCanBeCommitted(boolean forTransfer) {
         synchronized (mLock) {
             assertCallerIsOwnerOrRootLocked();
             assertPreparedAndNotDestroyedLocked("commit");
-
-            mRemoteStatusReceiver = statusReceiver;
+            assertNoWriteFileTransfersOpenLocked();
 
             if (forTransfer) {
                 mContext.enforceCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES, null);
@@ -973,6 +970,25 @@
                     throw new IllegalArgumentException("Session has been transferred");
                 }
             }
+        }
+    }
+
+    /**
+     * Do everything but actually commit the session. If this was not already called, the session
+     * will be sealed and marked as committed. The caller of this method is responsible for
+     * subsequently submitting this session for processing.
+     *
+     * This method may be called multiple times to update the status receiver validate caller
+     * permissions.
+     */
+    private boolean markAsCommitted(@NonNull IntentSender statusReceiver) {
+        Preconditions.checkNotNull(statusReceiver);
+
+        List<PackageInstallerSession> childSessions = getChildSessions();
+
+        final boolean wasSealed;
+        synchronized (mLock) {
+            mRemoteStatusReceiver = statusReceiver;
 
             // After validations and updating the observer, we can skip re-sealing, etc. because we
             // have already marked ourselves as committed.
@@ -1095,26 +1111,18 @@
                 assertMultiPackageConsistencyLocked(childSessions);
             }
 
-            // Read transfers from the original owner stay open, but as the session's data
-            // cannot be modified anymore, there is no leak of information. For staged sessions,
-            // further validation is performed by the staging manager.
+            // Read transfers from the original owner stay open, but as the session's data cannot
+            // be modified anymore, there is no leak of information. For staged sessions, further
+            // validation is performed by the staging manager.
             if (!params.isMultiPackage) {
                 final PackageInfo pkgInfo = mPm.getPackageInfo(
                         params.appPackageName, PackageManager.GET_SIGNATURES
                                 | PackageManager.MATCH_STATIC_SHARED_LIBRARIES /*flags*/, userId);
 
-                try {
-                    if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) {
-                        validateApexInstallLocked();
-                    } else {
-                        validateApkInstallLocked(pkgInfo);
-                    }
-                } catch (PackageManagerException e) {
-                    throw e;
-                } catch (Throwable e) {
-                    // Convert all exceptions into package manager exceptions as only those are
-                    // handled in the code above.
-                    throw new PackageManagerException(e);
+                if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) {
+                    validateApexInstallLocked();
+                } else {
+                    validateApkInstallLocked(pkgInfo);
                 }
             }
 
@@ -1122,15 +1130,23 @@
                 mStagingManager.checkNonOverlappingWithStagedSessions(this);
             }
         } catch (PackageManagerException e) {
-            // Session is sealed but could not be verified, we need to destroy it.
-            destroyInternal();
-            // Dispatch message to remove session from PackageInstallerService
-            dispatchSessionFinished(
-                    e.error, ExceptionUtils.getCompleteMessage(e), null);
-            throw e;
+            throw onSessionVerificationFailure(e);
+        } catch (Throwable e) {
+            // Convert all exceptions into package manager exceptions as only those are handled
+            // in the code above.
+            throw onSessionVerificationFailure(new PackageManagerException(e));
         }
     }
 
+    private PackageManagerException onSessionVerificationFailure(PackageManagerException e) {
+        // Session is sealed but could not be verified, we need to destroy it.
+        destroyInternal();
+        // Dispatch message to remove session from PackageInstallerService.
+        dispatchSessionFinished(e.error, ExceptionUtils.getCompleteMessage(e), null);
+
+        return e;
+    }
+
     /**
      * If session should be sealed, then it's sealed to prevent further modification
      * and then it's validated.
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index b6934c9..95ffd8f 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -17,7 +17,7 @@
 package com.android.server.statusbar;
 
 import android.os.Bundle;
-import android.view.InsetsState.InternalInsetType;
+import android.view.InsetsState.InternalInsetsType;
 import android.view.WindowInsetsController.Appearance;
 
 import com.android.internal.view.AppearanceRegion;
@@ -119,8 +119,8 @@
             AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme);
 
     /** @see com.android.internal.statusbar.IStatusBar#showTransient */
-    void showTransient(int displayId, @InternalInsetType int[] types);
+    void showTransient(int displayId, @InternalInsetsType int[] types);
 
     /** @see com.android.internal.statusbar.IStatusBar#abortTransient */
-    void abortTransient(int displayId, @InternalInsetType int[] types);
+    void abortTransient(int displayId, @InternalInsetsType int[] types);
 }
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 6ea08fe..870c81f 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -46,7 +46,7 @@
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
-import android.view.InsetsState.InternalInsetType;
+import android.view.InsetsState.InternalInsetsType;
 import android.view.WindowInsetsController.Appearance;
 
 import com.android.internal.R;
@@ -482,7 +482,7 @@
         }
 
         @Override
-        public void showTransient(int displayId, @InternalInsetType int[] types) {
+        public void showTransient(int displayId, @InternalInsetsType int[] types) {
             getUiState(displayId).showTransient(types);
             if (mBar != null) {
                 try {
@@ -492,7 +492,7 @@
         }
 
         @Override
-        public void abortTransient(int displayId, @InternalInsetType int[] types) {
+        public void abortTransient(int displayId, @InternalInsetsType int[] types) {
             getUiState(displayId).clearTransient(types);
             if (mBar != null) {
                 try {
@@ -966,13 +966,13 @@
             return true;
         }
 
-        private void showTransient(@InternalInsetType int[] types) {
+        private void showTransient(@InternalInsetsType int[] types) {
             for (int type : types) {
                 mTransientBarTypes.add(type);
             }
         }
 
-        private void clearTransient(@InternalInsetType int[] types) {
+        private void clearTransient(@InternalInsetsType int[] types) {
             for (int type : types) {
                 mTransientBarTypes.remove(type);
             }
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 73034b0..0a861ad 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -548,7 +548,7 @@
     private static boolean hasActivityToBeDrawn(Task t) {
         for (int i = t.getChildCount() - 1; i >= 0; --i) {
             final ActivityRecord r = t.getChildAt(i);
-            if (r.visible && !r.mDrawn && !r.finishing) {
+            if (r.mVisibleRequested && !r.mDrawn && !r.finishing) {
                 return true;
             }
         }
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index fcdb3b0..f24fa07 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -176,7 +176,6 @@
 import static com.android.server.wm.AppWindowTokenProto.DEFER_HIDING_CLIENT;
 import static com.android.server.wm.AppWindowTokenProto.FILLS_PARENT;
 import static com.android.server.wm.AppWindowTokenProto.FROZEN_BOUNDS;
-import static com.android.server.wm.AppWindowTokenProto.HIDDEN_REQUESTED;
 import static com.android.server.wm.AppWindowTokenProto.HIDDEN_SET_FROM_TRANSFERRED_STARTING_WINDOW;
 import static com.android.server.wm.AppWindowTokenProto.IS_ANIMATING;
 import static com.android.server.wm.AppWindowTokenProto.IS_WAITING_FOR_TRANSITION_START;
@@ -191,6 +190,7 @@
 import static com.android.server.wm.AppWindowTokenProto.STARTING_MOVED;
 import static com.android.server.wm.AppWindowTokenProto.STARTING_WINDOW;
 import static com.android.server.wm.AppWindowTokenProto.THUMBNAIL;
+import static com.android.server.wm.AppWindowTokenProto.VISIBLE_REQUESTED;
 import static com.android.server.wm.AppWindowTokenProto.WINDOW_TOKEN;
 import static com.android.server.wm.IdentifierProto.HASH_CODE;
 import static com.android.server.wm.IdentifierProto.TITLE;
@@ -461,7 +461,6 @@
     private boolean keysPaused;     // has key dispatching been paused for it?
     int launchMode;         // the launch mode activity attribute.
     int lockTaskLaunchMode; // the lockTaskMode manifest attribute, subject to override
-    boolean visible;        // does this activity's window need to be shown?
     boolean visibleIgnoringKeyguard; // is this activity visible, ignoring the fact that Keyguard
                                      // might hide this activity?
     // True if the hidden state of this token was forced to false due to a transferred starting
@@ -621,11 +620,11 @@
     // case do not clear allDrawn until the animation completes.
     boolean deferClearAllDrawn;
 
-    // Is this window's surface needed?  This is almost like hidden, except
-    // it will sometimes be true a little earlier: when the token has
+    // Is this window's surface needed?  This is almost like visible, except
+    // it will sometimes be true a little earlier: when the activity record has
     // been shown, but is still waiting for its app transition to execute
     // before making its windows shown.
-    boolean hiddenRequested;
+    boolean mVisibleRequested;
 
     // Last visibility state we reported to the app token.
     boolean reportedVisible;
@@ -832,7 +831,6 @@
                 pw.print(" finishing="); pw.println(finishing);
         pw.print(prefix); pw.print("keysPaused="); pw.print(keysPaused);
                 pw.print(" inHistory="); pw.print(inHistory);
-                pw.print(" visible="); pw.print(visible);
                 pw.print(" sleeping="); pw.print(sleeping);
                 pw.print(" idle="); pw.print(idle);
                 pw.print(" mStartingWindowState=");
@@ -856,7 +854,8 @@
         }
         pw.print(prefix); pw.print(" mOccludesParent="); pw.print(mOccludesParent);
         pw.print(" mOrientation="); pw.println(mOrientation);
-        pw.println(prefix + "hiddenRequested=" + hiddenRequested + " mClientHidden=" + mClientHidden
+        pw.println(prefix + "mVisibleRequested=" + mVisibleRequested
+                + " mClientHidden=" + mClientHidden
                 + ((mDeferHidingClient) ? " mDeferHidingClient=" + mDeferHidingClient : "")
                 + " reportedDrawn=" + reportedDrawn + " reportedVisible=" + reportedVisible);
         if (paused) {
@@ -1483,7 +1482,7 @@
 
         // Application tokens start out hidden.
         setHidden(true);
-        hiddenRequested = true;
+        mVisibleRequested = false;
 
         ColorDisplayService.ColorDisplayServiceInternal cds = LocalServices.getService(
                 ColorDisplayService.ColorDisplayServiceInternal.class);
@@ -1512,7 +1511,6 @@
         deferRelaunchUntilPaused = false;
         keysPaused = false;
         inHistory = false;
-        visible = false;
         nowVisible = false;
         mDrawn = false;
         idle = false;
@@ -2189,7 +2187,7 @@
      * 2. App is delayed closing since it might enter PIP.
      */
     boolean isClosingOrEnteringPip() {
-        return (isAnimating(TRANSITION | PARENTS) && hiddenRequested) || mWillCloseOrEnterPip;
+        return (isAnimating(TRANSITION | PARENTS) && !mVisibleRequested) || mWillCloseOrEnterPip;
     }
     /**
      * @return Whether AppOps allows this package to enter picture-in-picture.
@@ -2448,7 +2446,7 @@
                     mAtmService.getLockTaskController().clearLockedTask(task);
                 }
             } else if (!isState(PAUSING)) {
-                if (visible) {
+                if (mVisibleRequested) {
                     // Prepare and execute close transition.
                     prepareActivityHideTransitionAnimation(transit);
                 }
@@ -2527,12 +2525,13 @@
         // TODO(b/137329632): find the next activity directly underneath this one, not just anywhere
         final ActivityRecord next = getDisplay().topRunningActivity(
                 true /* considerKeyguardState */);
-        final boolean isVisible = visible || nowVisible;
+        final boolean isVisible = mVisibleRequested || nowVisible;
         // isNextNotYetVisible is to check if the next activity is invisible, or it has been
         // requested to be invisible but its windows haven't reported as invisible.  If so, it
         // implied that the current finishing activity should be added into stopping list rather
         // than destroy immediately.
-        final boolean isNextNotYetVisible = next != null && (!next.nowVisible || !next.visible);
+        final boolean isNextNotYetVisible = next != null
+                && (!next.nowVisible || !next.mVisibleRequested);
         if (isVisible && isNextNotYetVisible) {
             // Add this activity to the list of stopping activities. It will be processed and
             // destroyed when the next activity reports idle.
@@ -3214,7 +3213,7 @@
                 }
                 if (!fromActivity.isHidden()) {
                     setHidden(false);
-                    hiddenRequested = false;
+                    mVisibleRequested = true;
                     mHiddenSetFromTransferredStartingWindow = true;
                 }
                 setClientHidden(fromActivity.mClientHidden);
@@ -3263,7 +3262,7 @@
             if (fromActivity == this) {
                 return;
             }
-            if (fromActivity.hiddenRequested && transferStartingWindow(fromActivity.token)) {
+            if (!fromActivity.mVisibleRequested && transferStartingWindow(fromActivity.token)) {
                 return;
             }
         }
@@ -3778,6 +3777,10 @@
         return opts;
     }
 
+    boolean allowMoveToFront() {
+        return pendingOptions == null || !pendingOptions.getAvoidMoveToFront();
+    }
+
     void removeUriPermissionsLocked() {
         if (uriPermissions != null) {
             uriPermissions.removeUriPermissions();
@@ -3814,7 +3817,7 @@
             return;
         }
         mDeferHidingClient = deferHidingClient;
-        if (!mDeferHidingClient && !visible) {
+        if (!mDeferHidingClient && !mVisibleRequested) {
             // Hiding the client is no longer deferred and the app isn't visible still, go ahead and
             // update the visibility.
             setVisibility(false);
@@ -3834,20 +3837,17 @@
                     + appToken);
             return;
         }
+        if (visible) {
+            mDeferHidingClient = false;
+        }
         setVisibility(visible, mDeferHidingClient);
         mAtmService.addWindowLayoutReasons(
                 ActivityTaskManagerService.LAYOUT_REASON_VISIBILITY_CHANGED);
         mStackSupervisor.getActivityMetricsLogger().notifyVisibilityChanged(this);
-    }
-
-    // TODO: Look into merging with #commitVisibility()
-    void setVisible(boolean newVisible) {
-        visible = newVisible;
-        mDeferHidingClient = !visible && mDeferHidingClient;
-        setVisibility(visible);
         mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
     }
 
+    @VisibleForTesting
     void setVisibility(boolean visible, boolean deferHidingClient) {
         final AppTransition appTransition = getDisplayContent().mAppTransition;
 
@@ -3858,7 +3858,7 @@
         // transition can be selected.
         // TODO: Probably a good idea to separate the concept of opening/closing apps from the
         // concept of setting visibility...
-        if (!visible && hiddenRequested) {
+        if (!visible && !mVisibleRequested) {
 
             if (!deferHidingClient && mLastDeferHidingClient) {
                 // We previously deferred telling the client to hide itself when visibility was
@@ -3870,8 +3870,8 @@
         }
 
         ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
-                "setAppVisibility(%s, visible=%b): %s hidden=%b hiddenRequested=%b Callers=%s",
-                appToken, visible, appTransition, isHidden(), hiddenRequested,
+                "setAppVisibility(%s, visible=%b): %s hidden=%b mVisibleRequested=%b Callers=%s",
+                appToken, visible, appTransition, isHidden(), mVisibleRequested,
                 Debug.getCallers(6));
 
         final DisplayContent displayContent = getDisplayContent();
@@ -3882,7 +3882,7 @@
         }
         displayContent.mChangingApps.remove(this);
         waitingToShow = false;
-        hiddenRequested = !visible;
+        mVisibleRequested = visible;
         mLastDeferHidingClient = deferHidingClient;
 
         if (!visible) {
@@ -4021,7 +4021,7 @@
             }
 
             setHidden(!visible);
-            hiddenRequested = !visible;
+            mVisibleRequested = visible;
             visibilityChanged = true;
             if (!visible) {
                 stopFreezingScreen(true, true);
@@ -4039,8 +4039,8 @@
             }
 
             ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
-                    "commitVisibility: %s: hidden=%b hiddenRequested=%b", this,
-                    isHidden(), hiddenRequested);
+                    "commitVisibility: %s: hidden=%b visibleRequested=%b", this,
+                    isHidden(), mVisibleRequested);
 
             if (changed) {
                 displayContent.getInputMonitor().setUpdateInputWindowsNeededLw();
@@ -4380,7 +4380,7 @@
                 updateOptionsLocked(returningOptions);
                 stack.mUndrawnActivitiesBelowTopTranslucent.add(this);
             }
-            setVisible(true);
+            setVisibility(true);
             sleeping = false;
             app.postPendingUiCleanMsg(true);
             if (reportToClient) {
@@ -4416,7 +4416,7 @@
     }
 
     void makeInvisible() {
-        if (!visible) {
+        if (!mVisibleRequested) {
             if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + this);
             return;
         }
@@ -4438,7 +4438,7 @@
             final boolean deferHidingClient = canEnterPictureInPicture
                     && !isState(STOPPING, STOPPED, PAUSED);
             setDeferHidingClient(deferHidingClient);
-            setVisible(false);
+            setVisibility(false);
 
             switch (getState()) {
                 case STOPPING:
@@ -4625,8 +4625,8 @@
      * state to match that fact.
      */
     void completeResumeLocked() {
-        final boolean wasVisible = visible;
-        setVisible(true);
+        final boolean wasVisible = mVisibleRequested;
+        setVisibility(true);
         if (!wasVisible) {
             // Visibility has changed, so take a note of it so we call the TaskStackChangedListener
             mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
@@ -4710,15 +4710,16 @@
             }
             setState(STOPPING, "stopIfPossible");
             if (DEBUG_VISIBILITY) {
-                Slog.v(TAG_VISIBILITY, "Stopping visible=" + visible + " for " + this);
+                Slog.v(TAG_VISIBILITY, "Stopping visibleRequested="
+                        + mVisibleRequested + " for " + this);
             }
-            if (!visible) {
-                setVisible(false);
+            if (!mVisibleRequested) {
+                setVisibility(false);
             }
             EventLogTags.writeAmStopActivity(
                     mUserId, System.identityHashCode(this), shortComponentName);
             mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
-                    StopActivityItem.obtain(visible, configChangeFlags));
+                    StopActivityItem.obtain(mVisibleRequested, configChangeFlags));
             if (stack.shouldSleepOrShutDownActivities()) {
                 setSleeping(true);
             }
@@ -4881,10 +4882,10 @@
 
     void startFreezingScreen() {
         ProtoLog.i(WM_DEBUG_ORIENTATION,
-                "Set freezing of %s: hidden=%b freezing=%b hiddenRequested=%b. %s",
-                appToken, isHidden(), mFreezingScreen, hiddenRequested,
+                "Set freezing of %s: hidden=%b freezing=%b visibleRequested=%b. %s",
+                appToken, isHidden(), mFreezingScreen, mVisibleRequested,
                 new RuntimeException().fillInStackTrace());
-        if (!hiddenRequested) {
+        if (mVisibleRequested) {
             if (!mFreezingScreen) {
                 mFreezingScreen = true;
                 mWmService.registerAppFreezeListener(this);
@@ -5163,7 +5164,7 @@
                     Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceController
                             + " pv=" + w.isVisibleByPolicy()
                             + " mDrawState=" + winAnimator.drawStateToString()
-                            + " ph=" + w.isParentWindowHidden() + " th=" + hiddenRequested
+                            + " ph=" + w.isParentWindowHidden() + " th=" + mVisibleRequested
                             + " a=" + isAnimating(TRANSITION));
                 }
             }
@@ -5271,7 +5272,7 @@
      * currently pausing, or is resumed.
      */
     public boolean isInterestingToUserLocked() {
-        return visible || nowVisible || mState == PAUSING || mState == RESUMED;
+        return mVisibleRequested || nowVisible || mState == PAUSING || mState == RESUMED;
     }
 
     void setSleeping(boolean _sleeping) {
@@ -5345,7 +5346,7 @@
             // We're not ready for this kind of thing.
             return false;
         }
-        if (visible) {
+        if (mVisibleRequested) {
             // The user would notice this!
             return false;
         }
@@ -5903,7 +5904,7 @@
                 "AppWindowToken");
 
         clearThumbnail();
-        setClientHidden(isHidden() && hiddenRequested);
+        setClientHidden(isHidden() && !mVisibleRequested);
 
         getDisplayContent().computeImeTargetIfNeeded(this);
 
@@ -6499,7 +6500,7 @@
         if (display == null) {
             return;
         }
-        if (visible) {
+        if (mVisibleRequested) {
             // It may toggle the UI for user to restart the size compatibility mode activity.
             display.handleActivitySizeCompatModeIfNeeded(this);
         } else if (mCompatDisplayInsets != null) {
@@ -6796,7 +6797,7 @@
             } else {
                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                         "Config is relaunching " + this);
-                if (DEBUG_STATES && !visible) {
+                if (DEBUG_STATES && !mVisibleRequested) {
                     Slog.v(TAG_STATES, "Config is relaunching invisible activity " + this
                             + " called by " + Debug.getCallers(4));
                 }
@@ -6982,7 +6983,7 @@
         // Reset the existing override configuration so it can be updated according to the latest
         // configuration.
         clearSizeCompatMode();
-        if (visible) {
+        if (mVisibleRequested) {
             // Configuration will be ensured when becoming visible, so if it is already visible,
             // then the manual update is needed.
             updateSizeCompatMode();
@@ -6995,7 +6996,7 @@
         // The restarting state avoids removing this record when process is died.
         setState(RESTARTING_PROCESS, "restartActivityProcess");
 
-        if (!visible || mHaveState) {
+        if (!mVisibleRequested || mHaveState) {
             // Kill its process immediately because the activity should be in background.
             // The activity state will be update to {@link #DESTROYED} in
             // {@link ActivityStack#cleanUp} when handling process died.
@@ -7286,7 +7287,7 @@
         writeToProto(proto, APP_WINDOW_TOKEN, WindowTraceLogLevel.ALL);
         writeIdentifierToProto(proto, IDENTIFIER);
         proto.write(STATE, mState.toString());
-        proto.write(VISIBLE, visible);
+        proto.write(VISIBLE, mVisibleRequested);
         proto.write(FRONT_OF_TASK, isRootOfTask());
         if (hasProcess()) {
             proto.write(PROC_ID, app.getPid());
@@ -7322,7 +7323,7 @@
         }
         proto.write(FILLS_PARENT, mOccludesParent);
         proto.write(APP_STOPPED, mAppStopped);
-        proto.write(HIDDEN_REQUESTED, hiddenRequested);
+        proto.write(VISIBLE_REQUESTED, mVisibleRequested);
         proto.write(CLIENT_HIDDEN, mClientHidden);
         proto.write(DEFER_HIDING_CLIENT, mDeferHidingClient);
         proto.write(REPORTED_DRAWN, reportedDrawn);
diff --git a/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java b/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
index c56a9e2..6e75f9c 100644
--- a/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
+++ b/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
@@ -73,7 +73,7 @@
 
     public boolean isActivityVisible() {
         synchronized (mService.mGlobalLock) {
-            return mActivity.visible || mActivity.isState(RESUMED, PAUSING);
+            return mActivity.mVisibleRequested || mActivity.isState(RESUMED, PAUSING);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index d7e6852..ac94125 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -1693,7 +1693,8 @@
                 prev = prev.completeFinishing("completePausedLocked");
             } else if (prev.hasProcess()) {
                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev
-                        + " wasStopping=" + wasStopping + " visible=" + prev.visible);
+                        + " wasStopping=" + wasStopping
+                        + " visibleRequested=" + prev.mVisibleRequested);
                 if (prev.deferRelaunchUntilPaused) {
                     // Complete the deferred relaunch that was waiting for pause to complete.
                     if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
@@ -1703,7 +1704,7 @@
                     // We can't clobber it, because the stop confirmation will not be handled.
                     // We don't need to schedule another stop, we only need to let it happen.
                     prev.setState(STOPPING, "completePausedLocked");
-                } else if (!prev.visible || shouldSleepOrShutDownActivities()) {
+                } else if (!prev.mVisibleRequested || shouldSleepOrShutDownActivities()) {
                     // Clear out any deferred client hide we might currently have.
                     prev.setDeferHidingClient(false);
                     // If we were visible then resumeTopActivities will release resources before
@@ -1824,7 +1825,7 @@
 
     boolean isTopActivityVisible() {
         final ActivityRecord topActivity = getTopNonFinishingActivity();
-        return topActivity != null && topActivity.visible;
+        return topActivity != null && topActivity.mVisibleRequested;
     }
 
     /**
@@ -1965,7 +1966,7 @@
         for (int taskNdx = getChildCount() - 1; taskNdx >= 0; --taskNdx) {
             final Task task = getChildAt(taskNdx);
             ActivityRecord r = task.topRunningActivityLocked();
-            if (r == null || r.finishing || !r.visible) {
+            if (r == null || r.finishing || !r.mVisibleRequested) {
                 task.mLayerRank = -1;
             } else {
                 task.mLayerRank = baseLayer + layer++;
@@ -2054,7 +2055,7 @@
                         if (!r.attachedToProcess()) {
                             makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,
                                     resumeTopActivity && isTop, r);
-                        } else if (r.visible) {
+                        } else if (r.mVisibleRequested) {
                             // If this activity is already visible, then there is nothing to do here.
                             if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                                     "Skipping: already visible at " + r);
@@ -2231,16 +2232,16 @@
         // invisible. If the app is already visible, it must have died while it was visible. In this
         // case, we'll show the dead window but will not restart the app. Otherwise we could end up
         // thrashing.
-        if (isTop || !r.visible) {
+        if (isTop || !r.mVisibleRequested) {
             // This activity needs to be visible, but isn't even running...
             // get it started and resume if no other stack in this stack is resumed.
             if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r);
             if (r != starting) {
                 r.startFreezingScreenLocked(configChanges);
             }
-            if (!r.visible || r.mLaunchTaskBehind) {
+            if (!r.mVisibleRequested || r.mLaunchTaskBehind) {
                 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r);
-                r.setVisible(true);
+                r.setVisibility(true);
             }
             if (r != starting) {
                 mStackSupervisor.startSpecificActivityLocked(r, andResume, true /* checkConfig */);
@@ -2683,7 +2684,8 @@
 
         if (next.attachedToProcess()) {
             if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next
-                    + " stopped=" + next.stopped + " visible=" + next.visible);
+                    + " stopped=" + next.stopped
+                    + " visibleRequested=" + next.mVisibleRequested);
 
             // If the previous activity is translucent, force a visibility update of
             // the next activity, so that it's added to WM's opening app list, and
@@ -2698,7 +2700,7 @@
                     && !lastFocusedStack.mLastPausedActivity.occludesParent()));
 
             // This activity is now becoming visible.
-            if (!next.visible || next.stopped || lastActivityTranslucent) {
+            if (!next.mVisibleRequested || next.stopped || lastActivityTranslucent) {
                 next.setVisibility(true);
             }
 
@@ -2753,7 +2755,7 @@
                     // Do over!
                     mStackSupervisor.scheduleResumeTopActivities();
                 }
-                if (!next.visible || next.stopped) {
+                if (!next.mVisibleRequested || next.stopped) {
                     next.setVisibility(true);
                 }
                 next.completeResumeLocked();
@@ -3422,7 +3424,7 @@
 
         final ActivityRecord top = stack.topRunningActivityLocked();
 
-        if (stack.isActivityTypeHome() && (top == null || !top.visible)) {
+        if (stack.isActivityTypeHome() && (top == null || !top.mVisibleRequested)) {
             // If we will be focusing on the home stack next and its current top activity isn't
             // visible, then use the move the home stack task to top to make the activity visible.
             stack.getDisplay().moveHomeActivityToTop(reason);
@@ -3919,7 +3921,10 @@
                         "Record #" + targetIndex + " " + r + ": app=" + r.app);
 
                 if (r.app == app) {
-                    if (r.visible) {
+                    if (r.isVisible() || r.mVisibleRequested) {
+                        // While an activity launches a new activity, it's possible that the old
+                        // activity is already requested to be hidden (mVisibleRequested=false), but
+                        // this visibility is not yet committed, so isVisible()=true.
                         hasVisibleActivities = true;
                     }
                     final boolean remove;
@@ -3935,8 +3940,8 @@
                         // Don't currently have state for the activity, or
                         // it is finishing -- always remove it.
                         remove = true;
-                    } else if (!r.visible && r.launchCount > 2 &&
-                            r.lastLaunchTime > (SystemClock.uptimeMillis() - 60000)) {
+                    } else if (!r.mVisibleRequested && r.launchCount > 2
+                            && r.lastLaunchTime > (SystemClock.uptimeMillis() - 60000)) {
                         // We have launched this activity too many times since it was
                         // able to run, so give up and remove it.
                         // (Note if the activity is visible, we don't remove the record.
@@ -3972,7 +3977,7 @@
                         // it died, we leave the dead window on screen so it's basically visible.
                         // This is needed when user later tap on the dead window, we need to stop
                         // other apps when user transfers focus to the restarted activity.
-                        r.nowVisible = r.visible;
+                        r.nowVisible = r.mVisibleRequested;
                     }
                     r.cleanUp(true /* cleanServices */, true /* setState */);
                     if (remove) {
@@ -4155,7 +4160,7 @@
      * Ensures all visible activities at or below the input activity have the right configuration.
      */
     void ensureVisibleActivitiesConfigurationLocked(ActivityRecord start, boolean preserveWindow) {
-        if (start == null || !start.visible) {
+        if (start == null || !start.mVisibleRequested) {
             return;
         }
 
@@ -4550,7 +4555,7 @@
                 final ActivityRecord a = task.getChildAt(activityNdx);
                 if (a.info.packageName.equals(packageName)) {
                     a.forceNewConfig = true;
-                    if (starting != null && a == starting && a.visible) {
+                    if (starting != null && a == starting && a.mVisibleRequested) {
                         a.startFreezingScreenLocked(CONFIG_SCREEN_LAYOUT);
                     }
                 }
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 530fdcf..6ea80d2 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -773,12 +773,11 @@
             }
 
             if (r.getActivityStack().checkKeyguardVisibility(r, true /* shouldBeVisible */,
-                    true /* isTop */)) {
-                // We only set the visibility to true if the activity is allowed to be visible
-                // based on
-                // keyguard state. This avoids setting this into motion in window manager that is
-                // later cancelled due to later calls to ensure visible activities that set
-                // visibility back to false.
+                    true /* isTop */) && r.allowMoveToFront()) {
+                // We only set the visibility to true if the activity is not being launched in
+                // background, and is allowed to be visible based on keyguard state. This avoids
+                // setting this into motion in window manager that is later cancelled due to later
+                // calls to ensure visible activities that set visibility back to false.
                 r.setVisibility(true);
             }
 
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index db41968..456f650 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -34,9 +34,9 @@
 import static android.view.Display.FLAG_PRIVATE;
 import static android.view.Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
 import static android.view.Display.INVALID_DISPLAY;
-import static android.view.InsetsState.TYPE_IME;
-import static android.view.InsetsState.TYPE_LEFT_GESTURES;
-import static android.view.InsetsState.TYPE_RIGHT_GESTURES;
+import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
+import static android.view.InsetsState.ITYPE_RIGHT_GESTURES;
 import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_180;
 import static android.view.Surface.ROTATION_270;
@@ -178,7 +178,7 @@
 import android.view.InputChannel;
 import android.view.InputDevice;
 import android.view.InputWindowHandle;
-import android.view.InsetsState.InternalInsetType;
+import android.view.InsetsState.InternalInsetsType;
 import android.view.MagnificationSpec;
 import android.view.RemoteAnimationDefinition;
 import android.view.Surface;
@@ -645,11 +645,11 @@
             final ActivityRecord activity = w.mActivityRecord;
             if (gone) Slog.v(TAG, "  GONE: mViewVisibility=" + w.mViewVisibility
                     + " mRelayoutCalled=" + w.mRelayoutCalled + " hidden=" + w.mToken.isHidden()
-                    + " hiddenRequested=" + (activity != null && activity.hiddenRequested)
+                    + " visibleRequested=" + (activity != null && activity.mVisibleRequested)
                     + " parentHidden=" + w.isParentWindowHidden());
             else Slog.v(TAG, "  VIS: mViewVisibility=" + w.mViewVisibility
                     + " mRelayoutCalled=" + w.mRelayoutCalled + " hidden=" + w.mToken.isHidden()
-                    + " hiddenRequested=" + (activity != null && activity.hiddenRequested)
+                    + " visibleRequested=" + (activity != null && activity.mVisibleRequested)
                     + " parentHidden=" + w.isParentWindowHidden());
         }
 
@@ -1093,7 +1093,7 @@
      * @param frameProvider Function to compute the frame, or {@code null} if the just the frame of
      *                      the window should be taken.
      */
-    void setInsetProvider(@InternalInsetType int type, WindowState win,
+    void setInsetProvider(@InternalInsetsType int type, WindowState win,
             @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider) {
         mInsetsStateController.getSourceProvider(type).setWindow(win, frameProvider);
     }
@@ -3088,7 +3088,7 @@
                     mInputMethodWindow.getDisplayId());
         }
         computeImeTarget(true /* updateImeTarget */);
-        mInsetsStateController.getSourceProvider(TYPE_IME).setWindow(win,
+        mInsetsStateController.getSourceProvider(ITYPE_IME).setWindow(win,
                 null /* frameProvider */);
     }
 
@@ -4999,9 +4999,9 @@
         final Region unhandled = Region.obtain();
         unhandled.set(0, 0, mDisplayFrames.mDisplayWidth, mDisplayFrames.mDisplayHeight);
 
-        final Rect leftEdge = mInsetsStateController.getSourceProvider(TYPE_LEFT_GESTURES)
+        final Rect leftEdge = mInsetsStateController.getSourceProvider(ITYPE_LEFT_GESTURES)
                 .getSource().getFrame();
-        final Rect rightEdge = mInsetsStateController.getSourceProvider(TYPE_RIGHT_GESTURES)
+        final Rect rightEdge = mInsetsStateController.getSourceProvider(ITYPE_RIGHT_GESTURES)
                 .getSource().getFrame();
 
         final Region touchableRegion = Region.obtain();
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index f8c1ad9..8d5f90d 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -25,14 +25,19 @@
 import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
 import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
 import static android.view.Display.TYPE_BUILT_IN;
-import static android.view.InsetsState.TYPE_TOP_BAR;
-import static android.view.InsetsState.TYPE_TOP_GESTURES;
-import static android.view.InsetsState.TYPE_TOP_TAPPABLE_ELEMENT;
+import static android.view.InsetsState.ITYPE_BOTTOM_GESTURES;
+import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
+import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_RIGHT_GESTURES;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
+import static android.view.InsetsState.ITYPE_TOP_GESTURES;
+import static android.view.InsetsState.ITYPE_TOP_TAPPABLE_ELEMENT;
 import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE;
-import static android.view.WindowInsetsController.APPEARANCE_LIGHT_TOP_BAR;
+import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE;
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
 import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION;
@@ -144,8 +149,7 @@
 import android.view.InputEvent;
 import android.view.InputEventReceiver;
 import android.view.InsetsFlags;
-import android.view.InsetsState;
-import android.view.InsetsState.InternalInsetType;
+import android.view.InsetsState.InternalInsetsType;
 import android.view.MotionEvent;
 import android.view.PointerIcon;
 import android.view.Surface;
@@ -970,36 +974,36 @@
                             rect.top = 0;
                             rect.bottom = getStatusBarHeight(displayFrames);
                         };
-                mDisplayContent.setInsetProvider(TYPE_TOP_BAR, win, frameProvider);
-                mDisplayContent.setInsetProvider(TYPE_TOP_GESTURES, win, frameProvider);
-                mDisplayContent.setInsetProvider(TYPE_TOP_TAPPABLE_ELEMENT, win, frameProvider);
+                mDisplayContent.setInsetProvider(ITYPE_STATUS_BAR, win, frameProvider);
+                mDisplayContent.setInsetProvider(ITYPE_TOP_GESTURES, win, frameProvider);
+                mDisplayContent.setInsetProvider(ITYPE_TOP_TAPPABLE_ELEMENT, win, frameProvider);
                 break;
             case TYPE_NAVIGATION_BAR:
                 mNavigationBar = win;
                 mNavigationBarController.setWindow(win);
                 mNavigationBarController.setOnBarVisibilityChangedListener(
                         mNavBarVisibilityListener, true);
-                mDisplayContent.setInsetProvider(InsetsState.TYPE_NAVIGATION_BAR,
+                mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR,
                         win, null /* frameProvider */);
-                mDisplayContent.setInsetProvider(InsetsState.TYPE_BOTTOM_GESTURES, win,
+                mDisplayContent.setInsetProvider(ITYPE_BOTTOM_GESTURES, win,
                         (displayFrames, windowState, inOutFrame) -> {
                             inOutFrame.top -= mBottomGestureAdditionalInset;
                         });
-                mDisplayContent.setInsetProvider(InsetsState.TYPE_LEFT_GESTURES, win,
+                mDisplayContent.setInsetProvider(ITYPE_LEFT_GESTURES, win,
                         (displayFrames, windowState, inOutFrame) -> {
                             inOutFrame.left = 0;
                             inOutFrame.top = 0;
                             inOutFrame.bottom = displayFrames.mDisplayHeight;
                             inOutFrame.right = displayFrames.mUnrestricted.left + mSideGestureInset;
                         });
-                mDisplayContent.setInsetProvider(InsetsState.TYPE_RIGHT_GESTURES, win,
+                mDisplayContent.setInsetProvider(ITYPE_RIGHT_GESTURES, win,
                         (displayFrames, windowState, inOutFrame) -> {
                             inOutFrame.left = displayFrames.mUnrestricted.right - mSideGestureInset;
                             inOutFrame.top = 0;
                             inOutFrame.bottom = displayFrames.mDisplayHeight;
                             inOutFrame.right = displayFrames.mDisplayWidth;
                         });
-                mDisplayContent.setInsetProvider(InsetsState.TYPE_BOTTOM_TAPPABLE_ELEMENT, win,
+                mDisplayContent.setInsetProvider(ITYPE_BOTTOM_TAPPABLE_ELEMENT, win,
                         (displayFrames, windowState, inOutFrame) -> {
                             if ((windowState.getAttrs().flags & FLAG_NOT_TOUCHABLE) != 0
                                     || mNavigationBarLetsThroughTaps) {
@@ -1024,11 +1028,11 @@
             if (mDisplayContent.isDefaultDisplay) {
                 mService.mPolicy.setKeyguardCandidateLw(null);
             }
-            mDisplayContent.setInsetProvider(TYPE_TOP_BAR, null, null);
+            mDisplayContent.setInsetProvider(ITYPE_STATUS_BAR, null, null);
         } else if (mNavigationBar == win) {
             mNavigationBar = null;
             mNavigationBarController.setWindow(null);
-            mDisplayContent.setInsetProvider(InsetsState.TYPE_NAVIGATION_BAR, null, null);
+            mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, null, null);
         }
         if (mLastFocusedWindow == win) {
             mLastFocusedWindow = null;
@@ -2955,7 +2959,7 @@
             }
             if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL) {
                 if (swipeTarget == mNavigationBar
-                        && !getInsetsPolicy().isHidden(InsetsState.TYPE_NAVIGATION_BAR)) {
+                        && !getInsetsPolicy().isHidden(ITYPE_NAVIGATION_BAR)) {
                     // Don't show status bar when swiping on already visible navigation bar
                     return;
                 }
@@ -2966,7 +2970,7 @@
                 }
                 if (controlTarget.canShowTransient()) {
                     mDisplayContent.getInsetsPolicy().showTransient(IntArray.wrap(
-                            new int[]{TYPE_TOP_BAR, InsetsState.TYPE_NAVIGATION_BAR}));
+                            new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}));
                 } else {
                     controlTarget.showInsets(WindowInsets.Type.systemBars(), false);
                 }
@@ -3080,9 +3084,9 @@
         final boolean isFullscreen = (visibility & (View.SYSTEM_UI_FLAG_FULLSCREEN
                         | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)) != 0
                 || (PolicyControl.getWindowFlags(win, win.mAttrs) & FLAG_FULLSCREEN) != 0
-                || (mStatusBar != null && insetsPolicy.isHidden(TYPE_TOP_BAR))
+                || (mStatusBar != null && insetsPolicy.isHidden(ITYPE_STATUS_BAR))
                 || (mNavigationBar != null && insetsPolicy.isHidden(
-                        InsetsState.TYPE_NAVIGATION_BAR));
+                        ITYPE_NAVIGATION_BAR));
         final int behavior = win.mAttrs.insetsFlags.behavior;
         final boolean isImmersive = (visibility & (View.SYSTEM_UI_FLAG_IMMERSIVE
                         | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)) != 0
@@ -3149,15 +3153,15 @@
     private static Pair<int[], int[]> getTransientState(int vis, int oldVis) {
         final IntArray typesToShow = new IntArray(0);
         final IntArray typesToAbort = new IntArray(0);
-        updateTransientState(vis, oldVis, View.STATUS_BAR_TRANSIENT, TYPE_TOP_BAR, typesToShow,
+        updateTransientState(vis, oldVis, View.STATUS_BAR_TRANSIENT, ITYPE_STATUS_BAR, typesToShow,
                 typesToAbort);
         updateTransientState(vis, oldVis, View.NAVIGATION_BAR_TRANSIENT,
-                InsetsState.TYPE_NAVIGATION_BAR, typesToShow, typesToAbort);
+                ITYPE_NAVIGATION_BAR, typesToShow, typesToAbort);
         return Pair.create(typesToShow.toArray(), typesToAbort.toArray());
     }
 
     private static void updateTransientState(int vis, int oldVis, int transientFlag,
-            @InternalInsetType int type, IntArray typesToShow, IntArray typesToAbort) {
+            @InternalInsetsType int type, IntArray typesToShow, IntArray typesToAbort) {
         final boolean wasTransient = (oldVis & transientFlag) != 0;
         final boolean isTransient = (vis & transientFlag) != 0;
         if (!wasTransient && isTransient) {
@@ -3174,14 +3178,14 @@
         if (statusColorWin != null && (statusColorWin == opaque || onKeyguard)) {
             // If the top fullscreen-or-dimming window is also the top fullscreen, respect
             // its light flag.
-            appearance &= ~APPEARANCE_LIGHT_TOP_BAR;
+            appearance &= ~APPEARANCE_LIGHT_STATUS_BARS;
             final int legacyAppearance = InsetsFlags.getAppearance(
                     PolicyControl.getSystemUiVisibility(statusColorWin, null));
             appearance |= (statusColorWin.mAttrs.insetsFlags.appearance | legacyAppearance)
-                    & APPEARANCE_LIGHT_TOP_BAR;
+                    & APPEARANCE_LIGHT_STATUS_BARS;
         } else if (statusColorWin != null && statusColorWin.isDimming()) {
             // Otherwise if it's dimming, clear the light flag.
-            appearance &= ~APPEARANCE_LIGHT_TOP_BAR;
+            appearance &= ~APPEARANCE_LIGHT_STATUS_BARS;
         }
         return appearance;
     }
@@ -3508,7 +3512,7 @@
                 if (!isNavBarEmpty(mLastSystemUiFlags)) {
                     mNavigationBarController.showTransient();
                     mDisplayContent.getInsetsPolicy().showTransient(IntArray.wrap(
-                            new int[] {InsetsState.TYPE_NAVIGATION_BAR}));
+                            new int[] {ITYPE_NAVIGATION_BAR}));
                 }
             }
         }
diff --git a/services/core/java/com/android/server/wm/InsetsControlTarget.java b/services/core/java/com/android/server/wm/InsetsControlTarget.java
index c8ce53d..154cde1 100644
--- a/services/core/java/com/android/server/wm/InsetsControlTarget.java
+++ b/services/core/java/com/android/server/wm/InsetsControlTarget.java
@@ -17,7 +17,7 @@
 package com.android.server.wm;
 
 import android.inputmethodservice.InputMethodService;
-import android.view.WindowInsets.Type.InsetType;
+import android.view.WindowInsets.Type.InsetsType;
 
 /**
  * Generalization of an object that can control insets state.
@@ -31,7 +31,7 @@
      * @param types to specify which types of insets source window should be shown.
      * @param fromIme {@code true} if IME show request originated from {@link InputMethodService}.
      */
-    default void showInsets(@InsetType int types, boolean fromIme) {
+    default void showInsets(@InsetsType int types, boolean fromIme) {
     }
 
     /**
@@ -40,7 +40,7 @@
      * @param types to specify which types of insets source window should be hidden.
      * @param fromIme {@code true} if IME hide request originated from {@link InputMethodService}.
      */
-    default void hideInsets(@InsetType int types, boolean fromIme) {
+    default void hideInsets(@InsetsType int types, boolean fromIme) {
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index fc51b46..d50bcc4 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -20,8 +20,8 @@
 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.TYPE_TOP_BAR;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
@@ -30,7 +30,7 @@
 import android.app.StatusBarManager;
 import android.util.IntArray;
 import android.view.InsetsState;
-import android.view.InsetsState.InternalInsetType;
+import android.view.InsetsState.InternalInsetsType;
 import android.view.ViewRootImpl;
 
 /**
@@ -66,13 +66,13 @@
         }
         mTopBar.setVisible(focusedWin == null
                 || focusedWin != getTopControlTarget(focusedWin)
-                || focusedWin.getClientInsetsState().getSource(TYPE_TOP_BAR).isVisible());
+                || focusedWin.getClientInsetsState().getSource(ITYPE_STATUS_BAR).isVisible());
         mNavBar.setVisible(focusedWin == null
                 || focusedWin != getNavControlTarget(focusedWin)
-                || focusedWin.getClientInsetsState().getSource(TYPE_NAVIGATION_BAR).isVisible());
+                || focusedWin.getClientInsetsState().getSource(ITYPE_NAVIGATION_BAR).isVisible());
     }
 
-    boolean isHidden(@InternalInsetType int type) {
+    boolean isHidden(@InternalInsetsType int type) {
         final InsetsSourceProvider provider =  mStateController.peekSourceProvider(type);
         return provider != null && provider.hasWindow() && !provider.getSource().isVisible();
     }
@@ -131,10 +131,10 @@
             return;
         }
         if (windowState == getTopControlTarget(mFocusedWin)) {
-            mTopBar.setVisible(state.getSource(TYPE_TOP_BAR).isVisible());
+            mTopBar.setVisible(state.getSource(ITYPE_STATUS_BAR).isVisible());
         }
         if (windowState == getNavControlTarget(mFocusedWin)) {
-            mNavBar.setVisible(state.getSource(TYPE_NAVIGATION_BAR).isVisible());
+            mNavBar.setVisible(state.getSource(ITYPE_NAVIGATION_BAR).isVisible());
         }
     }
 
@@ -165,21 +165,21 @@
     }
 
     private @Nullable InsetsControlTarget getFakeTopControlTarget(@Nullable WindowState focused) {
-        if (mShowingTransientTypes.indexOf(TYPE_TOP_BAR) != -1) {
+        if (mShowingTransientTypes.indexOf(ITYPE_STATUS_BAR) != -1) {
             return focused;
         }
         return null;
     }
 
     private @Nullable InsetsControlTarget getFakeNavControlTarget(@Nullable WindowState focused) {
-        if (mShowingTransientTypes.indexOf(TYPE_NAVIGATION_BAR) != -1) {
+        if (mShowingTransientTypes.indexOf(ITYPE_NAVIGATION_BAR) != -1) {
             return focused;
         }
         return null;
     }
 
     private @Nullable InsetsControlTarget getTopControlTarget(@Nullable WindowState focusedWin) {
-        if (mShowingTransientTypes.indexOf(TYPE_TOP_BAR) != -1) {
+        if (mShowingTransientTypes.indexOf(ITYPE_STATUS_BAR) != -1) {
             return mTransientControlTarget;
         }
         if (areSystemBarsForciblyVisible() || isStatusBarForciblyVisible()) {
@@ -189,7 +189,7 @@
     }
 
     private @Nullable InsetsControlTarget getNavControlTarget(@Nullable WindowState focusedWin) {
-        if (mShowingTransientTypes.indexOf(TYPE_NAVIGATION_BAR) != -1) {
+        if (mShowingTransientTypes.indexOf(ITYPE_NAVIGATION_BAR) != -1) {
             return mTransientControlTarget;
         }
         if (areSystemBarsForciblyVisible() || isNavBarForciblyVisible()) {
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index a7724a1..b4055545 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -16,9 +16,9 @@
 
 package com.android.server.wm;
 
-import static android.view.InsetsState.TYPE_IME;
-import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.TYPE_TOP_BAR;
+import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_IME;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE;
@@ -81,9 +81,9 @@
                 new Point());
 
         final int type = source.getType();
-        if (type == TYPE_TOP_BAR || type == TYPE_NAVIGATION_BAR) {
+        if (type == ITYPE_STATUS_BAR || type == ITYPE_NAVIGATION_BAR) {
             mControllable = sNewInsetsMode == NEW_INSETS_MODE_FULL;
-        } else if (type == TYPE_IME) {
+        } else if (type == ITYPE_IME) {
             mControllable = sNewInsetsMode >= NEW_INSETS_MODE_IME;
         } else {
             mControllable = false;
@@ -256,7 +256,7 @@
                 OnAnimationFinishedCallback finishCallback) {
             // TODO(b/118118435): We can remove the type check when implementing the transient bar
             //                    animation.
-            if (mSource.getType() == TYPE_IME) {
+            if (mSource.getType() == ITYPE_IME) {
                 // TODO: use 0 alpha and remove t.hide() once b/138459974 is fixed.
                 t.setAlpha(animationLeash, 1 /* alpha */);
                 t.hide(animationLeash);
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index e055424..1526074 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -16,9 +16,9 @@
 
 package com.android.server.wm;
 
-import static android.view.InsetsState.TYPE_IME;
-import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.TYPE_TOP_BAR;
+import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
 import static android.view.ViewRootImpl.sNewInsetsMode;
 
@@ -30,7 +30,7 @@
 import android.view.InsetsSource;
 import android.view.InsetsSourceControl;
 import android.view.InsetsState;
-import android.view.InsetsState.InternalInsetType;
+import android.view.InsetsState.InternalInsetsType;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -84,9 +84,9 @@
         state.removeSource(type);
 
         // Navigation bar doesn't get influenced by anything else
-        if (type == TYPE_NAVIGATION_BAR) {
-            state.removeSource(TYPE_IME);
-            state.removeSource(TYPE_TOP_BAR);
+        if (type == ITYPE_NAVIGATION_BAR) {
+            state.removeSource(ITYPE_IME);
+            state.removeSource(ITYPE_STATUS_BAR);
         }
         return state;
     }
@@ -107,8 +107,8 @@
     /**
      * @return The provider of a specific type.
      */
-    InsetsSourceProvider getSourceProvider(@InternalInsetType int type) {
-        if (type == TYPE_IME) {
+    InsetsSourceProvider getSourceProvider(@InternalInsetsType int type) {
+        if (type == ITYPE_IME) {
             return mProviders.computeIfAbsent(type,
                     key -> new ImeInsetsSourceProvider(
                             mState.getSource(key), this, mDisplayContent));
@@ -119,13 +119,13 @@
     }
 
     ImeInsetsSourceProvider getImeSourceProvider() {
-        return (ImeInsetsSourceProvider) getSourceProvider(TYPE_IME);
+        return (ImeInsetsSourceProvider) getSourceProvider(ITYPE_IME);
     }
 
     /**
      * @return The provider of a specific type or null if we don't have it.
      */
-    @Nullable InsetsSourceProvider peekSourceProvider(@InternalInsetType int type) {
+    @Nullable InsetsSourceProvider peekSourceProvider(@InternalInsetsType int type) {
         return mProviders.get(type);
     }
 
@@ -159,12 +159,12 @@
         }
     }
 
-    boolean isFakeTarget(@InternalInsetType int type, InsetsControlTarget target) {
+    boolean isFakeTarget(@InternalInsetsType int type, InsetsControlTarget target) {
         return mTypeFakeControlTargetMap.get(type) == target;
     }
 
     void onImeTargetChanged(@Nullable InsetsControlTarget imeTarget) {
-        onControlChanged(TYPE_IME, imeTarget);
+        onControlChanged(ITYPE_IME, imeTarget);
         notifyPendingInsetsControlChanged();
     }
 
@@ -180,10 +180,10 @@
             @Nullable InsetsControlTarget fakeTopControlling,
             @Nullable InsetsControlTarget navControlling,
             @Nullable InsetsControlTarget fakeNavControlling) {
-        onControlChanged(TYPE_TOP_BAR, topControlling);
-        onControlChanged(TYPE_NAVIGATION_BAR, navControlling);
-        onControlFakeTargetChanged(TYPE_TOP_BAR, fakeTopControlling);
-        onControlFakeTargetChanged(TYPE_NAVIGATION_BAR, fakeNavControlling);
+        onControlChanged(ITYPE_STATUS_BAR, topControlling);
+        onControlChanged(ITYPE_NAVIGATION_BAR, navControlling);
+        onControlFakeTargetChanged(ITYPE_STATUS_BAR, fakeTopControlling);
+        onControlFakeTargetChanged(ITYPE_NAVIGATION_BAR, fakeNavControlling);
         notifyPendingInsetsControlChanged();
     }
 
@@ -193,7 +193,7 @@
                 false /* fake */);
     }
 
-    private void onControlChanged(@InternalInsetType int type,
+    private void onControlChanged(@InternalInsetsType int type,
             @Nullable InsetsControlTarget target) {
         final InsetsControlTarget previous = mTypeControlTargetMap.get(type);
         if (target == previous) {
@@ -223,7 +223,7 @@
      * showing/hiding. For example, when the transient bars are showing, and the fake target
      * requests to show system bars, the transient state will be aborted.
      */
-    void onControlFakeTargetChanged(@InternalInsetType  int type,
+    void onControlFakeTargetChanged(@InternalInsetsType int type,
             @Nullable InsetsControlTarget fakeTarget) {
         if (sNewInsetsMode != NEW_INSETS_MODE_FULL) {
             return;
@@ -248,7 +248,7 @@
     }
 
     private void removeFromControlMaps(@NonNull InsetsControlTarget target,
-            @InternalInsetType int type, boolean fake) {
+            @InternalInsetsType int type, boolean fake) {
         final ArrayList<Integer> array = mControlTargetTypeMap.get(target);
         if (array == null) {
             return;
@@ -265,7 +265,7 @@
     }
 
     private void addToControlMaps(@NonNull InsetsControlTarget target,
-            @InternalInsetType int type, boolean fake) {
+            @InternalInsetsType int type, boolean fake) {
         final ArrayList<Integer> array = mControlTargetTypeMap.computeIfAbsent(target,
                 key -> new ArrayList<>());
         array.add(type);
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index 948ed79..a17bd24 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -107,7 +107,7 @@
                 mTargetActivityType);
         ActivityRecord targetActivity = getTargetActivity(targetStack);
         if (targetActivity != null) {
-            if (targetActivity.visible || targetActivity.isTopRunningActivity()) {
+            if (targetActivity.mVisibleRequested || targetActivity.isTopRunningActivity()) {
                 // The activity is ready.
                 return;
             }
@@ -189,7 +189,7 @@
 
         // Send launch hint if we are actually launching the target. If it's already visible
         // (shouldn't happen in general) we don't need to send it.
-        if (targetActivity == null || !targetActivity.visible) {
+        if (targetActivity == null || !targetActivity.mVisibleRequested) {
             mService.mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded(
                     true /* forceSend */, targetActivity);
         }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index ba3b8b7..6ddd943 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -2204,7 +2204,7 @@
     void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
         for (int activityNdx = getChildCount() - 1; activityNdx >= 0; --activityNdx) {
             final ActivityRecord r = getChildAt(activityNdx);
-            if (r.visible) {
+            if (r.mVisibleRequested) {
                 r.showStartingWindow(null /* prev */, false /* newTask */, taskSwitch);
             }
         }
@@ -2508,7 +2508,7 @@
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             final ActivityRecord token = mChildren.get(i);
             // skip hidden (or about to hide) apps
-            if (token.mIsExiting || token.isClientHidden() || token.hiddenRequested) {
+            if (token.mIsExiting || token.isClientHidden() || !token.mVisibleRequested) {
                 continue;
             }
             final WindowState win = token.findMainWindow();
@@ -2728,7 +2728,7 @@
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             final ActivityRecord token = mChildren.get(i);
             // skip hidden (or about to hide) apps
-            if (!token.mIsExiting && !token.isClientHidden() && !token.hiddenRequested) {
+            if (!token.mIsExiting && !token.isClientHidden() && token.mVisibleRequested) {
                 return token;
             }
         }
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 3632284..ef79403 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -532,9 +532,9 @@
         }
 
         final boolean newTargetHidden = wallpaperTarget.mActivityRecord != null
-                && wallpaperTarget.mActivityRecord.hiddenRequested;
+                && !wallpaperTarget.mActivityRecord.mVisibleRequested;
         final boolean oldTargetHidden = prevWallpaperTarget.mActivityRecord != null
-                && prevWallpaperTarget.mActivityRecord.hiddenRequested;
+                && !prevWallpaperTarget.mActivityRecord.mVisibleRequested;
 
         if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Animating wallpapers:" + " old: "
                 + prevWallpaperTarget + " hidden=" + oldTargetHidden + " new: " + wallpaperTarget
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 41e88c8..c1783ef 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -533,7 +533,7 @@
         synchronized (mAtm.mGlobalLockWithoutBoost) {
             for (int i = mActivities.size() - 1; i >= 0; --i) {
                 final ActivityRecord r = mActivities.get(i);
-                if (r.visible) {
+                if (r.mVisibleRequested) {
                     return true;
                 }
             }
@@ -555,7 +555,7 @@
                 continue;
             }
             ActivityRecord topActivity = task.getTopNonFinishingActivity();
-            if (topActivity != null && topActivity.visible) {
+            if (topActivity != null && topActivity.mVisibleRequested) {
                 return true;
             }
         }
@@ -589,7 +589,7 @@
         // - no longer visible OR
         // - not focusable (in PiP mode for instance)
         if (topDisplay == null
-                || !mPreQTopResumedActivity.visible
+                || !mPreQTopResumedActivity.mVisibleRequested
                 || !mPreQTopResumedActivity.isFocusable()) {
             canUpdate = true;
         }
@@ -739,7 +739,7 @@
             }
             // Don't consider any activities that are currently not in a state where they
             // can be destroyed.
-            if (r.visible || !r.stopped || !r.hasSavedState()
+            if (r.mVisibleRequested || !r.stopped || !r.hasSavedState()
                     || r.isState(STARTED, RESUMED, PAUSING, PAUSED, STOPPING)) {
                 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r);
                 continue;
@@ -793,7 +793,7 @@
                         continue;
                     }
                 }
-                if (r.visible) {
+                if (r.mVisibleRequested) {
                     final Task task = r.getTask();
                     if (task != null && minTaskLayer > 0) {
                         final int layer = task.mLayerRank;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index d41e706..593b84f 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -200,7 +200,7 @@
 import android.view.View;
 import android.view.ViewTreeObserver;
 import android.view.WindowInfo;
-import android.view.WindowInsets.Type.InsetType;
+import android.view.WindowInsets.Type.InsetsType;
 import android.view.WindowManager;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
@@ -1560,7 +1560,7 @@
      */
     // TODO: Can we consolidate this with #isVisible() or have a more appropriate name for this?
     boolean isWinVisibleLw() {
-        return (mActivityRecord == null || !mActivityRecord.hiddenRequested
+        return (mActivityRecord == null || mActivityRecord.mVisibleRequested
                 || mActivityRecord.isAnimating(TRANSITION)) && isVisible();
     }
 
@@ -1591,7 +1591,7 @@
         final ActivityRecord atoken = mActivityRecord;
         return (mHasSurface || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
                 && isVisibleByPolicy() && !isParentWindowHidden()
-                && (atoken == null || !atoken.hiddenRequested)
+                && (atoken == null || atoken.mVisibleRequested)
                 && !mAnimatingExit && !mDestroying;
     }
 
@@ -1606,7 +1606,7 @@
         }
         final ActivityRecord atoken = mActivityRecord;
         if (atoken != null) {
-            return ((!isParentWindowHidden() && !atoken.hiddenRequested)
+            return ((!isParentWindowHidden() && atoken.mVisibleRequested)
                     || isAnimating(TRANSITION | PARENTS));
         }
         return !isParentWindowHidden() || isAnimating(TRANSITION | PARENTS);
@@ -1673,7 +1673,7 @@
     public boolean isDisplayedLw() {
         final ActivityRecord atoken = mActivityRecord;
         return isDrawnLw() && isVisibleByPolicy()
-                && ((!isParentWindowHidden() && (atoken == null || !atoken.hiddenRequested))
+                && ((!isParentWindowHidden() && (atoken == null || atoken.mVisibleRequested))
                         || isAnimating(TRANSITION | PARENTS));
     }
 
@@ -1691,7 +1691,7 @@
         return mViewVisibility == View.GONE
                 || !mRelayoutCalled
                 || (atoken == null && mToken.isHidden())
-                || (atoken != null && atoken.hiddenRequested)
+                || (atoken != null && !atoken.mVisibleRequested)
                 || isParentWindowGoneForLayout()
                 || (mAnimatingExit && !isAnimatingLw())
                 || mDestroying;
@@ -2183,7 +2183,8 @@
                         + " parentHidden=" + isParentWindowHidden()
                         + " exiting=" + mAnimatingExit + " destroying=" + mDestroying);
                 if (mActivityRecord != null) {
-                    Slog.i(TAG_WM, "  mActivityRecord.hiddenRequested=" + mActivityRecord.hiddenRequested);
+                    Slog.i(TAG_WM, "  mActivityRecord.visibleRequested="
+                            + mActivityRecord.mVisibleRequested);
                 }
             }
         }
@@ -2631,14 +2632,14 @@
         return showBecauseOfActivity || showBecauseOfWindow;
     }
 
-    /** @return false if this window desires touch events. */
+    /** @return {@code false} if this window desires touch events. */
     boolean cantReceiveTouchInput() {
         if (mActivityRecord == null || mActivityRecord.getTask() == null) {
             return false;
         }
 
         return mActivityRecord.getTask().getTaskStack().shouldIgnoreInput()
-                || mActivityRecord.hiddenRequested
+                || !mActivityRecord.mVisibleRequested
                 || isAnimatingToRecents();
     }
 
@@ -3376,7 +3377,7 @@
     }
 
     @Override
-    public void showInsets(@InsetType int types, boolean fromIme) {
+    public void showInsets(@InsetsType int types, boolean fromIme) {
         try {
             mClient.showInsets(types, fromIme);
         } catch (RemoteException e) {
@@ -3385,7 +3386,7 @@
     }
 
     @Override
-    public void hideInsets(@InsetType int types, boolean fromIme) {
+    public void hideInsets(@InsetsType int types, boolean fromIme) {
         try {
             mClient.hideInsets(types, fromIme);
         } catch (RemoteException e) {
@@ -4167,8 +4168,8 @@
                     + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING)
                     + " during animation: policyVis=" + isVisibleByPolicy()
                     + " parentHidden=" + isParentWindowHidden()
-                    + " tok.hiddenRequested="
-                    + (mActivityRecord != null && mActivityRecord.hiddenRequested)
+                    + " tok.visibleRequested="
+                    + (mActivityRecord != null && mActivityRecord.mVisibleRequested)
                     + " tok.hidden=" + (mActivityRecord != null && mActivityRecord.isHidden())
                     + " animating=" + isAnimating(TRANSITION | PARENTS)
                     + " tok animating="
@@ -4576,7 +4577,7 @@
                         + " pv=" + isVisibleByPolicy()
                         + " mDrawState=" + mWinAnimator.mDrawState
                         + " ph=" + isParentWindowHidden()
-                        + " th=" + (mActivityRecord != null ? mActivityRecord.hiddenRequested : false)
+                        + " th=" + (mActivityRecord != null && mActivityRecord.mVisibleRequested)
                         + " a=" + isAnimating(TRANSITION | PARENTS));
             }
         }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 4d0cfbc..21de668 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -57,6 +57,7 @@
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.Assert.fail;
 
+import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.anyString;
@@ -658,6 +659,43 @@
     }
 
     @Test
+    public void testDefaultAssistant_overrideDefault() {
+        final int userId = 0;
+        final String testComponent = "package/class";
+        final List<UserInfo> userInfos = new ArrayList<>();
+        userInfos.add(new UserInfo(0, "", 0));
+        final ArraySet<ComponentName> validAssistants = new ArraySet<>();
+        validAssistants.add(ComponentName.unflattenFromString(testComponent));
+        final String originalComponent = DeviceConfig.getProperty(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE
+        );
+        DeviceConfig.setProperty(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE,
+                testComponent,
+                false
+        );
+        when(mActivityManager.isLowRamDevice()).thenReturn(false);
+        when(mAssistants.queryPackageForServices(isNull(), anyInt(), anyInt()))
+                .thenReturn(validAssistants);
+        when(mAssistants.getDefaultComponents()).thenReturn(new ArraySet<>());
+        when(mUm.getEnabledProfiles(anyInt())).thenReturn(userInfos);
+
+        mService.setDefaultAssistantForUser(userId);
+
+        verify(mAssistants).setPackageOrComponentEnabled(
+                eq(testComponent), eq(userId), eq(true), eq(true));
+
+        DeviceConfig.setProperty(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE,
+                originalComponent,
+                false
+        );
+    }
+
+    @Test
     public void testCreateNotificationChannels_SingleChannel() throws Exception {
         final NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index 3c619f7..734761f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -160,7 +160,7 @@
     public void testOnActivityLaunchCancelled_hasDrawn() {
         onActivityLaunched();
 
-        mTopActivity.visible = mTopActivity.mDrawn = true;
+        mTopActivity.mVisibleRequested = mTopActivity.mDrawn = true;
 
         // Cannot time already-visible activities.
         mActivityMetricsLogger.notifyActivityLaunched(START_TASK_TO_FRONT, mTopActivity);
@@ -171,7 +171,7 @@
 
     @Test
     public void testOnActivityLaunchCancelled_finishedBeforeDrawn() {
-        mTopActivity.visible = mTopActivity.mDrawn = true;
+        mTopActivity.mVisibleRequested = mTopActivity.mDrawn = true;
 
         // Suppress resume when creating the record because we want to notify logger manually.
         mSupervisor.beginDeferResume();
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 6c63d41..a2e4233 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -591,7 +591,7 @@
         // Prepare the activity record to be ready for immediate removal. It should be invisible and
         // have no process. Otherwise, request to finish it will send a message to client first.
         mActivity.setState(STOPPED, "test");
-        mActivity.visible = false;
+        mActivity.mVisibleRequested = false;
         mActivity.nowVisible = false;
         // Set process to 'null' to allow immediate removal, but don't call mActivity.setProcess() -
         // this will cause NPE when updating task's process.
@@ -600,7 +600,7 @@
         // Put a visible activity on top, so the finishing activity doesn't have to wait until the
         // next activity reports idle to destroy it.
         final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
-        topActivity.visible = true;
+        topActivity.mVisibleRequested = true;
         topActivity.nowVisible = true;
         topActivity.setState(RESUMED, "test");
 
@@ -686,7 +686,7 @@
     @Test
     public void testFinishActivityIfPossible_visibleResumedPreparesAppTransition() {
         mActivity.finishing = false;
-        mActivity.visible = true;
+        mActivity.mVisibleRequested = true;
         mActivity.setState(RESUMED, "test");
         mActivity.finishIfPossible("test", false /* oomAdj */);
 
@@ -702,7 +702,7 @@
     @Test
     public void testFinishActivityIfPossible_visibleNotResumedExecutesAppTransition() {
         mActivity.finishing = false;
-        mActivity.visible = true;
+        mActivity.mVisibleRequested = true;
         mActivity.setState(PAUSED, "test");
         mActivity.finishIfPossible("test", false /* oomAdj */);
 
@@ -720,7 +720,7 @@
         // Put an activity on top of test activity to make it invisible and prevent us from
         // accidentally resuming the topmost one again.
         new ActivityBuilder(mService).build();
-        mActivity.visible = false;
+        mActivity.mVisibleRequested = false;
         mActivity.setState(STOPPED, "test");
 
         mActivity.finishIfPossible("test", false /* oomAdj */);
@@ -772,7 +772,7 @@
     @Test
     public void testCompleteFinishing_keepStateOfNextInvisible() {
         final ActivityRecord currentTop = mActivity;
-        currentTop.visible = currentTop.nowVisible = true;
+        currentTop.mVisibleRequested = currentTop.nowVisible = true;
 
         // Simulates that {@code currentTop} starts an existing activity from background (so its
         // state is stopped) and the starting flow just goes to place it at top.
@@ -798,13 +798,13 @@
     @Test
     public void testCompleteFinishing_waitForNextVisible() {
         final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
-        topActivity.visible = true;
+        topActivity.mVisibleRequested = true;
         topActivity.nowVisible = true;
         topActivity.finishing = true;
         topActivity.setState(PAUSED, "true");
         // Mark the bottom activity as not visible, so that we will wait for it before removing
         // the top one.
-        mActivity.visible = false;
+        mActivity.mVisibleRequested = false;
         mActivity.nowVisible = false;
         mActivity.setState(STOPPED, "test");
 
@@ -823,13 +823,13 @@
     @Test
     public void testCompleteFinishing_noWaitForNextVisible_alreadyInvisible() {
         final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
-        topActivity.visible = false;
+        topActivity.mVisibleRequested = false;
         topActivity.nowVisible = false;
         topActivity.finishing = true;
         topActivity.setState(PAUSED, "true");
         // Mark the bottom activity as not visible, so that we would wait for it before removing
         // the top one.
-        mActivity.visible = false;
+        mActivity.mVisibleRequested = false;
         mActivity.nowVisible = false;
         mActivity.setState(STOPPED, "test");
 
@@ -845,12 +845,12 @@
     @Test
     public void testCompleteFinishing_waitForIdle() {
         final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
-        topActivity.visible = true;
+        topActivity.mVisibleRequested = true;
         topActivity.nowVisible = true;
         topActivity.finishing = true;
         topActivity.setState(PAUSED, "true");
         // Mark the bottom activity as already visible, so that there is no need to wait for it.
-        mActivity.visible = true;
+        mActivity.mVisibleRequested = true;
         mActivity.nowVisible = true;
         mActivity.setState(RESUMED, "test");
 
@@ -866,12 +866,12 @@
     @Test
     public void testCompleteFinishing_noWaitForNextVisible_stopped() {
         final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
-        topActivity.visible = false;
+        topActivity.mVisibleRequested = false;
         topActivity.nowVisible = false;
         topActivity.finishing = true;
         topActivity.setState(STOPPED, "true");
         // Mark the bottom activity as already visible, so that there is no need to wait for it.
-        mActivity.visible = true;
+        mActivity.mVisibleRequested = true;
         mActivity.nowVisible = true;
         mActivity.setState(RESUMED, "test");
 
@@ -887,12 +887,12 @@
     @Test
     public void testCompleteFinishing_noWaitForNextVisible_nonFocusedStack() {
         final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
-        topActivity.visible = true;
+        topActivity.mVisibleRequested = true;
         topActivity.nowVisible = true;
         topActivity.finishing = true;
         topActivity.setState(PAUSED, "true");
         // Mark the bottom activity as already visible, so that there is no need to wait for it.
-        mActivity.visible = true;
+        mActivity.mVisibleRequested = true;
         mActivity.nowVisible = true;
         mActivity.setState(RESUMED, "test");
 
@@ -901,7 +901,7 @@
         final ActivityStack stack = new StackBuilder(mRootActivityContainer).build();
         final ActivityRecord focusedActivity = stack.getChildAt(0).getChildAt(0);
         focusedActivity.nowVisible = true;
-        focusedActivity.visible = true;
+        focusedActivity.mVisibleRequested = true;
         focusedActivity.setState(RESUMED, "test");
         stack.mResumedActivity = focusedActivity;
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index aa9dd9d..3a6ed54 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -1006,7 +1006,7 @@
 
         // There is still an activity1 in stack1 so the activity2 should be added to finishing list
         // that will be destroyed until idle.
-        stack2.getTopNonFinishingActivity().visible = true;
+        stack2.getTopNonFinishingActivity().mVisibleRequested = true;
         final ActivityRecord activity2 = finishTopActivity(stack2);
         assertEquals(STOPPING, activity2.getState());
         assertThat(mSupervisor.mStoppingActivities).contains(activity2);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 466dc9b..5070fb6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -395,7 +395,7 @@
         assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
 
         // Make sure top focused display not changed if there is a focused app.
-        window1.mActivityRecord.hiddenRequested = true;
+        window1.mActivityRecord.mVisibleRequested = false;
         window1.getDisplayContent().setFocusedApp(window1.mActivityRecord);
         updateFocusedWindow();
         assertTrue(!window1.isFocused());
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
index 55947ae..df34c7c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
@@ -19,7 +19,8 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.view.InsetsState.TYPE_TOP_BAR;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
@@ -67,7 +68,7 @@
 
     @Test
     public void testControlsForDispatch_regular() {
-        addWindow(TYPE_STATUS_BAR, "topBar");
+        addWindow(TYPE_STATUS_BAR, "statusBar");
         addWindow(TYPE_NAVIGATION_BAR, "navBar");
 
         final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch();
@@ -79,7 +80,7 @@
 
     @Test
     public void testControlsForDispatch_dockedStackVisible() {
-        addWindow(TYPE_STATUS_BAR, "topBar");
+        addWindow(TYPE_STATUS_BAR, "statusBar");
         addWindow(TYPE_NAVIGATION_BAR, "navBar");
 
         final WindowState win = createWindowOnStack(null, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
@@ -92,7 +93,7 @@
 
     @Test
     public void testControlsForDispatch_freeformStackVisible() {
-        addWindow(TYPE_STATUS_BAR, "topBar");
+        addWindow(TYPE_STATUS_BAR, "statusBar");
         addWindow(TYPE_NAVIGATION_BAR, "navBar");
 
         final WindowState win = createWindowOnStack(null, WINDOWING_MODE_FREEFORM,
@@ -105,7 +106,7 @@
 
     @Test
     public void testControlsForDispatch_dockedDividerControllerResizing() {
-        addWindow(TYPE_STATUS_BAR, "topBar");
+        addWindow(TYPE_STATUS_BAR, "statusBar");
         addWindow(TYPE_NAVIGATION_BAR, "navBar");
         mDisplayContent.getDockedDividerController().setResizing(true);
 
@@ -117,7 +118,7 @@
 
     @Test
     public void testControlsForDispatch_keyguard() {
-        addWindow(TYPE_STATUS_BAR, "topBar").mAttrs.privateFlags |= PRIVATE_FLAG_KEYGUARD;
+        addWindow(TYPE_STATUS_BAR, "statusBar").mAttrs.privateFlags |= PRIVATE_FLAG_KEYGUARD;
         addWindow(TYPE_NAVIGATION_BAR, "navBar");
 
         final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch();
@@ -130,7 +131,7 @@
     // TODO: adjust this test if we pretend to the app that it's still able to control it.
     @Test
     public void testControlsForDispatch_forceStatusBarVisibleTransparent() {
-        addWindow(TYPE_STATUS_BAR, "topBar").mAttrs.privateFlags |=
+        addWindow(TYPE_STATUS_BAR, "statusBar").mAttrs.privateFlags |=
                 PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
         addWindow(TYPE_NAVIGATION_BAR, "navBar");
 
@@ -143,7 +144,7 @@
 
     @Test
     public void testControlsForDispatch_statusBarForceShowNavigation() {
-        addWindow(TYPE_STATUS_BAR, "topBar").mAttrs.privateFlags |=
+        addWindow(TYPE_STATUS_BAR, "statusBar").mAttrs.privateFlags |=
                 PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
         addWindow(TYPE_NAVIGATION_BAR, "navBar");
 
@@ -156,7 +157,7 @@
 
     @Test
     public void testShowTransientBars_bothCanBeTransient_appGetsBothFakeControls() {
-        addWindow(TYPE_STATUS_BAR, "topBar")
+        addWindow(TYPE_STATUS_BAR, "statusBar")
                 .getControllableInsetProvider().getSource().setVisible(false);
         addWindow(TYPE_NAVIGATION_BAR, "navBar")
                 .getControllableInsetProvider().getSource().setVisible(false);
@@ -165,7 +166,7 @@
         final InsetsPolicy policy = mDisplayContent.getInsetsPolicy();
         policy.updateBarControlTarget(app);
         policy.showTransient(
-                IntArray.wrap(new int[]{TYPE_TOP_BAR, InsetsState.TYPE_NAVIGATION_BAR}));
+                IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}));
         final InsetsSourceControl[] controls =
                 mDisplayContent.getInsetsStateController().getControlsForDispatch(app);
 
@@ -182,7 +183,7 @@
         // being cleared by InsetsSourceProvider.updateVisibility.
         final WindowState app = addWindow(TYPE_APPLICATION, "app");
 
-        addWindow(TYPE_STATUS_BAR, "topBar")
+        addWindow(TYPE_STATUS_BAR, "statusBar")
                 .getControllableInsetProvider().getSource().setVisible(false);
         addWindow(TYPE_NAVIGATION_BAR, "navBar")
                 .getControllableInsetProvider().getSource().setVisible(true);
@@ -190,7 +191,7 @@
         final InsetsPolicy policy = mDisplayContent.getInsetsPolicy();
         policy.updateBarControlTarget(app);
         policy.showTransient(
-                IntArray.wrap(new int[]{TYPE_TOP_BAR, InsetsState.TYPE_NAVIGATION_BAR}));
+                IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}));
         final InsetsSourceControl[] controls =
                 mDisplayContent.getInsetsStateController().getControlsForDispatch(app);
 
@@ -199,7 +200,7 @@
         assertEquals(2, controls.length);
         for (int i = controls.length - 1; i >= 0; i--) {
             final InsetsSourceControl control = controls[i];
-            if (control.getType() == TYPE_TOP_BAR) {
+            if (control.getType() == ITYPE_STATUS_BAR) {
                 assertNull(controls[i].getLeash());
             } else {
                 assertNotNull(controls[i].getLeash());
@@ -209,7 +210,7 @@
 
     @Test
     public void testAbortTransientBars_bothCanBeAborted_appGetsBothRealControls() {
-        addWindow(TYPE_STATUS_BAR, "topBar")
+        addWindow(TYPE_STATUS_BAR, "statusBar")
                 .getControllableInsetProvider().getSource().setVisible(false);
         addWindow(TYPE_NAVIGATION_BAR, "navBar")
                 .getControllableInsetProvider().getSource().setVisible(false);
@@ -218,7 +219,7 @@
         final InsetsPolicy policy = mDisplayContent.getInsetsPolicy();
         policy.updateBarControlTarget(app);
         policy.showTransient(
-                IntArray.wrap(new int[]{TYPE_TOP_BAR, InsetsState.TYPE_NAVIGATION_BAR}));
+                IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}));
         InsetsSourceControl[] controls =
                 mDisplayContent.getInsetsStateController().getControlsForDispatch(app);
 
@@ -229,8 +230,8 @@
         }
 
         final InsetsState state = policy.getInsetsForDispatch(app);
-        state.setSourceVisible(TYPE_TOP_BAR, true);
-        state.setSourceVisible(InsetsState.TYPE_NAVIGATION_BAR, true);
+        state.setSourceVisible(ITYPE_STATUS_BAR, true);
+        state.setSourceVisible(ITYPE_NAVIGATION_BAR, true);
         policy.onInsetsModified(app, state);
 
         controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(app);
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
index 3e2e438..09ac9ce 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
@@ -16,7 +16,7 @@
 
 package com.android.server.wm;
 
-import static android.view.InsetsState.TYPE_TOP_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 
 import static org.junit.Assert.assertEquals;
@@ -42,7 +42,7 @@
 @RunWith(WindowTestRunner.class)
 public class InsetsSourceProviderTest extends WindowTestsBase {
 
-    private InsetsSource mSource = new InsetsSource(TYPE_TOP_BAR);
+    private InsetsSource mSource = new InsetsSource(ITYPE_STATUS_BAR);
     private InsetsSourceProvider mProvider;
 
     @Before
@@ -54,10 +54,10 @@
 
     @Test
     public void testPostLayout() {
-        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
-        topBar.getFrameLw().set(0, 0, 500, 100);
-        topBar.mHasSurface = true;
-        mProvider.setWindow(topBar, null);
+        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
+        statusBar.getFrameLw().set(0, 0, 500, 100);
+        statusBar.mHasSurface = true;
+        mProvider.setWindow(statusBar, null);
         mProvider.onPostLayout();
         assertEquals(new Rect(0, 0, 500, 100), mProvider.getSource().getFrame());
         assertEquals(Insets.of(0, 100, 0, 0),
@@ -67,9 +67,9 @@
 
     @Test
     public void testPostLayout_invisible() {
-        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
-        topBar.getFrameLw().set(0, 0, 500, 100);
-        mProvider.setWindow(topBar, null);
+        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
+        statusBar.getFrameLw().set(0, 0, 500, 100);
+        mProvider.setWindow(statusBar, null);
         mProvider.onPostLayout();
         assertEquals(Insets.NONE, mProvider.getSource().calculateInsets(new Rect(0, 0, 500, 500),
                         false /* ignoreVisibility */));
@@ -77,9 +77,9 @@
 
     @Test
     public void testPostLayout_frameProvider() {
-        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
-        topBar.getFrameLw().set(0, 0, 500, 100);
-        mProvider.setWindow(topBar,
+        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
+        statusBar.getFrameLw().set(0, 0, 500, 100);
+        mProvider.setWindow(statusBar,
                 (displayFrames, windowState, rect) -> {
                     rect.set(10, 10, 20, 20);
                 });
@@ -89,10 +89,10 @@
 
     @Test
     public void testUpdateControlForTarget() {
-        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
+        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
         final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
-        topBar.getFrameLw().set(0, 0, 500, 100);
-        mProvider.setWindow(topBar, null);
+        statusBar.getFrameLw().set(0, 0, 500, 100);
+        mProvider.setWindow(statusBar, null);
         mProvider.updateControlForTarget(target, false /* force */);
         assertNotNull(mProvider.getControl(target));
         mProvider.updateControlForTarget(null, false /* force */);
@@ -101,10 +101,10 @@
 
     @Test
     public void testUpdateControlForFakeTarget() {
-        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
+        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
         final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
-        topBar.getFrameLw().set(0, 0, 500, 100);
-        mProvider.setWindow(topBar, null);
+        statusBar.getFrameLw().set(0, 0, 500, 100);
+        mProvider.setWindow(statusBar, null);
         mProvider.updateControlForFakeTarget(target);
         assertNotNull(mProvider.getControl(target));
         assertNull(mProvider.getControl(target).getLeash());
@@ -114,26 +114,26 @@
 
     @Test
     public void testInsetsModified() {
-        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
+        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
         final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
-        topBar.getFrameLw().set(0, 0, 500, 100);
-        mProvider.setWindow(topBar, null);
+        statusBar.getFrameLw().set(0, 0, 500, 100);
+        mProvider.setWindow(statusBar, null);
         mProvider.updateControlForTarget(target, false /* force */);
         InsetsState state = new InsetsState();
-        state.getSource(TYPE_TOP_BAR).setVisible(false);
-        mProvider.onInsetsModified(target, state.getSource(TYPE_TOP_BAR));
+        state.getSource(ITYPE_STATUS_BAR).setVisible(false);
+        mProvider.onInsetsModified(target, state.getSource(ITYPE_STATUS_BAR));
         assertFalse(mSource.isVisible());
     }
 
     @Test
     public void testInsetsModified_noControl() {
-        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
+        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
         final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
-        topBar.getFrameLw().set(0, 0, 500, 100);
-        mProvider.setWindow(topBar, null);
+        statusBar.getFrameLw().set(0, 0, 500, 100);
+        mProvider.setWindow(statusBar, null);
         InsetsState state = new InsetsState();
-        state.getSource(TYPE_TOP_BAR).setVisible(false);
-        mProvider.onInsetsModified(target, state.getSource(TYPE_TOP_BAR));
+        state.getSource(ITYPE_STATUS_BAR).setVisible(false);
+        mProvider.onInsetsModified(target, state.getSource(ITYPE_STATUS_BAR));
         assertTrue(mSource.isVisible());
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index 011161b..d13baec 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -16,9 +16,9 @@
 
 package com.android.server.wm;
 
-import static android.view.InsetsState.TYPE_IME;
-import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.TYPE_TOP_BAR;
+import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 
@@ -63,44 +63,44 @@
     @Test
     @FlakyTest(bugId = 131005232)
     public void testStripForDispatch_notOwn() {
-        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
+        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
-        getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
-        topBar.setControllableInsetProvider(getController().getSourceProvider(TYPE_TOP_BAR));
-        assertNotNull(getController().getInsetsForDispatch(app).getSource(TYPE_TOP_BAR));
+        getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null);
+        statusBar.setControllableInsetProvider(getController().getSourceProvider(ITYPE_STATUS_BAR));
+        assertNotNull(getController().getInsetsForDispatch(app).getSource(ITYPE_STATUS_BAR));
     }
 
     @Test
     public void testStripForDispatch_own() {
-        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
-        mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR)
-                .setWindow(topBar, null);
-        topBar.setControllableInsetProvider(getController().getSourceProvider(TYPE_TOP_BAR));
-        final InsetsState state = getController().getInsetsForDispatch(topBar);
+        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
+        mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_STATUS_BAR)
+                .setWindow(statusBar, null);
+        statusBar.setControllableInsetProvider(getController().getSourceProvider(ITYPE_STATUS_BAR));
+        final InsetsState state = getController().getInsetsForDispatch(statusBar);
         for (int i = state.getSourcesCount() - 1; i >= 0; i--) {
             final InsetsSource source = state.sourceAt(i);
-            assertNotEquals(TYPE_TOP_BAR, source.getType());
+            assertNotEquals(ITYPE_STATUS_BAR, source.getType());
         }
     }
 
     @Test
     public void testStripForDispatch_navBar() {
         final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
-        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
+        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
         final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime");
-        getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
-        getController().getSourceProvider(TYPE_NAVIGATION_BAR).setWindow(navBar, null);
-        getController().getSourceProvider(TYPE_IME).setWindow(ime, null);
+        getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null);
+        getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindow(navBar, null);
+        getController().getSourceProvider(ITYPE_IME).setWindow(ime, null);
         assertEquals(0, getController().getInsetsForDispatch(navBar).getSourcesCount());
     }
 
     @Test
     public void testBarControllingWinChanged() {
         final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
-        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
+        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
-        getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
-        getController().getSourceProvider(TYPE_NAVIGATION_BAR).setWindow(navBar, null);
+        getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null);
+        getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindow(navBar, null);
         getController().onBarControlTargetChanged(app, null, app, null);
         InsetsSourceControl[] controls = getController().getControlsForDispatch(app);
         assertEquals(2, controls.length);
@@ -108,9 +108,9 @@
 
     @Test
     public void testControlRevoked() {
-        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
+        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
-        getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
+        getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null);
         getController().onBarControlTargetChanged(app, null, null, null);
         assertNotNull(getController().getControlsForDispatch(app));
         getController().onBarControlTargetChanged(null, null, null, null);
@@ -120,12 +120,12 @@
     @FlakyTest(bugId = 124088319)
     @Test
     public void testControlRevoked_animation() {
-        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "topBar");
+        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
-        getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
+        getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null);
         getController().onBarControlTargetChanged(app, null, null, null);
         assertNotNull(getController().getControlsForDispatch(app));
-        topBar.cancelAnimation();
+        statusBar.cancelAnimation();
         assertNull(getController().getControlsForDispatch(app));
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index b2cb8c9..d48b9d7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -106,12 +106,12 @@
         RecentsAnimationCallbacks recentsAnimation = startRecentsActivity(
                 mRecentsComponent, true /* getRecentsAnimation */);
         // The launch-behind state should make the recents activity visible.
-        assertTrue(recentActivity.visible);
+        assertTrue(recentActivity.mVisibleRequested);
 
         // Simulate the animation is cancelled without changing the stack order.
         recentsAnimation.onAnimationFinished(REORDER_KEEP_IN_PLACE, false /* sendUserLeaveHint */);
         // The non-top recents activity should be invisible by the restored launch-behind state.
-        assertFalse(recentActivity.visible);
+        assertFalse(recentActivity.mVisibleRequested);
     }
 
     @Test
@@ -158,7 +158,7 @@
         // The activity is started in background so it should be invisible and will be stopped.
         assertThat(recentsActivity).isNotNull();
         assertThat(mSupervisor.mStoppingActivities).contains(recentsActivity);
-        assertFalse(recentsActivity.visible);
+        assertFalse(recentsActivity.mVisibleRequested);
 
         // Assume it is stopped to test next use case.
         recentsActivity.activityStoppedLocked(null /* newIcicle */, null /* newPersistentState */,
@@ -361,7 +361,7 @@
                 true);
 
         // Ensure we find the task for the right user and it is made visible
-        assertTrue(otherUserHomeActivity.visible);
+        assertTrue(otherUserHomeActivity.mVisibleRequested);
     }
 
     private void startRecentsActivity() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index afe18c3..894890a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -83,10 +83,11 @@
 
     @Test
     public void testIsAnyNonToastWindowVisibleForUid_aFewNonToastButNoneVisible() {
-        final WindowState topBar = createWindow(null, TYPE_STATUS_BAR, "topBar", FAKE_CALLING_UID);
+        final WindowState statusBar =
+                createWindow(null, TYPE_STATUS_BAR, "statusBar", FAKE_CALLING_UID);
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app", FAKE_CALLING_UID);
 
-        assertFalse(topBar.isVisibleNow());
+        assertFalse(statusBar.isVisibleNow());
         assertFalse(app.isVisibleNow());
         assertFalse(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID));
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index ecd9a83..b9e1d4b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -84,7 +84,7 @@
     public void testRestartProcessIfVisible() {
         setUpApp(new TestActivityDisplay.Builder(mService, 1000, 2500).build());
         doNothing().when(mSupervisor).scheduleRestartTimeout(mActivity);
-        mActivity.visible = true;
+        mActivity.mVisibleRequested = true;
         mActivity.setSavedState(null /* savedState */);
         mActivity.setState(ActivityStack.ActivityState.RESUMED, "testRestart");
         prepareUnresizable(1.5f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
@@ -167,7 +167,7 @@
                 .setResizeMode(RESIZE_MODE_UNRESIZEABLE)
                 .setMaxAspectRatio(1.5f)
                 .build();
-        mActivity.visible = true;
+        mActivity.mVisibleRequested = true;
 
         final Rect originalBounds = new Rect(mActivity.getBounds());
         final int originalDpi = mActivity.getConfiguration().densityDpi;
@@ -320,7 +320,7 @@
 
         prepareUnresizable(1.5f, SCREEN_ORIENTATION_UNSPECIFIED);
         mActivity.setState(STOPPED, "testSizeCompatMode");
-        mActivity.visible = false;
+        mActivity.mVisibleRequested = false;
         mActivity.app.setReportedProcState(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY);
         // Make the parent bounds to be different so the activity is in size compatibility mode.
         mTask.getWindowConfiguration().setAppBounds(new Rect(0, 0, 600, 1200));
@@ -383,7 +383,7 @@
         compatTokens.clear();
         // Make the activity resizable again by restarting it
         activity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
-        activity.visible = true;
+        activity.mVisibleRequested = true;
         activity.restartProcessIfVisible();
         // The full lifecycle isn't hooked up so manually set state to resumed
         activity.setState(ActivityStack.ActivityState.RESUMED, "testHandleActivitySizeCompatMode");
@@ -400,7 +400,7 @@
      */
     private void prepareUnresizable(float maxAspect, int screenOrientation) {
         mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
-        mActivity.visible = true;
+        mActivity.mVisibleRequested = true;
         if (maxAspect >= 0) {
             mActivity.info.maxAspectRatio = maxAspect;
         }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 9e0d3a7..8af47bc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -20,7 +20,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.hardware.camera2.params.OutputConfiguration.ROTATION_90;
-import static android.view.InsetsState.TYPE_TOP_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.Surface.ROTATION_0;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
@@ -403,18 +403,18 @@
 
     @Test
     public void testVisibleWithInsetsProvider() {
-        final WindowState topBar = createWindow(null, TYPE_STATUS_BAR, "topBar");
+        final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, "statusBar");
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
-        topBar.mHasSurface = true;
-        assertTrue(topBar.isVisible());
-        mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR)
-                .setWindow(topBar, null /* frameProvider */);
+        statusBar.mHasSurface = true;
+        assertTrue(statusBar.isVisible());
+        mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_STATUS_BAR)
+                .setWindow(statusBar, null /* frameProvider */);
         mDisplayContent.getInsetsStateController().onBarControlTargetChanged(
                 app, null /* fakeTopControlling */, app, null /* fakeNavControlling */);
-        mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR)
-                .onInsetsModified(app, new InsetsSource(TYPE_TOP_BAR));
+        mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_STATUS_BAR)
+                .onInsetsModified(app, new InsetsSource(ITYPE_STATUS_BAR));
         waitUntilHandlersIdle();
-        assertFalse(topBar.isVisible());
+        assertFalse(statusBar.isVisible());
     }
 
     @Test
@@ -569,7 +569,7 @@
     @Test
     public void testCantReceiveTouchWhenAppTokenHiddenRequested() {
         final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0");
-        win0.mActivityRecord.hiddenRequested = true;
+        win0.mActivityRecord.mVisibleRequested = false;
         assertTrue(win0.cantReceiveTouchInput());
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
index 797a6bc..34a2369 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
@@ -75,7 +75,7 @@
         activity.onDisplayChanged(dc);
         activity.setOccludesParent(true);
         activity.setHidden(false);
-        activity.hiddenRequested = false;
+        activity.mVisibleRequested = true;
     }
 
     static TestWindowToken createTestWindowToken(int type, DisplayContent dc) {
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 3d63e4a..43d9c11 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -58,6 +58,7 @@
 import android.telephony.ims.ImsMmTelManager;
 import android.util.DisplayMetrics;
 import android.util.Log;
+import android.util.Pair;
 
 import com.android.internal.telephony.ISetOpportunisticDataCallback;
 import com.android.internal.telephony.ISub;
@@ -73,6 +74,7 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
@@ -908,6 +910,11 @@
     private final Context mContext;
     private volatile INetworkPolicyManager mNetworkPolicy;
 
+    // Cache of Resource that has been created in getResourcesForSubId. Key is a Pair containing
+    // the Context and subId.
+    private static final Map<Pair<Context, Integer>, Resources> sResourcesCache =
+            new ConcurrentHashMap<>();
+
     /**
      * A listener class for monitoring changes to {@link SubscriptionInfo} records.
      * <p>
@@ -2329,8 +2336,20 @@
      * @return Resources associated with Subscription.
      * @hide
      */
+    @NonNull
     public static Resources getResourcesForSubId(Context context, int subId,
             boolean useRootLocale) {
+        // Check if resources for this context and subId already exist in the resource cache.
+        // Resources that use the root locale are not cached.
+        Pair<Context, Integer> cacheKey = null;
+        if (isValidSubscriptionId(subId) && !useRootLocale) {
+            cacheKey = Pair.create(context, subId);
+            if (sResourcesCache.containsKey(cacheKey)) {
+                // Cache hit. Use cached Resources.
+                return sResourcesCache.get(cacheKey);
+            }
+        }
+
         final SubscriptionInfo subInfo =
                 SubscriptionManager.from(context).getActiveSubscriptionInfo(subId);
 
@@ -2350,7 +2369,13 @@
         DisplayMetrics metrics = context.getResources().getDisplayMetrics();
         DisplayMetrics newMetrics = new DisplayMetrics();
         newMetrics.setTo(metrics);
-        return new Resources(context.getResources().getAssets(), newMetrics, newConfig);
+        Resources res = new Resources(context.getResources().getAssets(), newMetrics, newConfig);
+
+        if (cacheKey != null) {
+            // Save the newly created Resources in the resource cache.
+            sResourcesCache.put(cacheKey, res);
+        }
+        return res;
     }
 
     /**