Merge "Block face auth when lock icon is pressed" into qt-dev
diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java
index 59ae334..8e40449 100644
--- a/core/java/android/app/usage/NetworkStatsManager.java
+++ b/core/java/android/app/usage/NetworkStatsManager.java
@@ -278,6 +278,12 @@
             return null;
         }
 
+        return querySummary(template, startTime, endTime);
+    }
+
+    /** @hide */
+    public NetworkStats querySummary(NetworkTemplate template, long startTime,
+            long endTime) throws SecurityException, RemoteException {
         NetworkStats result;
         result = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
         result.startSummaryEnumeration();
@@ -296,6 +302,13 @@
             NetworkStats.Bucket.TAG_NONE, NetworkStats.Bucket.STATE_ALL);
     }
 
+    /** @hide */
+    public NetworkStats queryDetailsForUid(NetworkTemplate template,
+            long startTime, long endTime, int uid) throws SecurityException {
+        return queryDetailsForUidTagState(template, startTime, endTime, uid,
+                NetworkStats.Bucket.TAG_NONE, NetworkStats.Bucket.STATE_ALL);
+    }
+
     /**
      * Query network usage statistics details for a given uid and tag.
      *
@@ -340,6 +353,13 @@
         NetworkTemplate template;
         template = createTemplate(networkType, subscriberId);
 
+        return queryDetailsForUidTagState(template, startTime, endTime, uid, tag, state);
+    }
+
+    /** @hide */
+    public NetworkStats queryDetailsForUidTagState(NetworkTemplate template,
+            long startTime, long endTime, int uid, int tag, int state) throws SecurityException {
+
         NetworkStats result;
         try {
             result = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index ee62af5..69c1295 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -248,6 +248,8 @@
     public static final int FLAG_STORAGE_DE = IInstalld.FLAG_STORAGE_DE;
     /** {@hide} */
     public static final int FLAG_STORAGE_CE = IInstalld.FLAG_STORAGE_CE;
+    /** {@hide} */
+    public static final int FLAG_STORAGE_EXTERNAL = IInstalld.FLAG_STORAGE_EXTERNAL;
 
     /** {@hide} */
     public static final int FLAG_FOR_WRITE = 1 << 8;
diff --git a/core/java/android/os/storage/VolumeRecord.java b/core/java/android/os/storage/VolumeRecord.java
index b6ee261..1a794eb 100644
--- a/core/java/android/os/storage/VolumeRecord.java
+++ b/core/java/android/os/storage/VolumeRecord.java
@@ -25,6 +25,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 
+import java.util.Locale;
 import java.util.Objects;
 
 /**
@@ -45,6 +46,7 @@
     public String nickname;
     public int userFlags;
     public long createdMillis;
+    public long lastSeenMillis;
     public long lastTrimMillis;
     public long lastBenchMillis;
 
@@ -61,6 +63,7 @@
         nickname = parcel.readString();
         userFlags = parcel.readInt();
         createdMillis = parcel.readLong();
+        lastSeenMillis = parcel.readLong();
         lastTrimMillis = parcel.readLong();
         lastBenchMillis = parcel.readLong();
     }
@@ -73,6 +76,10 @@
         return fsUuid;
     }
 
+    public String getNormalizedFsUuid() {
+        return fsUuid != null ? fsUuid.toLowerCase(Locale.US) : null;
+    }
+
     public String getNickname() {
         return nickname;
     }
@@ -97,6 +104,7 @@
                 DebugUtils.flagsToString(VolumeRecord.class, "USER_FLAG_", userFlags));
         pw.println();
         pw.printPair("createdMillis", TimeUtils.formatForLogging(createdMillis));
+        pw.printPair("lastSeenMillis", TimeUtils.formatForLogging(lastSeenMillis));
         pw.printPair("lastTrimMillis", TimeUtils.formatForLogging(lastTrimMillis));
         pw.printPair("lastBenchMillis", TimeUtils.formatForLogging(lastBenchMillis));
         pw.decreaseIndent();
@@ -155,6 +163,7 @@
         parcel.writeString(nickname);
         parcel.writeInt(userFlags);
         parcel.writeLong(createdMillis);
+        parcel.writeLong(lastSeenMillis);
         parcel.writeLong(lastTrimMillis);
         parcel.writeLong(lastBenchMillis);
     }
diff --git a/core/java/android/service/appprediction/AppPredictionService.java b/core/java/android/service/appprediction/AppPredictionService.java
index 1391d43..be20570 100644
--- a/core/java/android/service/appprediction/AppPredictionService.java
+++ b/core/java/android/service/appprediction/AppPredictionService.java
@@ -39,6 +39,7 @@
 import android.os.RemoteException;
 import android.service.appprediction.IPredictionService.Stub;
 import android.util.ArrayMap;
+import android.util.Log;
 import android.util.Slog;
 
 import java.util.ArrayList;
@@ -46,7 +47,7 @@
 import java.util.function.Consumer;
 
 /**
- * TODO(b/111701043): Add java docs
+ * A service used to predict app and shortcut usage.
  *
  * @hide
  */
@@ -58,7 +59,9 @@
 
     /**
      * The {@link Intent} that must be declared as handled by the service.
-     * TODO(b/111701043): Add any docs about permissions the service must hold
+     *
+     * <p>The service must also require the {@link android.permission#MANAGE_APP_PREDICTIONS}
+     * permission.
      *
      * @hide
      */
@@ -145,8 +148,11 @@
     @Override
     @NonNull
     public final IBinder onBind(@NonNull Intent intent) {
-        // TODO(b/111701043): Verify that the action is valid
-        return mInterface.asBinder();
+        if (SERVICE_INTERFACE.equals(intent.getAction())) {
+            return mInterface.asBinder();
+        }
+        Log.w(TAG, "Tried to bind to wrong intent (should be " + SERVICE_INTERFACE + ": " + intent);
+        return null;
     }
 
     /**
@@ -180,7 +186,6 @@
 
     /**
      * Called by the client app to request sorting of targets based on prediction rank.
-     * TODO(b/111701043): Implement CancellationSignal so caller can cancel a long running request
      */
     @MainThread
     public abstract void onSortAppTargets(@NonNull AppPredictionSessionId sessionId,
@@ -254,7 +259,6 @@
     /**
      * Called by the client app to request target predictions. This method is only called if there
      * are one or more prediction callbacks registered.
-     * TODO(b/111701043): Add java docs
      *
      * @see #updatePredictions(AppPredictionSessionId, List)
      */
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index d67c884..63e1485 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -2660,6 +2660,9 @@
          */
         @NonNull
         public Transaction merge(@NonNull Transaction other) {
+            if (this == other) {
+                return this;
+            }
             mResizedSurfaces.putAll(other.mResizedSurfaces);
             other.mResizedSurfaces.clear();
             nativeMergeTransaction(mNativeObject, other.mNativeObject);
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 0cf9500..7de6ca5 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1533,7 +1533,7 @@
     <!-- Message shown during face acquisition when only the left part of the user's face was detected [CHAR LIMIT=50] -->
     <string name="face_acquired_too_left">Move phone to the right.</string>
     <!-- Message shown during face acquisition when the user is not front facing the sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_poor_gaze">Look at the screen with your eyes open.</string>
+    <string name="face_acquired_poor_gaze">Please look more directly at your device.</string>
     <!-- Message shown during face acquisition when the user is not detected [CHAR LIMIT=50] -->
     <string name="face_acquired_not_detected">Can\u2019t see your face. Look at the phone.</string>
     <!-- Message shown during face acquisition when the device is not steady [CHAR LIMIT=50] -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
index 2bfcc91..f30de13 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
@@ -175,9 +175,7 @@
 
     private long getUsageLevel(NetworkTemplate template, long start, long end) {
         try {
-            final Bucket bucket = mNetworkStatsManager.querySummaryForDevice(
-                    getNetworkType(template), getActiveSubscriberId(),
-                    start, end);
+            final Bucket bucket = mNetworkStatsManager.querySummaryForDevice(template, start, end);
             if (bucket != null) {
                 return bucket.getRxBytes() + bucket.getTxBytes();
             }
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java
index ec5a0b5..787dc55 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java
@@ -37,14 +37,14 @@
 
     private NetworkCycleChartDataLoader(Builder builder) {
         super(builder);
-        mData = new ArrayList<NetworkCycleChartData>();
+        mData = new ArrayList<>();
     }
 
     @Override
     void recordUsage(long start, long end) {
         try {
             final NetworkStats.Bucket bucket = mNetworkStatsManager.querySummaryForDevice(
-                mNetworkType, mSubId, start, end);
+                    mNetworkTemplate, start, end);
             final long total = bucket == null ? 0L : bucket.getRxBytes() + bucket.getTxBytes();
             if (total > 0L) {
                 final NetworkCycleChartData.Builder builder = new NetworkCycleChartData.Builder();
@@ -81,7 +81,7 @@
             long usage = 0L;
             try {
                 final NetworkStats.Bucket bucket = mNetworkStatsManager.querySummaryForDevice(
-                    mNetworkType, mSubId, bucketStart, bucketEnd);
+                        mNetworkTemplate, bucketStart, bucketEnd);
                 if (bucket != null) {
                     usage = bucket.getRxBytes() + bucket.getTxBytes();
                 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
index bd9a636..43c05b8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
@@ -23,11 +23,11 @@
 import android.content.Context;
 import android.util.Log;
 
+import androidx.annotation.VisibleForTesting;
+
 import java.util.ArrayList;
 import java.util.List;
 
-import androidx.annotation.VisibleForTesting;
-
 /**
  * Loader for network data usage history. It returns a list of usage data per billing cycle for the
  * specific Uid(s).
@@ -44,7 +44,7 @@
         super(builder);
         mUids = builder.mUids;
         mRetrieveDetail = builder.mRetrieveDetail;
-        mData = new ArrayList<NetworkCycleDataForUid>();
+        mData = new ArrayList<>();
     }
 
     @Override
@@ -54,7 +54,7 @@
             long totalForeground = 0L;
             for (int uid : mUids) {
                 final NetworkStats stats = mNetworkStatsManager.queryDetailsForUid(
-                    mNetworkType, mSubId, start, end, uid);
+                        mNetworkTemplate, start, end, uid);
                 final long usage = getTotalUsage(stats);
                 if (usage > 0L) {
                     totalUsage += usage;
@@ -100,7 +100,7 @@
 
     private long getForegroundUsage(long start, long end, int uid) {
         final NetworkStats stats = mNetworkStatsManager.queryDetailsForUidTagState(
-            mNetworkType, mSubId, start, end, uid, TAG_NONE, STATE_FOREGROUND);
+                mNetworkTemplate, start, end, uid, TAG_NONE, STATE_FOREGROUND);
         return getTotalUsage(stats);
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java
index dd6d563..3e95b01 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java
@@ -49,18 +49,14 @@
 public abstract class NetworkCycleDataLoader<D> extends AsyncTaskLoader<D> {
     private static final String TAG = "NetworkCycleDataLoader";
     protected final NetworkStatsManager mNetworkStatsManager;
-    protected final String mSubId;
-    protected final int mNetworkType;
+    protected final NetworkTemplate mNetworkTemplate;
     private final NetworkPolicy mPolicy;
-    private final NetworkTemplate mNetworkTemplate;
     private final ArrayList<Long> mCycles;
     @VisibleForTesting
     final INetworkStatsService mNetworkStatsService;
 
     protected NetworkCycleDataLoader(Builder<?> builder) {
         super(builder.mContext);
-        mSubId = builder.mSubId;
-        mNetworkType = builder.mNetworkType;
         mNetworkTemplate = builder.mNetworkTemplate;
         mCycles = builder.mCycles;
         mNetworkStatsManager = (NetworkStatsManager)
@@ -180,8 +176,6 @@
 
     public static abstract class Builder<T extends NetworkCycleDataLoader> {
         private final Context mContext;
-        private String mSubId;
-        private int mNetworkType;
         private NetworkTemplate mNetworkTemplate;
         private ArrayList<Long> mCycles;
 
@@ -189,14 +183,8 @@
             mContext = context;
         }
 
-        public Builder<T> setSubscriberId(String subId) {
-            mSubId = subId;
-            return this;
-        }
-
         public Builder<T> setNetworkTemplate(NetworkTemplate template) {
             mNetworkTemplate = template;
-            mNetworkType = DataUsageController.getNetworkType(template);
             return this;
         }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsSummaryLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsSummaryLoader.java
index 34e6097..ed093629 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsSummaryLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsSummaryLoader.java
@@ -16,9 +16,10 @@
 
 package com.android.settingslib.net;
 
-import android.app.usage.NetworkStatsManager;
 import android.app.usage.NetworkStats;
+import android.app.usage.NetworkStatsManager;
 import android.content.Context;
+import android.net.NetworkTemplate;
 import android.os.RemoteException;
 import android.util.Log;
 
@@ -33,15 +34,13 @@
     private final NetworkStatsManager mNetworkStatsManager;
     private final long mStart;
     private final long mEnd;
-    private final String mSubId;
-    private final int mNetworkType;
+    private final NetworkTemplate mNetworkTemplate;
 
     private NetworkStatsSummaryLoader(Builder builder) {
         super(builder.mContext);
         mStart = builder.mStart;
         mEnd = builder.mEnd;
-        mSubId = builder.mSubId;
-        mNetworkType = builder.mNetworkType;
+        mNetworkTemplate = builder.mNetworkTemplate;
         mNetworkStatsManager = (NetworkStatsManager)
                 builder.mContext.getSystemService(Context.NETWORK_STATS_SERVICE);
     }
@@ -55,7 +54,7 @@
     @Override
     public NetworkStats loadInBackground() {
         try {
-            return mNetworkStatsManager.querySummary(mNetworkType, mSubId, mStart, mEnd);
+            return mNetworkStatsManager.querySummary(mNetworkTemplate, mStart, mEnd);
         } catch (RemoteException e) {
             Log.e(TAG, "Exception querying network detail.", e);
             return null;
@@ -78,8 +77,7 @@
         private final Context mContext;
         private long mStart;
         private long mEnd;
-        private String mSubId;
-        private int mNetworkType;
+        private NetworkTemplate mNetworkTemplate;
 
         public Builder(Context context) {
             mContext = context;
@@ -95,13 +93,11 @@
             return this;
         }
 
-        public Builder setSubscriberId(String subId) {
-            mSubId = subId;
-            return this;
-        }
-
-        public Builder setNetworkType(int networkType) {
-            mNetworkType = networkType;
+        /**
+         * Set {@link NetworkTemplate} for builder
+         */
+        public Builder setNetworkTemplate(NetworkTemplate template) {
+            mNetworkTemplate = template;
             return this;
         }
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
index a28bb6c..3da5e76 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
@@ -31,7 +31,6 @@
 import android.app.usage.NetworkStats;
 import android.app.usage.NetworkStatsManager;
 import android.content.Context;
-import android.net.ConnectivityManager;
 import android.net.INetworkStatsSession;
 import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
@@ -52,6 +51,7 @@
 public class DataUsageControllerTest {
 
     private static final String SUB_ID = "Test Subscriber";
+    private static final String SUB_ID_2 = "Test Subscriber 2";
 
     @Mock
     private INetworkStatsSession mSession;
@@ -63,6 +63,9 @@
     private NetworkStatsManager mNetworkStatsManager;
     @Mock
     private Context mContext;
+    private NetworkTemplate mNetworkTemplate;
+    private NetworkTemplate mNetworkTemplate2;
+    private NetworkTemplate mWifiNetworkTemplate;
 
     private DataUsageController mController;
     private NetworkStatsHistory mNetworkStatsHistory;
@@ -83,24 +86,27 @@
                 .when(mSession).getHistoryForNetwork(any(NetworkTemplate.class), anyInt());
         ShadowSubscriptionManager.setDefaultDataSubscriptionId(mDefaultSubscriptionId);
         doReturn(SUB_ID).when(mTelephonyManager).getSubscriberId();
+
+        mNetworkTemplate = NetworkTemplate.buildTemplateMobileAll(SUB_ID);
+        mNetworkTemplate2 = NetworkTemplate.buildTemplateMobileAll(SUB_ID_2);
+        mWifiNetworkTemplate = NetworkTemplate.buildTemplateWifiWildcard();
     }
 
     @Test
     public void getHistoricalUsageLevel_shouldQuerySummaryForDevice() throws Exception {
+        mController.getHistoricalUsageLevel(mWifiNetworkTemplate);
 
-        mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard());
-
-        verify(mNetworkStatsManager).querySummaryForDevice(eq(ConnectivityManager.TYPE_WIFI),
-                eq(SUB_ID), eq(0L) /* startTime */, anyLong() /* endTime */);
+        verify(mNetworkStatsManager).querySummaryForDevice(eq(mWifiNetworkTemplate),
+                eq(0L) /* startTime */, anyLong() /* endTime */);
     }
 
     @Test
     public void getHistoricalUsageLevel_noUsageData_shouldReturn0() throws Exception {
-        when(mNetworkStatsManager.querySummaryForDevice(eq(ConnectivityManager.TYPE_WIFI),
-                eq(SUB_ID), eq(0L) /* startTime */, anyLong() /* endTime */))
+        when(mNetworkStatsManager.querySummaryForDevice(eq(mWifiNetworkTemplate),
+                eq(0L) /* startTime */, anyLong() /* endTime */))
                 .thenReturn(mock(NetworkStats.Bucket.class));
-        assertThat(mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
-            .isEqualTo(0L);
+        assertThat(mController.getHistoricalUsageLevel(mWifiNetworkTemplate))
+                .isEqualTo(0L);
     }
 
     @Test
@@ -110,10 +116,10 @@
         final NetworkStats.Bucket bucket = mock(NetworkStats.Bucket.class);
         when(bucket.getRxBytes()).thenReturn(receivedBytes);
         when(bucket.getTxBytes()).thenReturn(transmittedBytes);
-        when(mNetworkStatsManager.querySummaryForDevice(eq(ConnectivityManager.TYPE_WIFI),
-                eq(SUB_ID), eq(0L) /* startTime */, anyLong() /* endTime */)).thenReturn(bucket);
+        when(mNetworkStatsManager.querySummaryForDevice(eq(mWifiNetworkTemplate),
+                eq(0L) /* startTime */, anyLong() /* endTime */)).thenReturn(bucket);
 
-        assertThat(mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
+        assertThat(mController.getHistoricalUsageLevel(mWifiNetworkTemplate))
                 .isEqualTo(receivedBytes + transmittedBytes);
     }
 
@@ -126,9 +132,8 @@
         final NetworkStats.Bucket defaultSubscriberBucket = mock(NetworkStats.Bucket.class);
         when(defaultSubscriberBucket.getRxBytes()).thenReturn(defaultSubRx);
         when(defaultSubscriberBucket.getTxBytes()).thenReturn(defaultSubTx);
-        when(mNetworkStatsManager.querySummaryForDevice(eq(ConnectivityManager.TYPE_MOBILE),
-                eq(SUB_ID), eq(0L)/* startTime */, anyLong() /* endTime */)).thenReturn(
-                defaultSubscriberBucket);
+        when(mNetworkStatsManager.querySummaryForDevice(eq(mNetworkTemplate), eq(0L)/* startTime */,
+                anyLong() /* endTime */)).thenReturn(defaultSubscriberBucket);
 
         // Now setup a stats bucket for a different, non-default subscription / subscriber ID.
         final long nonDefaultSubRx = 7654321L;
@@ -137,25 +142,21 @@
         when(nonDefaultSubscriberBucket.getRxBytes()).thenReturn(nonDefaultSubRx);
         when(nonDefaultSubscriberBucket.getTxBytes()).thenReturn(nonDefaultSubTx);
         final int explicitSubscriptionId = 55;
-        final String subscriberId2 = "Test Subscriber 2";
-        when(mNetworkStatsManager.querySummaryForDevice(eq(ConnectivityManager.TYPE_MOBILE),
-                eq(subscriberId2), eq(0L)/* startTime */, anyLong() /* endTime */)).thenReturn(
+        when(mNetworkStatsManager.querySummaryForDevice(eq(mNetworkTemplate2),
+                eq(0L)/* startTime */, anyLong() /* endTime */)).thenReturn(
                 nonDefaultSubscriberBucket);
-        doReturn(subscriberId2).when(mTelephonyManager).getSubscriberId();
+        doReturn(SUB_ID_2).when(mTelephonyManager).getSubscriberId();
 
         // Now verify that when we're asking for stats on the non-default subscription, we get
         // the data back for that subscription and *not* the default one.
         mController.setSubscriptionId(explicitSubscriptionId);
 
-        assertThat(mController.getHistoricalUsageLevel(
-                NetworkTemplate.buildTemplateMobileAll(subscriberId2))).isEqualTo(
+        assertThat(mController.getHistoricalUsageLevel(mNetworkTemplate2)).isEqualTo(
                 nonDefaultSubRx + nonDefaultSubTx);
-
-        verify(mTelephonyManager).createForSubscriptionId(explicitSubscriptionId);
     }
 
     @Test
-    public void getTelephonyManager_shouldCreateWithExplicitSubId() throws Exception {
+    public void getTelephonyManager_shouldCreateWithExplicitSubId() {
         int explicitSubId = 1;
         TelephonyManager tmForSub1 = new TelephonyManager(mContext, explicitSubId);
         when(mTelephonyManager.createForSubscriptionId(eq(explicitSubId))).thenReturn(tmForSub1);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleChartDataLoaderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleChartDataLoaderTest.java
index 011f234..c3e1613 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleChartDataLoaderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleChartDataLoaderTest.java
@@ -21,9 +21,9 @@
 
 import android.app.usage.NetworkStatsManager;
 import android.content.Context;
-import android.net.ConnectivityManager;
 import android.net.NetworkPolicy;
 import android.net.NetworkPolicyManager;
+import android.net.NetworkTemplate;
 import android.os.RemoteException;
 import android.text.format.DateUtils;
 
@@ -43,6 +43,8 @@
     private NetworkPolicyManager mNetworkPolicyManager;
     @Mock
     private Context mContext;
+    @Mock
+    private NetworkTemplate mNetworkTemplate;
 
     private NetworkCycleChartDataLoader mLoader;
 
@@ -60,13 +62,12 @@
     public void recordUsage_shouldQueryNetworkSummaryForDevice() throws RemoteException {
         final long end = System.currentTimeMillis();
         final long start = end - (DateUtils.WEEK_IN_MILLIS * 4);
-        final int networkType = ConnectivityManager.TYPE_MOBILE;
-        final String subId = "TestSubscriber";
         mLoader = NetworkCycleChartDataLoader.builder(mContext)
-            .setSubscriberId(subId).build();
+                .setNetworkTemplate(mNetworkTemplate)
+                .build();
 
         mLoader.recordUsage(start, end);
 
-        verify(mNetworkStatsManager).querySummaryForDevice(networkType, subId, start, end);
+        verify(mNetworkStatsManager).querySummaryForDevice(mNetworkTemplate, start, end);
     }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
index aafb46a..877eb61 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
@@ -28,9 +28,9 @@
 
 import android.app.usage.NetworkStatsManager;
 import android.content.Context;
-import android.net.ConnectivityManager;
 import android.net.NetworkPolicy;
 import android.net.NetworkPolicyManager;
+import android.net.NetworkTemplate;
 import android.text.format.DateUtils;
 
 import org.junit.Before;
@@ -42,6 +42,7 @@
 
 @RunWith(RobolectricTestRunner.class)
 public class NetworkCycleDataForUidLoaderTest {
+    private static final String SUB_ID = "Test Subscriber";
 
     @Mock
     private NetworkStatsManager mNetworkStatsManager;
@@ -49,6 +50,7 @@
     private NetworkPolicyManager mNetworkPolicyManager;
     @Mock
     private Context mContext;
+    private NetworkTemplate mNetworkTemplate;
 
     private NetworkCycleDataForUidLoader mLoader;
 
@@ -56,64 +58,62 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         when(mContext.getSystemService(Context.NETWORK_STATS_SERVICE))
-            .thenReturn(mNetworkStatsManager);
+                .thenReturn(mNetworkStatsManager);
         when(mContext.getSystemService(Context.NETWORK_POLICY_SERVICE))
-            .thenReturn(mNetworkPolicyManager);
+                .thenReturn(mNetworkPolicyManager);
         when(mNetworkPolicyManager.getNetworkPolicies()).thenReturn(new NetworkPolicy[0]);
+        mNetworkTemplate = NetworkTemplate.buildTemplateMobileAll(SUB_ID);
     }
 
     @Test
     public void recordUsage_shouldQueryNetworkDetailsForUidAndForegroundState() {
         final long end = System.currentTimeMillis();
         final long start = end - (DateUtils.WEEK_IN_MILLIS * 4);
-        final int networkType = ConnectivityManager.TYPE_MOBILE;
-        final String subId = "TestSubscriber";
         final int uid = 1;
         mLoader = spy(NetworkCycleDataForUidLoader.builder(mContext)
-            .addUid(uid).setSubscriberId(subId).build());
+                .addUid(uid)
+                .setNetworkTemplate(mNetworkTemplate)
+                .build());
         doReturn(1024L).when(mLoader).getTotalUsage(any());
 
         mLoader.recordUsage(start, end);
 
-        verify(mNetworkStatsManager).queryDetailsForUid(networkType, subId, start, end, uid);
+        verify(mNetworkStatsManager).queryDetailsForUid(mNetworkTemplate, start, end, uid);
         verify(mNetworkStatsManager).queryDetailsForUidTagState(
-            networkType, subId, start, end, uid, TAG_NONE, STATE_FOREGROUND);
+                mNetworkTemplate, start, end, uid, TAG_NONE, STATE_FOREGROUND);
     }
 
     @Test
     public void recordUsage_retrieveDetailIsFalse_shouldNotQueryNetworkForegroundState() {
         final long end = System.currentTimeMillis();
         final long start = end - (DateUtils.WEEK_IN_MILLIS * 4);
-        final int networkType = ConnectivityManager.TYPE_MOBILE;
-        final String subId = "TestSubscriber";
         final int uid = 1;
         mLoader = spy(NetworkCycleDataForUidLoader.builder(mContext)
-            .setRetrieveDetail(false).addUid(uid).setSubscriberId(subId).build());
+                .setRetrieveDetail(false).addUid(uid).build());
         doReturn(1024L).when(mLoader).getTotalUsage(any());
 
         mLoader.recordUsage(start, end);
         verify(mNetworkStatsManager, never()).queryDetailsForUidTagState(
-            networkType, subId, start, end, uid, TAG_NONE, STATE_FOREGROUND);
+                mNetworkTemplate, start, end, uid, TAG_NONE, STATE_FOREGROUND);
     }
 
     @Test
     public void recordUsage_multipleUids_shouldQueryNetworkDetailsForEachUid() {
         final long end = System.currentTimeMillis();
         final long start = end - (DateUtils.WEEK_IN_MILLIS * 4);
-        final int networkType = ConnectivityManager.TYPE_MOBILE;
-        final String subId = "TestSubscriber";
         mLoader = spy(NetworkCycleDataForUidLoader.builder(mContext)
-            .addUid(1)
-            .addUid(2)
-            .addUid(3)
-            .setSubscriberId(subId).build());
+                .addUid(1)
+                .addUid(2)
+                .addUid(3)
+                .setNetworkTemplate(mNetworkTemplate)
+                .build());
         doReturn(1024L).when(mLoader).getTotalUsage(any());
 
         mLoader.recordUsage(start, end);
 
-        verify(mNetworkStatsManager).queryDetailsForUid(networkType, subId, start, end, 1);
-        verify(mNetworkStatsManager).queryDetailsForUid(networkType, subId, start, end, 2);
-        verify(mNetworkStatsManager).queryDetailsForUid(networkType, subId, start, end, 3);
+        verify(mNetworkStatsManager).queryDetailsForUid(mNetworkTemplate, start, end, 1);
+        verify(mNetworkStatsManager).queryDetailsForUid(mNetworkTemplate, start, end, 2);
+        verify(mNetworkStatsManager).queryDetailsForUid(mNetworkTemplate, start, end, 3);
     }
 
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataLoaderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataLoaderTest.java
index c5f54bb..74b9151 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataLoaderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataLoaderTest.java
@@ -126,8 +126,6 @@
         when(mIterator.next()).thenReturn(cycle);
         mLoader = spy(new NetworkCycleDataTestLoader(mContext));
         ReflectionHelpers.setField(mLoader, "mPolicy", mPolicy);
-        ReflectionHelpers.setField(mLoader, "mNetworkType", networkType);
-        ReflectionHelpers.setField(mLoader, "mSubId", subId);
 
         mLoader.loadPolicyData();
 
diff --git a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/LegacyRecentsImpl.java b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/LegacyRecentsImpl.java
index b7bb751..a150de9 100644
--- a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/LegacyRecentsImpl.java
+++ b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/LegacyRecentsImpl.java
@@ -662,11 +662,17 @@
 
     public final void onBusEvent(ExpandPipEvent event) {
         PipUI pipUi = getComponent(PipUI.class);
+        if (pipUi == null) {
+            return;
+        }
         pipUi.expandPip();
     }
 
     public final void onBusEvent(HidePipMenuEvent event) {
         PipUI pipUi = getComponent(PipUI.class);
+        if (pipUi == null) {
+            return;
+        }
         event.getAnimationTrigger().increment();
         pipUi.hidePipMenu(() -> {
                 event.getAnimationTrigger().increment();
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index cdef09d..2792a01 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -31,23 +31,36 @@
         android:layout_height="wrap_content"
         android:layout_marginBottom="@dimen/keyguard_indication_margin_bottom"
         android:layout_gravity="bottom|center_horizontal"
-        android:orientation="vertical">
+        android:orientation="horizontal">
 
-        <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
-            android:id="@+id/keyguard_indication_enterprise_disclosure"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center"
-            android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
-            android:visibility="gone" />
+        <include layout="@layout/left_docked_overlay" />
 
-        <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
-            android:id="@+id/keyguard_indication_text"
-            android:layout_width="match_parent"
+        <LinearLayout
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:gravity="center"
-            android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
-            android:accessibilityLiveRegion="polite" />
+            android:layout_weight="1"
+            android:layout_gravity="center_vertical|center_horizontal"
+            android:orientation="vertical">
+
+            <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
+                android:id="@+id/keyguard_indication_enterprise_disclosure"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
+                android:visibility="gone" />
+
+            <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
+                android:id="@+id/keyguard_indication_text"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
+                android:accessibilityLiveRegion="polite" />
+
+        </LinearLayout>
+
+        <include layout="@layout/right_docked_overlay" />
 
     </LinearLayout>
 
diff --git a/packages/SystemUI/res/layout/left_docked_overlay.xml b/packages/SystemUI/res/layout/left_docked_overlay.xml
new file mode 100644
index 0000000..430143c
--- /dev/null
+++ b/packages/SystemUI/res/layout/left_docked_overlay.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+
+<!-- empty stub -->
+<merge />
diff --git a/packages/SystemUI/res/layout/right_docked_overlay.xml b/packages/SystemUI/res/layout/right_docked_overlay.xml
new file mode 100644
index 0000000..430143c
--- /dev/null
+++ b/packages/SystemUI/res/layout/right_docked_overlay.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+
+<!-- empty stub -->
+<merge />
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index f33974a..e01e6a8 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -292,6 +292,14 @@
     <string name="biometric_dialog_try_again">Try again</string>
     <!-- Content description for empty spaces that are not taken by the biometric dialog. Clicking on these areas will cancel authentication and dismiss the biometric dialog [CHAR LIMIT=NONE] -->
     <string name="biometric_dialog_empty_space_description">Empty region, tap to cancel authentication</string>
+    <!-- Content description for the face icon when the device is not authenticating anymore [CHAR LIMIT=NONE] -->
+    <string name="biometric_dialog_face_icon_description_idle">Please try again</string>
+    <!-- Content description for the face icon when the device is authenticating [CHAR LIMIT=NONE] -->
+    <string name="biometric_dialog_face_icon_description_authenticating">Looking for your face</string>
+    <!-- Content description for the face icon when the user has been authenticated [CHAR LIMIT=NONE] -->
+    <string name="biometric_dialog_face_icon_description_authenticated">Face authenticated</string>
+    <!-- Content description for the face icon when the user has been authenticated and the confirm button has been pressed [CHAR LIMIT=NONE] -->
+    <string name="biometric_dialog_face_icon_description_confirmed">Confirmed</string>
 
     <!-- Message shown when the system-provided fingerprint dialog is shown, asking for authentication -->
     <string name="fingerprint_dialog_touch_sensor">Touch the fingerprint sensor</string>
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
index 9dfcf7d..45c19ad 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
@@ -325,7 +325,6 @@
 
     private void handleTryAgainPressed() {
         try {
-            mCurrentDialog.clearTemporaryMessage();
             mReceiver.onTryAgainPressed();
         } catch (RemoteException e) {
             Log.e(TAG, "RemoteException when handling try again", e);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
index a70ebb3..5717a54 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
@@ -223,6 +223,7 @@
         });
 
         mTryAgainButton.setOnClickListener((View v) -> {
+            handleResetMessage();
             updateState(STATE_AUTHENTICATING);
             showTryAgainButton(false /* show */);
             mCallback.onTryAgainPressed();
@@ -265,6 +266,7 @@
         if (mRestoredState == null) {
             updateState(STATE_AUTHENTICATING);
             mErrorText.setText(getHintStringResourceId());
+            mErrorText.setContentDescription(mContext.getString(getHintStringResourceId()));
             mErrorText.setVisibility(View.VISIBLE);
         } else {
             updateState(mState);
@@ -415,11 +417,6 @@
                 BiometricPrompt.HIDE_DIALOG_DELAY);
     }
 
-    public void clearTemporaryMessage() {
-        mHandler.removeMessages(MSG_RESET_MESSAGE);
-        mHandler.obtainMessage(MSG_RESET_MESSAGE).sendToTarget();
-    }
-
     /**
      * Transient help message (acquire) is received, dialog stays showing. Sensor stays in
      * "authenticating" state.
@@ -478,6 +475,7 @@
         mPositiveButton.setVisibility(bundle.getInt(KEY_CONFIRM_VISIBILITY));
         mState = bundle.getInt(KEY_STATE);
         mErrorText.setText(bundle.getCharSequence(KEY_ERROR_TEXT_STRING));
+        mErrorText.setContentDescription(bundle.getCharSequence(KEY_ERROR_TEXT_STRING));
         mErrorText.setVisibility(bundle.getInt(KEY_ERROR_TEXT_VISIBILITY));
         mErrorText.setTextColor(bundle.getInt(KEY_ERROR_TEXT_COLOR));
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
index dbbb71c..8f26f18 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
@@ -288,6 +288,7 @@
     @Override
     protected void handleResetMessage() {
         mErrorText.setText(getHintStringResourceId());
+        mErrorText.setContentDescription(mContext.getString(getHintStringResourceId()));
         mErrorText.setTextColor(mTextColor);
         if (getState() == STATE_AUTHENTICATING) {
             mErrorText.setVisibility(View.VISIBLE);
@@ -406,13 +407,21 @@
             } else {
                 mIconController.showIcon(R.drawable.face_dialog_pulse_dark_to_light);
             }
+            mBiometricIcon.setContentDescription(mContext.getString(
+                    R.string.biometric_dialog_face_icon_description_authenticating));
         } else if (oldState == STATE_PENDING_CONFIRMATION && newState == STATE_AUTHENTICATED) {
             mIconController.animateOnce(R.drawable.face_dialog_dark_to_checkmark);
+            mBiometricIcon.setContentDescription(mContext.getString(
+                    R.string.biometric_dialog_face_icon_description_confirmed));
         } else if (oldState == STATE_ERROR && newState == STATE_IDLE) {
             mIconController.animateOnce(R.drawable.face_dialog_error_to_idle);
+            mBiometricIcon.setContentDescription(mContext.getString(
+                    R.string.biometric_dialog_face_icon_description_idle));
         } else if (oldState == STATE_ERROR && newState == STATE_AUTHENTICATED) {
             mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
             mIconController.animateOnce(R.drawable.face_dialog_dark_to_checkmark);
+            mBiometricIcon.setContentDescription(mContext.getString(
+                    R.string.biometric_dialog_face_icon_description_authenticated));
         } else if (newState == STATE_ERROR) {
             // It's easier to only check newState and gate showing the animation on the
             // mErrorToIdleAnimationRunnable as a proxy, than add a ton of extra state. For example,
@@ -426,11 +435,17 @@
             }
         } else if (oldState == STATE_AUTHENTICATING && newState == STATE_AUTHENTICATED) {
             mIconController.animateOnce(R.drawable.face_dialog_dark_to_checkmark);
+            mBiometricIcon.setContentDescription(mContext.getString(
+                    R.string.biometric_dialog_face_icon_description_authenticated));
         } else if (newState == STATE_PENDING_CONFIRMATION) {
             mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
             mIconController.animateOnce(R.drawable.face_dialog_wink_from_dark);
+            mBiometricIcon.setContentDescription(mContext.getString(
+                    R.string.biometric_dialog_face_icon_description_authenticated));
         } else if (newState == STATE_IDLE) {
             mIconController.showStatic(R.drawable.face_dialog_idle_static);
+            mBiometricIcon.setContentDescription(mContext.getString(
+                    R.string.biometric_dialog_face_icon_description_idle));
         } else {
             Log.w(TAG, "Unknown animation from " + oldState + " -> " + newState);
         }
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index facc299..f12bfc3 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -3497,7 +3497,8 @@
      */
     @Override
     public void startCaptivePortalAppInternal(Network network, Bundle appExtras) {
-        mContext.checkCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
+        mContext.enforceCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+                "ConnectivityService");
 
         final Intent appIntent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN);
         appIntent.putExtras(appExtras);
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index c646149..fc355b7 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -286,6 +286,7 @@
     private static final String ATTR_NICKNAME = "nickname";
     private static final String ATTR_USER_FLAGS = "userFlags";
     private static final String ATTR_CREATED_MILLIS = "createdMillis";
+    private static final String ATTR_LAST_SEEN_MILLIS = "lastSeenMillis";
     private static final String ATTR_LAST_TRIM_MILLIS = "lastTrimMillis";
     private static final String ATTR_LAST_BENCH_MILLIS = "lastBenchMillis";
 
@@ -1313,7 +1314,7 @@
     private void onVolumeStateChangedLocked(VolumeInfo vol, int oldState, int newState) {
         // Remember that we saw this volume so we're ready to accept user
         // metadata, or so we can annoy them when a private volume is ejected
-        if (vol.isMountedReadable() && !TextUtils.isEmpty(vol.fsUuid)) {
+        if (!TextUtils.isEmpty(vol.fsUuid)) {
             VolumeRecord rec = mRecords.get(vol.fsUuid);
             if (rec == null) {
                 rec = new VolumeRecord(vol.type, vol.fsUuid);
@@ -1323,14 +1324,15 @@
                     rec.nickname = vol.disk.getDescription();
                 }
                 mRecords.put(rec.fsUuid, rec);
-                writeSettingsLocked();
             } else {
                 // Handle upgrade case where we didn't store partition GUID
                 if (TextUtils.isEmpty(rec.partGuid)) {
                     rec.partGuid = vol.partGuid;
-                    writeSettingsLocked();
                 }
             }
+
+            rec.lastSeenMillis = System.currentTimeMillis();
+            writeSettingsLocked();
         }
 
         mCallbacks.notifyVolumeStateChanged(vol, oldState, newState);
@@ -1731,9 +1733,10 @@
         meta.partGuid = readStringAttribute(in, ATTR_PART_GUID);
         meta.nickname = readStringAttribute(in, ATTR_NICKNAME);
         meta.userFlags = readIntAttribute(in, ATTR_USER_FLAGS);
-        meta.createdMillis = readLongAttribute(in, ATTR_CREATED_MILLIS);
-        meta.lastTrimMillis = readLongAttribute(in, ATTR_LAST_TRIM_MILLIS);
-        meta.lastBenchMillis = readLongAttribute(in, ATTR_LAST_BENCH_MILLIS);
+        meta.createdMillis = readLongAttribute(in, ATTR_CREATED_MILLIS, 0);
+        meta.lastSeenMillis = readLongAttribute(in, ATTR_LAST_SEEN_MILLIS, 0);
+        meta.lastTrimMillis = readLongAttribute(in, ATTR_LAST_TRIM_MILLIS, 0);
+        meta.lastBenchMillis = readLongAttribute(in, ATTR_LAST_BENCH_MILLIS, 0);
         return meta;
     }
 
@@ -1745,6 +1748,7 @@
         writeStringAttribute(out, ATTR_NICKNAME, rec.nickname);
         writeIntAttribute(out, ATTR_USER_FLAGS, rec.userFlags);
         writeLongAttribute(out, ATTR_CREATED_MILLIS, rec.createdMillis);
+        writeLongAttribute(out, ATTR_LAST_SEEN_MILLIS, rec.lastSeenMillis);
         writeLongAttribute(out, ATTR_LAST_TRIM_MILLIS, rec.lastTrimMillis);
         writeLongAttribute(out, ATTR_LAST_BENCH_MILLIS, rec.lastBenchMillis);
         out.endTag(null, TAG_VOLUME);
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 88919df..b9a6a10 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -760,7 +760,6 @@
         @Override // Binder call
         public int canAuthenticate(String opPackageName) {
             checkPermission();
-            checkAppOp(opPackageName, Binder.getCallingUid());
 
             final int userId = UserHandle.getCallingUserId();
             final long ident = Binder.clearCallingIdentity();
@@ -833,9 +832,9 @@
     }
 
     private void checkPermission() {
-        if (getContext().checkCallingPermission(USE_FINGERPRINT)
+        if (getContext().checkCallingOrSelfPermission(USE_FINGERPRINT)
                 != PackageManager.PERMISSION_GRANTED) {
-            getContext().enforceCallingPermission(USE_BIOMETRIC,
+            getContext().enforceCallingOrSelfPermission(USE_BIOMETRIC,
                     "Must have USE_BIOMETRIC permission");
         }
     }
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index c2125b0..b246eb6 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -421,8 +421,9 @@
                     new PasswordSlotManager());
         }
 
-        public boolean hasBiometrics() {
-            return BiometricManager.hasBiometrics(mContext);
+        public boolean hasEnrolledBiometrics() {
+            BiometricManager bm = mContext.getSystemService(BiometricManager.class);
+            return bm.canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS;
         }
 
         public int binderGetCallingUid() {
@@ -2502,7 +2503,8 @@
         // TODO: When lockout is handled under the HAL for all biometrics (fingerprint),
         // we need to generate challenge for each one, have it signed by GK and reset lockout
         // for each modality.
-        if (!hasChallenge && pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
+        if (!hasChallenge && pm.hasSystemFeature(PackageManager.FEATURE_FACE)
+                && mInjector.hasEnrolledBiometrics()) {
             challenge = mContext.getSystemService(FaceManager.class).generateChallenge();
         }
 
@@ -2544,8 +2546,8 @@
         if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
             notifyActivePasswordMetricsAvailable(credentialType, userCredential, userId);
             unlockKeystore(authResult.authToken.deriveKeyStorePassword(), userId);
-            // Reset lockout
-            if (mInjector.hasBiometrics()) {
+            // Reset lockout only if user has enrolled templates
+            if (mInjector.hasEnrolledBiometrics()) {
                 BiometricManager bm = mContext.getSystemService(BiometricManager.class);
                 Slog.i(TAG, "Resetting lockout, length: "
                         + authResult.gkResponse.getPayload().length);
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index bab612d..9d11596 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -73,6 +73,7 @@
 
     public static final int FLAG_STORAGE_DE = IInstalld.FLAG_STORAGE_DE;
     public static final int FLAG_STORAGE_CE = IInstalld.FLAG_STORAGE_CE;
+    public static final int FLAG_STORAGE_EXTERNAL = IInstalld.FLAG_STORAGE_EXTERNAL;
 
     public static final int FLAG_CLEAR_CACHE_ONLY = IInstalld.FLAG_CLEAR_CACHE_ONLY;
     public static final int FLAG_CLEAR_CODE_CACHE_ONLY = IInstalld.FLAG_CLEAR_CODE_CACHE_ONLY;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 9d70209..23aa8f0 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -89,6 +89,7 @@
 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
 import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
 import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
+import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
 
 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
@@ -3249,7 +3250,7 @@
                     if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
                         // No apps are running this early, so no need to freeze
                         clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
-                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
+                                FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
                                         | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
                     }
                 }
@@ -3502,8 +3503,8 @@
                 }
                 return false;
             }
-            clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE
-                    | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
+            clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
+                    | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
             mDexManager.notifyPackageUpdated(pkg.packageName,
                     pkg.baseCodePath, pkg.splitCodePaths);
         }
@@ -15975,6 +15976,9 @@
             synchronized (mInstallLock) {
                 // Clean up both app data and code
                 // All package moves are frozen until finished
+
+                // We purposefully exclude FLAG_STORAGE_EXTERNAL here, since
+                // this task was only focused on moving data on internal storage.
                 for (int userId : userIds) {
                     try {
                         mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
@@ -17075,8 +17079,8 @@
             final String packageName = pkg.packageName;
             prepareAppDataAfterInstallLIF(pkg);
             if (reconciledPkg.prepareResult.clearCodeCache) {
-                clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
-                        | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
+                clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
+                        | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
             }
             if (reconciledPkg.prepareResult.replace) {
                 mDexManager.notifyPackageUpdated(pkg.packageName,
@@ -18848,7 +18852,7 @@
                 resolvedPkg.setVolumeUuid(deletedPs.volumeUuid);
             }
             destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
-                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
+                    FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
             destroyAppProfilesLIF(resolvedPkg);
             if (outInfo != null) {
                 outInfo.dataRemoved = true;
@@ -19600,7 +19604,7 @@
             }
 
             destroyAppDataLIF(pkg, nextUserId,
-                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
+                    FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
             clearDefaultBrowserIfNeededForUser(ps.name, nextUserId);
             removeKeystoreDataIfNeeded(nextUserId, ps.appId);
             final SparseBooleanArray changedUsers = new SparseBooleanArray();
@@ -19736,7 +19740,7 @@
         }
 
         clearAppDataLIF(pkg, userId,
-                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
+                FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
 
         final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
         removeKeystoreDataIfNeeded(userId, appId);
@@ -19967,8 +19971,7 @@
             }
             if (doClearData) {
                 synchronized (mInstallLock) {
-                    final int flags = StorageManager.FLAG_STORAGE_DE
-                            | StorageManager.FLAG_STORAGE_CE;
+                    final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL;
                     // We're only clearing cache files, so we don't care if the
                     // app is unfrozen and still able to run
                     clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
@@ -22516,9 +22519,8 @@
                 }
 
                 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
-                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
-                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
-                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
+                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
+                            | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
                 }
             }
         }
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index fd90f03..ecbecba 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -2005,7 +2005,7 @@
         }
         layoutLetterbox(winHint);
         if (mLetterbox != null && mLetterbox.needsApplySurfaceChanges()) {
-            mLetterbox.applySurfaceChanges(mPendingTransaction);
+            mLetterbox.applySurfaceChanges(getPendingTransaction());
         }
     }
 
@@ -3059,13 +3059,13 @@
 
         if (mSurfaceControl != null) {
             if (show && !mLastSurfaceShowing) {
-                mPendingTransaction.show(mSurfaceControl);
+                getPendingTransaction().show(mSurfaceControl);
             } else if (!show && mLastSurfaceShowing) {
-                mPendingTransaction.hide(mSurfaceControl);
+                getPendingTransaction().hide(mSurfaceControl);
             }
         }
         if (mThumbnail != null) {
-            mThumbnail.setShowing(mPendingTransaction, show);
+            mThumbnail.setShowing(getPendingTransaction(), show);
         }
         mLastSurfaceShowing = show;
         super.prepareSurfaces();
@@ -3225,8 +3225,8 @@
 
     private void updateColorTransform() {
         if (mSurfaceControl != null && mLastAppSaturationInfo != null) {
-            mPendingTransaction.setColorTransform(mSurfaceControl, mLastAppSaturationInfo.mMatrix,
-                    mLastAppSaturationInfo.mTranslation);
+            getPendingTransaction().setColorTransform(mSurfaceControl,
+                    mLastAppSaturationInfo.mMatrix, mLastAppSaturationInfo.mTranslation);
             mWmService.scheduleAnimationLocked();
         }
     }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 58a03b2..1e826ee 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3340,7 +3340,7 @@
         final SurfaceControl newParent =
                 shouldAttachToDisplay ? mWindowingLayer : computeImeParent();
         if (newParent != null) {
-            mPendingTransaction.reparent(mImeWindowsContainers.mSurfaceControl, newParent);
+            getPendingTransaction().reparent(mImeWindowsContainers.mSurfaceControl, newParent);
             scheduleAnimation();
         }
     }
@@ -3747,7 +3747,8 @@
             mPortalWindowHandle.touchableRegion.getBounds(mTmpRect);
             if (!mTmpBounds.equals(mTmpRect)) {
                 mPortalWindowHandle.touchableRegion.set(mTmpBounds);
-                mPendingTransaction.setInputWindowInfo(mParentSurfaceControl, mPortalWindowHandle);
+                getPendingTransaction().setInputWindowInfo(
+                        mParentSurfaceControl, mPortalWindowHandle);
             }
         }
     }
@@ -4846,18 +4847,23 @@
         try {
             final ScreenRotationAnimation screenRotationAnimation =
                     mWmService.mAnimator.getScreenRotationAnimationLocked(mDisplayId);
+            final Transaction transaction = getPendingTransaction();
             if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
                 screenRotationAnimation.getEnterTransformation().getMatrix().getValues(mTmpFloats);
-                mPendingTransaction.setMatrix(mWindowingLayer,
+                transaction.setMatrix(mWindowingLayer,
                         mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
                         mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
-                mPendingTransaction.setPosition(mWindowingLayer,
+                transaction.setPosition(mWindowingLayer,
                         mTmpFloats[Matrix.MTRANS_X], mTmpFloats[Matrix.MTRANS_Y]);
-                mPendingTransaction.setAlpha(mWindowingLayer,
+                transaction.setAlpha(mWindowingLayer,
                         screenRotationAnimation.getEnterTransformation().getAlpha());
             }
 
             super.prepareSurfaces();
+
+            // TODO: Once we totally eliminate global transaction we will pass transaction in here
+            //       rather than merging to global.
+            SurfaceControl.mergeToGlobalTransaction(transaction);
         } finally {
             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
@@ -5013,7 +5019,7 @@
         if (mPortalWindowHandle == null) {
             mPortalWindowHandle = createPortalWindowHandle(sc.toString());
         }
-        mPendingTransaction.setInputWindowInfo(sc, mPortalWindowHandle)
+        getPendingTransaction().setInputWindowInfo(sc, mPortalWindowHandle)
                 .reparent(mWindowingLayer, sc).reparent(mOverlayLayer, sc);
     }
 
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index bb7867c..3820106 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -138,6 +138,7 @@
         setOrientation(SCREEN_ORIENTATION_UNSET);
     }
 
+    @Override
     DisplayContent getDisplayContent() {
         return mStack != null ? mStack.getDisplayContent() : null;
     }
diff --git a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
index 17e4b89..ee4e462 100644
--- a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
+++ b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
@@ -77,7 +77,7 @@
 
     @Override
     public SurfaceControl.Transaction getPendingTransaction() {
-        return mTask.mPendingTransaction;
+        return mTask.getPendingTransaction();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 757f6a1..ab5e071 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -93,10 +93,6 @@
     /** Unique identifier */
     final int mStackId;
 
-    /** The display this stack sits under. */
-    // TODO: Track parent marks like this in WindowContainer.
-    private DisplayContent mDisplayContent;
-
     /** For comparison with DisplayContent bounds. */
     private Rect mTmpRect = new Rect();
     private Rect mTmpRect2 = new Rect();
@@ -177,10 +173,6 @@
         EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId);
     }
 
-    DisplayContent getDisplayContent() {
-        return mDisplayContent;
-    }
-
     Task findHomeTask() {
         if (!isActivityTypeHome() || mChildren.isEmpty()) {
             return null;
@@ -825,8 +817,7 @@
             throw new IllegalStateException("onDisplayChanged: Already attached");
         }
 
-        final boolean movedToNewDisplay = mDisplayContent == null;
-        mDisplayContent = dc;
+        super.onDisplayChanged(dc);
 
         updateSurfaceBounds();
         if (mAnimationBackgroundSurface == null) {
@@ -834,8 +825,6 @@
                     .setName("animation background stackId=" + mStackId)
                     .build();
         }
-
-        super.onDisplayChanged(dc);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index d5c3e4f..bbef261 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -109,14 +109,19 @@
     // The owner/creator for this container. No controller if null.
     WindowContainerController mController;
 
+    // The display this window container is on.
+    protected DisplayContent mDisplayContent;
+
     protected SurfaceControl mSurfaceControl;
     private int mLastLayer = 0;
     private SurfaceControl mLastRelativeToLayer = null;
 
+    // TODO(b/132320879): Remove this from WindowContainers except DisplayContent.
+    private final Transaction mPendingTransaction;
+
     /**
      * Applied as part of the animation pass in "prepareSurfaces".
      */
-    protected final Transaction mPendingTransaction;
     protected final SurfaceAnimator mSurfaceAnimator;
     protected final WindowManagerService mWmService;
 
@@ -320,12 +325,12 @@
         }
 
         if (mSurfaceControl != null) {
-            mPendingTransaction.remove(mSurfaceControl);
+            getPendingTransaction().remove(mSurfaceControl);
 
             // Merge to parent transaction to ensure the transactions on this WindowContainer are
             // applied in native even if WindowContainer is removed.
             if (mParent != null) {
-                mParent.getPendingTransaction().merge(mPendingTransaction);
+                mParent.getPendingTransaction().merge(getPendingTransaction());
             }
 
             mSurfaceControl = null;
@@ -508,12 +513,20 @@
      * @param dc The display this container is on after changes.
      */
     void onDisplayChanged(DisplayContent dc) {
+        mDisplayContent = dc;
+        if (dc != null && dc != this) {
+            dc.getPendingTransaction().merge(mPendingTransaction);
+        }
         for (int i = mChildren.size() - 1; i >= 0; --i) {
             final WindowContainer child = mChildren.get(i);
             child.onDisplayChanged(dc);
         }
     }
 
+    DisplayContent getDisplayContent() {
+        return mDisplayContent;
+    }
+
     void setWaitingForDrawnIfResizingChanged() {
         for (int i = mChildren.size() - 1; i >= 0; --i) {
             final WindowContainer wc = mChildren.get(i);
@@ -1180,13 +1193,7 @@
         }
     }
 
-    /**
-     * TODO: Once we totally eliminate global transaction we will pass transaction in here
-     * rather than merging to global.
-     */
     void prepareSurfaces() {
-        SurfaceControl.mergeToGlobalTransaction(getPendingTransaction());
-
         // If a leash has been set when the transaction was committed, then the leash reparent has
         // been committed.
         mCommittedReparentToAnimationLeash = mSurfaceAnimator.hasLeash();
@@ -1204,8 +1211,8 @@
     }
 
     /**
-     * Trigger a call to prepareSurfaces from the animation thread, such that
-     * mPendingTransaction will be applied.
+     * Trigger a call to prepareSurfaces from the animation thread, such that pending transactions
+     * will be applied.
      */
     void scheduleAnimation() {
         if (mParent != null) {
@@ -1224,6 +1231,14 @@
 
     @Override
     public Transaction getPendingTransaction() {
+        final DisplayContent displayContent = getDisplayContent();
+        if (displayContent != null && displayContent != this) {
+            return displayContent.getPendingTransaction();
+        }
+        // This WindowContainer has not attached to a display yet or this is a DisplayContent, so we
+        // let the caller to save the surface operations within the local mPendingTransaction.
+        // If this is not a DisplayContent, we will merge it to the pending transaction of its
+        // display once it attaches to it.
         return mPendingTransaction;
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index dd3c600..5ef184a 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1313,6 +1313,7 @@
         mOrientationChangeTimedOut = true;
     }
 
+    @Override
     DisplayContent getDisplayContent() {
         return mToken.getDisplayContent();
     }
@@ -4602,7 +4603,7 @@
                 new WindowAnimationSpec(anim, mSurfacePosition, false /* canSkipFirstFrame */,
                         0 /* windowCornerRadius */),
                 mWmService.mSurfaceAnimationRunner);
-        startAnimation(mPendingTransaction, adapter);
+        startAnimation(getPendingTransaction(), adapter);
         commitPendingTransaction();
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index f0b9c62..8aee0f2 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -82,9 +82,6 @@
     // windows will be put to the bottom of the list.
     boolean sendingToBottom;
 
-    // The display this token is on.
-    protected DisplayContent mDisplayContent;
-
     /** The owner has {@link android.Manifest.permission#MANAGE_APP_TOKENS} */
     final boolean mOwnerCanManageAppTokens;
 
@@ -249,10 +246,6 @@
         return null;
     }
 
-    DisplayContent getDisplayContent() {
-        return mDisplayContent;
-    }
-
     @Override
     void removeImmediately() {
         if (mDisplayContent != null) {
@@ -266,7 +259,6 @@
     @Override
     void onDisplayChanged(DisplayContent dc) {
         dc.reParentWindowToken(this);
-        mDisplayContent = dc;
 
         // TODO(b/36740756): One day this should perhaps be hooked
         // up with goodToGo, so we don't move a window
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
index 10fb3ba..19ed5f3 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -110,7 +110,7 @@
         }
 
         @Override
-        public boolean hasBiometrics() {
+        public boolean hasEnrolledBiometrics() {
             return false;
         }
 
diff --git a/services/usage/java/com/android/server/usage/StorageStatsService.java b/services/usage/java/com/android/server/usage/StorageStatsService.java
index faf6ee2..0f3050f 100644
--- a/services/usage/java/com/android/server/usage/StorageStatsService.java
+++ b/services/usage/java/com/android/server/usage/StorageStatsService.java
@@ -120,6 +120,7 @@
             @Override
             public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
                 switch (vol.type) {
+                    case VolumeInfo.TYPE_PUBLIC:
                     case VolumeInfo.TYPE_PRIVATE:
                     case VolumeInfo.TYPE_EMULATED:
                         if (newState == VolumeInfo.STATE_MOUNTED) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index e1ffb0f..d77ea6e 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -77,6 +77,7 @@
 import com.android.internal.util.Preconditions;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
+import com.android.server.SystemServerInitThreadPool;
 import com.android.server.SystemService;
 import com.android.server.UiThread;
 import com.android.server.soundtrigger.SoundTriggerInternal;
@@ -1283,7 +1284,9 @@
                 mRm.addOnRoleHoldersChangedListenerAsUser(executor, this, UserHandle.ALL);
                 UserHandle currentUser = UserHandle.of(LocalServices.getService(
                         ActivityManagerInternal.class).getCurrentUserId());
-                onRoleHoldersChanged(RoleManager.ROLE_ASSISTANT, currentUser);
+                SystemServerInitThreadPool.get().submit(() -> onRoleHoldersChanged(
+                        RoleManager.ROLE_ASSISTANT, currentUser),
+                        "VoiceInteractionManagerService RoleObserver initialization");
             }
 
             private @NonNull String getDefaultRecognizer(@NonNull UserHandle user) {