Merge "DO NOT MERGE Check fingerprint client against top activity in auth callback" into rvc-qpr-dev
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index dc16125..13bf197 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -554,6 +554,10 @@
             return NO_ERROR;
         }
         if (!args[0].compare(String8("section"))) {
+            if (argCount == 1) {
+                fprintf(out, "Not enough arguments for section\n");
+                return NO_ERROR;
+            }
             int id = atoi(args[1]);
             int idx = 0;
             while (SECTION_LIST[idx] != NULL) {
diff --git a/core/java/android/app/slice/SliceProvider.java b/core/java/android/app/slice/SliceProvider.java
index bd1eea5..46be548 100644
--- a/core/java/android/app/slice/SliceProvider.java
+++ b/core/java/android/app/slice/SliceProvider.java
@@ -153,6 +153,7 @@
      */
     public static final String EXTRA_PKG = "pkg";
     /**
+     * @Deprecated provider pkg is now being extracted in SlicePermissionActivity
      * @hide
      */
     public static final String EXTRA_PROVIDER_PKG = "provider_pkg";
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 986e6ea..9d4ab0b 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -72,6 +72,7 @@
 import android.util.Size;
 
 import dalvik.annotation.optimization.FastNative;
+import dalvik.system.VMRuntime;
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
@@ -351,6 +352,7 @@
         if (mMetadataPtr == 0) {
             throw new OutOfMemoryError("Failed to allocate native CameraMetadata");
         }
+        updateNativeAllocation();
     }
 
     /**
@@ -362,6 +364,7 @@
         if (mMetadataPtr == 0) {
             throw new OutOfMemoryError("Failed to allocate native CameraMetadata");
         }
+        updateNativeAllocation();
     }
 
     /**
@@ -443,6 +446,7 @@
 
     public void readFromParcel(Parcel in) {
         nativeReadFromParcel(in, mMetadataPtr);
+        updateNativeAllocation();
     }
 
     /**
@@ -533,6 +537,11 @@
         // Delete native pointer, but does not clear it
         nativeClose(mMetadataPtr);
         mMetadataPtr = 0;
+
+        if (mBufferSize > 0) {
+            VMRuntime.getRuntime().registerNativeFree(mBufferSize);
+        }
+        mBufferSize = 0;
     }
 
     private <T> T getBase(CameraCharacteristics.Key<T> key) {
@@ -1645,9 +1654,26 @@
         return true;
     }
 
+    private void updateNativeAllocation() {
+        long currentBufferSize = nativeGetBufferSize(mMetadataPtr);
+
+        if (currentBufferSize != mBufferSize) {
+            if (mBufferSize > 0) {
+                VMRuntime.getRuntime().registerNativeFree(mBufferSize);
+            }
+
+            mBufferSize = currentBufferSize;
+
+            if (mBufferSize > 0) {
+                VMRuntime.getRuntime().registerNativeAllocation(mBufferSize);
+            }
+        }
+    }
+
     private int mCameraId = -1;
     private boolean mHasMandatoryConcurrentStreams = false;
     private Size mDisplaySize = new Size(0, 0);
+    private long mBufferSize = 0;
 
     /**
      * Set the current camera Id.
@@ -1705,6 +1731,8 @@
     private static synchronized native boolean nativeIsEmpty(long ptr);
     @FastNative
     private static synchronized native int nativeGetEntryCount(long ptr);
+    @FastNative
+    private static synchronized native long nativeGetBufferSize(long ptr);
 
     @UnsupportedAppUsage
     @FastNative
@@ -1744,6 +1772,8 @@
         mCameraId = other.mCameraId;
         mHasMandatoryConcurrentStreams = other.mHasMandatoryConcurrentStreams;
         mDisplaySize = other.mDisplaySize;
+        updateNativeAllocation();
+        other.updateNativeAllocation();
     }
 
     /**
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 327bca2..4e1f819 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -218,8 +218,15 @@
     }
 
     /** {@hide} */
-    private void enforceTree(Uri documentUri) {
-        if (isTreeUri(documentUri)) {
+    private void enforceTreeForExtraUris(Bundle extras) {
+        enforceTree(extras.getParcelable(DocumentsContract.EXTRA_URI));
+        enforceTree(extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI));
+        enforceTree(extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI));
+    }
+
+    /** {@hide} */
+    private void enforceTree(@Nullable Uri documentUri) {
+        if (documentUri != null && isTreeUri(documentUri)) {
             final String parent = getTreeDocumentId(documentUri);
             final String child = getDocumentId(documentUri);
             if (Objects.equals(parent, child)) {
@@ -232,6 +239,10 @@
         }
     }
 
+    private Uri validateIncomingNullableUri(@Nullable Uri uri) {
+        return uri == null ? null : validateIncomingUri(uri);
+    }
+
     /**
      * Create a new document and return its newly generated
      * {@link Document#COLUMN_DOCUMENT_ID}. You must allocate a new
@@ -1076,11 +1087,21 @@
         final Context context = getContext();
         final Bundle out = new Bundle();
 
+        // If the URI is a tree URI performs some validation.
+        enforceTreeForExtraUris(extras);
+
+        final Uri extraUri = validateIncomingNullableUri(
+                extras.getParcelable(DocumentsContract.EXTRA_URI));
+        final Uri extraTargetUri = validateIncomingNullableUri(
+                extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI));
+        final Uri extraParentUri = validateIncomingNullableUri(
+                extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI));
+
         if (METHOD_EJECT_ROOT.equals(method)) {
             // Given that certain system apps can hold MOUNT_UNMOUNT permission, but only apps
             // signed with platform signature can hold MANAGE_DOCUMENTS, we are going to check for
             // MANAGE_DOCUMENTS or associated URI permission here instead
-            final Uri rootUri = extras.getParcelable(DocumentsContract.EXTRA_URI);
+            final Uri rootUri = extraUri;
             enforceWritePermissionInner(rootUri, getCallingPackage(), getCallingAttributionTag(),
                     null);
 
@@ -1090,7 +1111,7 @@
             return out;
         }
 
-        final Uri documentUri = extras.getParcelable(DocumentsContract.EXTRA_URI);
+        final Uri documentUri = extraUri;
         final String authority = documentUri.getAuthority();
         final String documentId = DocumentsContract.getDocumentId(documentUri);
 
@@ -1099,14 +1120,11 @@
                     "Requested authority " + authority + " doesn't match provider " + mAuthority);
         }
 
-        // If the URI is a tree URI performs some validation.
-        enforceTree(documentUri);
-
         if (METHOD_IS_CHILD_DOCUMENT.equals(method)) {
             enforceReadPermissionInner(documentUri, getCallingPackage(),
                     getCallingAttributionTag(), null);
 
-            final Uri childUri = extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI);
+            final Uri childUri = extraTargetUri;
             final String childAuthority = childUri.getAuthority();
             final String childId = DocumentsContract.getDocumentId(childUri);
 
@@ -1173,7 +1191,7 @@
             revokeDocumentPermission(documentId);
 
         } else if (METHOD_COPY_DOCUMENT.equals(method)) {
-            final Uri targetUri = extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI);
+            final Uri targetUri = extraTargetUri;
             final String targetId = DocumentsContract.getDocumentId(targetUri);
 
             enforceReadPermissionInner(documentUri, getCallingPackage(),
@@ -1197,9 +1215,9 @@
             }
 
         } else if (METHOD_MOVE_DOCUMENT.equals(method)) {
-            final Uri parentSourceUri = extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI);
+            final Uri parentSourceUri = extraParentUri;
             final String parentSourceId = DocumentsContract.getDocumentId(parentSourceUri);
-            final Uri targetUri = extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI);
+            final Uri targetUri = extraTargetUri;
             final String targetId = DocumentsContract.getDocumentId(targetUri);
 
             enforceWritePermissionInner(documentUri, getCallingPackage(),
@@ -1225,7 +1243,7 @@
             }
 
         } else if (METHOD_REMOVE_DOCUMENT.equals(method)) {
-            final Uri parentSourceUri = extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI);
+            final Uri parentSourceUri = extraParentUri;
             final String parentSourceId = DocumentsContract.getDocumentId(parentSourceUri);
 
             enforceReadPermissionInner(parentSourceUri, getCallingPackage(),
diff --git a/core/jni/android_hardware_camera2_CameraMetadata.cpp b/core/jni/android_hardware_camera2_CameraMetadata.cpp
index 9ad4cd9..b5955c4 100644
--- a/core/jni/android_hardware_camera2_CameraMetadata.cpp
+++ b/core/jni/android_hardware_camera2_CameraMetadata.cpp
@@ -249,6 +249,16 @@
     return metadata->entryCount();
 }
 
+static jlong CameraMetadata_getBufferSize(JNIEnv *env, jclass thiz, jlong ptr) {
+    ALOGV("%s", __FUNCTION__);
+
+    CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, ptr);
+
+    if (metadata == NULL) return 0;
+
+    return metadata->bufferSize();
+}
+
 // idempotent. calling more than once has no effect.
 static void CameraMetadata_close(JNIEnv *env, jclass thiz, jlong ptr) {
     ALOGV("%s", __FUNCTION__);
@@ -552,6 +562,9 @@
   { "nativeGetEntryCount",
     "(J)I",
     (void*)CameraMetadata_getEntryCount },
+  { "nativeGetBufferSize",
+    "(J)J",
+    (void*)CameraMetadata_getBufferSize },
   { "nativeClose",
     "(J)V",
     (void*)CameraMetadata_close },
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6a92a83..bb134f1 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -144,7 +144,7 @@
     <protected-broadcast android:name="android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.device.action.UUID" />
     <protected-broadcast android:name="android.bluetooth.device.action.MAS_INSTANCE" />
-    <protected-broadcast android:name="android.bluetooth.action.ALIAS_CHANGED" />
+    <protected-broadcast android:name="android.bluetooth.device.action.ALIAS_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.device.action.FOUND" />
     <protected-broadcast android:name="android.bluetooth.device.action.CLASS_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.device.action.ACL_CONNECTED" />
diff --git a/drm/jni/Android.bp b/drm/jni/Android.bp
index 1e33f0e..68757d8 100644
--- a/drm/jni/Android.bp
+++ b/drm/jni/Android.bp
@@ -21,6 +21,7 @@
 
     shared_libs: [
         "libdrmframework",
+        "libdrmframeworkcommon",
         "liblog",
         "libutils",
         "libandroid_runtime",
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index c5d52ee..05f796a 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -1070,7 +1070,7 @@
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"تمت الإضافة إلى المفضّلة"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"تمت الإضافة إلى المفضّلة، الموضع <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"تمت الإزالة من المفضّلة"</string>
-    <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"إضافة إلى المُفضلة"</string>
+    <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"إضافة إلى المحتوى المفضّل"</string>
     <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"إزالة من المفضّلة"</string>
     <string name="accessibility_control_move" msgid="8980344493796647792">"نقل إلى الموضع <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="controls_favorite_default_title" msgid="967742178688938137">"عناصر التحكّم"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 4827ace..0e7345d 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -246,7 +246,7 @@
     <string name="accessibility_remove_notification" msgid="1641455251495815527">"پاک کردن اعلان"</string>
     <string name="accessibility_gps_enabled" msgid="4061313248217660858">"‏GPS فعال شد."</string>
     <string name="accessibility_gps_acquiring" msgid="896207402196024040">"‏دستیابی به GPS."</string>
-    <string name="accessibility_tty_enabled" msgid="1123180388823381118">"‏TeleTypewriter فعال شد."</string>
+    <string name="accessibility_tty_enabled" msgid="1123180388823381118">"تله‌تایپ فعال شد."</string>
     <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"زنگ لرزشی."</string>
     <string name="accessibility_ringer_silent" msgid="8994620163934249882">"زنگ بی‌صدا."</string>
     <!-- no translation found for accessibility_casting (8708751252897282313) -->
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 42831c3..480da30 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -246,7 +246,7 @@
     <string name="accessibility_remove_notification" msgid="1641455251495815527">"Eliminar notificación."</string>
     <string name="accessibility_gps_enabled" msgid="4061313248217660858">"GPS activado"</string>
     <string name="accessibility_gps_acquiring" msgid="896207402196024040">"Obtendo GPS."</string>
-    <string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter activado"</string>
+    <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teletipo activado"</string>
     <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Timbre en vibración"</string>
     <string name="accessibility_ringer_silent" msgid="8994620163934249882">"Timbre silenciado"</string>
     <!-- no translation found for accessibility_casting (8708751252897282313) -->
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 214a6d7..77c5141 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -246,7 +246,7 @@
     <string name="accessibility_remove_notification" msgid="1641455251495815527">"Մաքրել ծանուցումը:"</string>
     <string name="accessibility_gps_enabled" msgid="4061313248217660858">"GPS-ը միացված է:"</string>
     <string name="accessibility_gps_acquiring" msgid="896207402196024040">"GPS-ի ստացում:"</string>
-    <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Հեռամուտքագրիչը միացված է:"</string>
+    <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Հեռատիպը միացված է:"</string>
     <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Թրթռազանգ:"</string>
     <string name="accessibility_ringer_silent" msgid="8994620163934249882">"Զանգակը լռեցված է:"</string>
     <!-- no translation found for accessibility_casting (8708751252897282313) -->
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 97652f0..6216736 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -597,7 +597,7 @@
     <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh lama tombol Ringkasan untuk melepas pin."</string>
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh lama tombol Beranda untuk melepas pin."</string>
     <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Data pribadi dapat diakses (seperti kontak dan konten email)."</string>
-    <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Aplikasi yang dipasangi pin dapat membuka aplikasi lain."</string>
+    <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Aplikasi yang disematkan dapat membuka aplikasi lain."</string>
     <string name="screen_pinning_toast" msgid="8177286912533744328">"Untuk melepas pin aplikasi ini, sentuh &amp; lama tombol Kembali dan Ringkasan"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Untuk melepas pin aplikasi ini, sentuh &amp; lama tombol Kembali dan Layar utama"</string>
     <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Untuk melepas pin aplikasi ini, geser ke atas &amp; tahan"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index a67130b..912b25e 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -246,7 +246,7 @@
     <string name="accessibility_remove_notification" msgid="1641455251495815527">"Pastro njoftimin."</string>
     <string name="accessibility_gps_enabled" msgid="4061313248217660858">"GPS-ja është e aktivizuar."</string>
     <string name="accessibility_gps_acquiring" msgid="896207402196024040">"Po siguron GPS-në."</string>
-    <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teleprinteri është i aktivizuar."</string>
+    <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teletajpi është i aktivizuar."</string>
     <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Zile me dridhje."</string>
     <string name="accessibility_ringer_silent" msgid="8994620163934249882">"Zilja është heshtur."</string>
     <!-- no translation found for accessibility_casting (8708751252897282313) -->
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 3d77bd7..99219d1 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -882,12 +882,12 @@
     <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"மேலே 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"மேலே 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"கீழ்ப்புறம் முழுத் திரை"</string>
-    <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"டைலை அகற்றும்"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"கடைசியில் டைலைச் சேர்க்கும்"</string>
-    <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"டைலை நகர்த்து"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"டைலைச் சேர்"</string>
-    <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> இடத்திற்கு நகர்த்தும்"</string>
-    <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> என்ற இடத்தில் சேர்க்கும்"</string>
+    <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"கட்டத்தை அகற்றும்"</string>
+    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"கடைசியில் கட்டத்தைச் சேர்க்கும்"</string>
+    <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"கட்டத்தை நகர்த்து"</string>
+    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"கட்டத்தைச் சேர்"</string>
+    <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g>க்கு நகர்த்தும்"</string>
+    <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g>ல் சேர்க்கும்"</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"இடம்: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"விரைவு அமைப்புகள் திருத்தி."</string>
     <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> அறிவிப்பு: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java b/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java
index 449ed8c..1b241b7 100644
--- a/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java
@@ -16,6 +16,7 @@
 
 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 
+import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.slice.SliceManager;
@@ -29,6 +30,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.text.BidiFormatter;
+import android.util.EventLog;
 import android.util.Log;
 import android.widget.CheckBox;
 import android.widget.TextView;
@@ -50,10 +52,12 @@
 
         mUri = getIntent().getParcelableExtra(SliceProvider.EXTRA_BIND_URI);
         mCallingPkg = getIntent().getStringExtra(SliceProvider.EXTRA_PKG);
-        mProviderPkg = getIntent().getStringExtra(SliceProvider.EXTRA_PROVIDER_PKG);
 
         try {
             PackageManager pm = getPackageManager();
+            mProviderPkg = pm.resolveContentProvider(mUri.getAuthority(),
+                    PackageManager.GET_META_DATA).applicationInfo.packageName;
+            verifyCallingPkg();
             CharSequence app1 = BidiFormatter.getInstance().unicodeWrap(pm.getApplicationInfo(
                     mCallingPkg, 0).loadSafeLabel(pm, PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX,
                     PackageItemInfo.SAFE_LABEL_FLAG_TRIM
@@ -97,4 +101,29 @@
     public void onDismiss(DialogInterface dialog) {
         finish();
     }
+
+    private void verifyCallingPkg() {
+        final String providerPkg = getIntent().getStringExtra(SliceProvider.EXTRA_PROVIDER_PKG);
+        if (providerPkg == null || mProviderPkg.equals(providerPkg)) return;
+        final String callingPkg = getCallingPkg();
+        EventLog.writeEvent(0x534e4554, "159145361", getUid(callingPkg), String.format(
+                "pkg %s (disguised as %s) attempted to request permission to show %s slices in %s",
+                callingPkg, providerPkg, mProviderPkg, mCallingPkg));
+    }
+
+    @Nullable
+    private String getCallingPkg() {
+        final Uri referrer = getReferrer();
+        if (referrer == null) return null;
+        return referrer.getHost();
+    }
+
+    private int getUid(@Nullable final String pkg) {
+        if (pkg == null) return -1;
+        try {
+            return getPackageManager().getApplicationInfo(pkg, 0).uid;
+        } catch (NameNotFoundException e) {
+        }
+        return -1;
+    }
 }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 23bf955..c4f1c80 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -310,11 +310,10 @@
     private List<Map<Integer, PreciseDataConnectionState>> mPreciseDataConnectionStates =
             new ArrayList<Map<Integer, PreciseDataConnectionState>>();
 
-    static final int ENFORCE_COARSE_LOCATION_PERMISSION_MASK =
-            PhoneStateListener.LISTEN_REGISTRATION_FAILURE
-                    | PhoneStateListener.LISTEN_BARRING_INFO;
-
-    static final int ENFORCE_FINE_LOCATION_PERMISSION_MASK =
+    // Starting in Q, almost all cellular location requires FINE location enforcement.
+    // Prior to Q, cellular was available with COARSE location enforcement. Bits in this
+    // list will be checked for COARSE on apps targeting P or earlier and FINE on Q or later.
+    static final int ENFORCE_LOCATION_PERMISSION_MASK =
             PhoneStateListener.LISTEN_CELL_LOCATION
                     | PhoneStateListener.LISTEN_CELL_INFO
                     | PhoneStateListener.LISTEN_REGISTRATION_FAILURE
@@ -371,7 +370,7 @@
                                 + " newDefaultPhoneId=" + newDefaultPhoneId);
                     }
 
-                    //Due to possible risk condition,(notify call back using the new
+                    //Due to possible race condition,(notify call back using the new
                     //defaultSubId comes before new defaultSubId update) we need to recall all
                     //possible missed notify callback
                     synchronized (mRecords) {
@@ -904,7 +903,8 @@
                     if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
                         try {
                             if (DBG_LOC) log("listen: mCellIdentity = " + mCellIdentity[phoneId]);
-                            if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
+                            if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
+                                    && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
                                 // null will be translated to empty CellLocation object in client.
                                 r.callback.onCellLocationChanged(mCellIdentity[phoneId]);
                             }
@@ -959,7 +959,8 @@
                         try {
                             if (DBG_LOC) log("listen: mCellInfo[" + phoneId + "] = "
                                     + mCellInfo.get(phoneId));
-                            if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
+                            if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
+                                    && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
                                 r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
                             }
                         } catch (RemoteException ex) {
@@ -1513,7 +1514,8 @@
                 for (Record r : mRecords) {
                     if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO) &&
                             idMatch(r.subId, subId, phoneId) &&
-                            checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
+                            (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
+                                    && checkFineLocationAccess(r, Build.VERSION_CODES.Q))) {
                         try {
                             if (DBG_LOC) {
                                 log("notifyCellInfoForSubscriber: mCellInfo=" + cellInfo
@@ -1845,7 +1847,8 @@
                 for (Record r : mRecords) {
                     if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) &&
                             idMatch(r.subId, subId, phoneId) &&
-                            checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
+                            (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
+                                    && checkFineLocationAccess(r, Build.VERSION_CODES.Q))) {
                         try {
                             if (DBG_LOC) {
                                 log("notifyCellLocation: cellLocation=" + cellLocation
@@ -2624,19 +2627,13 @@
                 .setCallingPid(Binder.getCallingPid())
                 .setCallingUid(Binder.getCallingUid());
 
-        boolean shouldCheckLocationPermissions = false;
-        if ((events & ENFORCE_COARSE_LOCATION_PERMISSION_MASK) != 0) {
-            locationQueryBuilder.setMinSdkVersionForCoarse(0);
-            shouldCheckLocationPermissions = true;
-        }
-
-        if ((events & ENFORCE_FINE_LOCATION_PERMISSION_MASK) != 0) {
+        if ((events & ENFORCE_LOCATION_PERMISSION_MASK) != 0) {
             // Everything that requires fine location started in Q. So far...
             locationQueryBuilder.setMinSdkVersionForFine(Build.VERSION_CODES.Q);
-            shouldCheckLocationPermissions = true;
-        }
+            // If we're enforcing fine starting in Q, we also want to enforce coarse even for
+            // older SDK versions.
+            locationQueryBuilder.setMinSdkVersionForCoarse(0);
 
-        if (shouldCheckLocationPermissions) {
             LocationAccessPolicy.LocationPermissionResult result =
                     LocationAccessPolicy.checkLocationPermission(
                             mContext, locationQueryBuilder.build());
@@ -2803,8 +2800,16 @@
             try {
                 if (VDBG) log("checkPossibleMissNotify: onServiceStateChanged state=" +
                         mServiceState[phoneId]);
-                r.callback.onServiceStateChanged(
-                        new ServiceState(mServiceState[phoneId]));
+                ServiceState ss = new ServiceState(mServiceState[phoneId]);
+                if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
+                    r.callback.onServiceStateChanged(ss);
+                } else if (checkCoarseLocationAccess(r, Build.VERSION_CODES.Q)) {
+                    r.callback.onServiceStateChanged(
+                            ss.createLocationInfoSanitizedCopy(false));
+                } else {
+                    r.callback.onServiceStateChanged(
+                            ss.createLocationInfoSanitizedCopy(true));
+                }
             } catch (RemoteException ex) {
                 mRemoveList.add(r.binder);
             }
@@ -2849,7 +2854,8 @@
                     log("checkPossibleMissNotify: onCellInfoChanged[" + phoneId + "] = "
                             + mCellInfo.get(phoneId));
                 }
-                if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
+                if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
+                        && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
                     r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
                 }
             } catch (RemoteException ex) {
@@ -2915,7 +2921,8 @@
                     log("checkPossibleMissNotify: onCellLocationChanged mCellIdentity = "
                             + mCellIdentity[phoneId]);
                 }
-                if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
+                if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
+                        && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
                     // null will be translated to empty CellLocation object in client.
                     r.callback.onCellLocationChanged(mCellIdentity[phoneId]);
                 }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3b85180..091c77e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -10459,12 +10459,10 @@
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
-        if (uid == Process.INVALID_UID) {
-            return Process.INVALID_UID;
-        }
+        // If the uid is Process.INVALID_UID, the below 'if' check will be always true
         if (UserHandle.getAppId(uid) != UserHandle.getAppId(callingUid)) {
             // Requires the DUMP permission if the target package doesn't belong
-            // to the caller.
+            // to the caller or it doesn't exist.
             enforceCallingPermission(android.Manifest.permission.DUMP, function);
         }
         return uid;
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 347beab..bcb17bc 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -1601,7 +1601,7 @@
      */
     public synchronized void onUserStopped() {
         // Switch off networking lockdown (if it was enabled)
-        setLockdown(false);
+        setVpnForcedLocked(false);
         mAlwaysOn = false;
 
         // Quit any active connections
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 69b02ce..f630820 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -113,6 +113,7 @@
 import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.internal.util.Preconditions;
 import com.android.internal.widget.ICheckCredentialProgressCallback;
 import com.android.internal.widget.ILockSettings;
 import com.android.internal.widget.LockPatternUtils;
@@ -2618,6 +2619,10 @@
     protected AuthenticationToken initializeSyntheticPasswordLocked(byte[] credentialHash,
             LockscreenCredential credential, int userId) {
         Slog.i(TAG, "Initialize SyntheticPassword for user: " + userId);
+        Preconditions.checkState(
+                getSyntheticPasswordHandleLocked(userId) == SyntheticPasswordManager.DEFAULT_HANDLE,
+                "Cannot reinitialize SP");
+
         final AuthenticationToken auth = mSpManager.newSyntheticPasswordAndSid(
                 getGateKeeperService(), credentialHash, credential, userId);
         if (auth == null) {
@@ -2678,7 +2683,7 @@
 
     @VisibleForTesting
     protected boolean shouldMigrateToSyntheticPasswordLocked(int userId) {
-        return true;
+        return getSyntheticPasswordHandleLocked(userId) == SyntheticPasswordManager.DEFAULT_HANDLE;
     }
 
     private VerifyCredentialResponse spBasedDoVerifyCredential(LockscreenCredential userCredential,
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index b3eb531..ffa518e 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -586,7 +586,7 @@
 
     private final NetworkPolicyLogger mLogger = new NetworkPolicyLogger();
 
-    /** List of apps indexed by appId and whether they have the internet permission */
+    /** List of apps indexed by uid and whether they have the internet permission */
     @GuardedBy("mUidRulesFirstLock")
     private final SparseBooleanArray mInternetPermissionMap = new SparseBooleanArray();
 
@@ -972,7 +972,7 @@
                 if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid);
                 // Clear the cache for the app
                 synchronized (mUidRulesFirstLock) {
-                    mInternetPermissionMap.delete(UserHandle.getAppId(uid));
+                    mInternetPermissionMap.delete(uid);
                     updateRestrictionRulesForUidUL(uid);
                 }
             }
@@ -4194,16 +4194,14 @@
     @GuardedBy("mUidRulesFirstLock")
     private boolean hasInternetPermissionUL(int uid) {
         try {
-            final int appId = UserHandle.getAppId(uid);
-            final boolean hasPermission;
-            if (mInternetPermissionMap.indexOfKey(appId) < 0) {
-                hasPermission =
-                        mIPm.checkUidPermission(Manifest.permission.INTERNET, uid)
-                                == PackageManager.PERMISSION_GRANTED;
-                mInternetPermissionMap.put(appId, hasPermission);
-            } else {
-                hasPermission = mInternetPermissionMap.get(appId);
+            if (mInternetPermissionMap.get(uid)) {
+                return true;
             }
+            // If the cache shows that uid doesn't have internet permission,
+            // then always re-check with PackageManager just to be safe.
+            final boolean hasPermission = mIPm.checkUidPermission(Manifest.permission.INTERNET,
+                    uid) == PackageManager.PERMISSION_GRANTED;
+            mInternetPermissionMap.put(uid, hasPermission);
             return hasPermission;
         } catch (RemoteException e) {
         }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 5d0981d..81c72ef 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3056,6 +3056,8 @@
                         UserHandle.getUserId(uid), REASON_PACKAGE_BANNED, null);
             }
 
+            mAppOps.setMode(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg,
+                    enabled ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED);
             try {
                 getContext().sendBroadcastAsUser(
                         new Intent(ACTION_APP_BLOCK_STATE_CHANGED)
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index d42c7ea..c20a912 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3655,6 +3655,8 @@
         PackageParser.readConfigUseRoundIcon(mContext.getResources());
 
         mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L);
+
+        Slog.i(TAG, "Fix for b/169414761 is applied");
     }
 
     /**
diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
index 8eefd8f..a106dc6 100644
--- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java
+++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
@@ -115,7 +115,7 @@
     private static final String TAG = "UriGrantsManagerService";
     // Maximum number of persisted Uri grants a package is allowed
     private static final int MAX_PERSISTED_URI_GRANTS = 512;
-    private static final boolean ENABLE_DYNAMIC_PERMISSIONS = false;
+    private static final boolean ENABLE_DYNAMIC_PERMISSIONS = true;
 
     private final Object mLock = new Object();
     private final H mH;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 553aad1..946d797 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1496,6 +1496,15 @@
                 // intermediate orientation change, it is more stable to freeze the display.
                 return false;
             }
+            if (r.isState(RESUMED) && !r.getRootTask().mInResumeTopActivity) {
+                // If the activity is executing or has done the lifecycle callback, use normal
+                // rotation animation so the display info can be updated immediately (see
+                // updateDisplayAndOrientation). This prevents a compatibility issue such as
+                // calling setRequestedOrientation in Activity#onCreate and then get display info.
+                // If fixed rotation is applied, the display rotation will still be the old one,
+                // unless the client side gets the rotation again after the adjustments arrive.
+                return false;
+            }
         } else if (r != topRunningActivity()) {
             // If the transition has not started yet, the activity must be the top.
             return false;
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index c691a0e..515d1f5 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -2659,6 +2659,14 @@
         }
 
         win.computeFrame(displayFrames);
+
+        // When system bars are added to the Android device through {@link #layoutStatusBar} and
+        // {@link #layoutNavigationBar}, the displayFrames are adjusted to take the system bars into
+        // account. The call below adjusts the display frames for system bars which use flexible
+        // insets mapping instead of {@link #layoutStatusbar} and {@link #layoutNavigationBar}. Note
+        // that this call is a no-op if not using flexible insets mapping.
+        adjustDisplayFramesForFlexibleInsets(win, displayFrames);
+
         // Dock windows carve out the bottom of the screen, so normal windows
         // can't appear underneath them.
         if (type == TYPE_INPUT_METHOD && win.isVisibleLw()
@@ -2671,6 +2679,40 @@
         }
     }
 
+    private void adjustDisplayFramesForFlexibleInsets(WindowState win,
+            DisplayFrames displayFrames) {
+        if (win == mStatusBarAlt) {
+            adjustDisplayFramesForWindow(win, mStatusBarAltPosition, displayFrames);
+        } else if (win == mNavigationBarAlt) {
+            adjustDisplayFramesForWindow(win, mNavigationBarAltPosition, displayFrames);
+        } else if (win == mClimateBarAlt) {
+            adjustDisplayFramesForWindow(win, mClimateBarAltPosition, displayFrames);
+        } else if (win == mExtraNavBarAlt) {
+            adjustDisplayFramesForWindow(win, mExtraNavBarAltPosition, displayFrames);
+        }
+    }
+
+    private static void adjustDisplayFramesForWindow(WindowState win,
+            @WindowManagerPolicy.AltBarPosition int position, DisplayFrames displayFrames) {
+        final Rect frame = win.getFrameLw();
+
+        // Note: This doesn't take into account display cutouts.
+        switch (position) {
+            case ALT_BAR_TOP:
+                displayFrames.mStable.top = frame.bottom;
+                break;
+            case ALT_BAR_BOTTOM:
+                displayFrames.mStable.bottom = displayFrames.mStableFullscreen.bottom = frame.top;
+                break;
+            case ALT_BAR_LEFT:
+                displayFrames.mStable.left = displayFrames.mStableFullscreen.left = frame.right;
+                break;
+            case ALT_BAR_RIGHT:
+                displayFrames.mStable.right = displayFrames.mStableFullscreen.right = frame.left;
+                break;
+        }
+    }
+
     private void layoutWallpaper(DisplayFrames displayFrames, Rect pf, Rect df, Rect cf) {
         // The wallpaper has Real Ultimate Power
         df.set(displayFrames.mUnrestricted);
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index ba85199..2c2fdca 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -519,10 +519,24 @@
         LockscreenCredential password = newPassword("password");
         initializeCredentialUnderSP(password, PRIMARY_USER_ID);
         assertTrue(mService.setLockCredential(password, password, PRIMARY_USER_ID));
+        assertNoOrphanedFilesLeft(PRIMARY_USER_ID);
+    }
 
+    @Test
+    public void testAddingEscrowToken_NoOrphanedFilesLeft() throws Exception {
+        final byte[] token = "some-high-entropy-secure-token".getBytes();
+        for (int i = 0; i < 16; i++) {
+            long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null);
+            assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+            mLocalService.removeEscrowToken(handle, PRIMARY_USER_ID);
+        }
+        assertNoOrphanedFilesLeft(PRIMARY_USER_ID);
+    }
+
+    private void assertNoOrphanedFilesLeft(int userId) {
         String handleString = String.format("%016x",
-                mService.getSyntheticPasswordHandleLocked(PRIMARY_USER_ID));
-        File directory = mStorage.getSyntheticPasswordDirectoryForUser(PRIMARY_USER_ID);
+                mService.getSyntheticPasswordHandleLocked(userId));
+        File directory = mStorage.getSyntheticPasswordDirectoryForUser(userId);
         for (File file : directory.listFiles()) {
             String[] parts = file.getName().split("\\.");
             if (!parts[0].equals(handleString) && !parts[0].equals("0000000000000000")) {
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 c7a8bd8..1948003a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -1276,6 +1276,27 @@
     }
 
     @Test
+    public void testNoFixedRotationOnResumedScheduledApp() {
+        final ActivityRecord app = new ActivityTestsBase.StackBuilder(mWm.mRoot)
+                .setDisplay(mDisplayContent).build().getTopMostActivity();
+        app.setVisible(false);
+        app.setState(ActivityStack.ActivityState.RESUMED, "test");
+        mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_OPEN,
+                false /* alwaysKeepCurrent */);
+        mDisplayContent.mOpeningApps.add(app);
+        final int newOrientation = getRotatedOrientation(mDisplayContent);
+        app.setRequestedOrientation(newOrientation);
+
+        // The condition should reject using fixed rotation because the resumed client in real case
+        // might get display info immediately. And the fixed rotation adjustments haven't arrived
+        // client side so the info may be inconsistent with the requested orientation.
+        verify(mDisplayContent).handleTopActivityLaunchingInDifferentOrientation(eq(app),
+                eq(true) /* checkOpening */);
+        assertFalse(app.isFixedRotationTransforming());
+        assertFalse(mDisplayContent.hasTopFixedRotationLaunchingApp());
+    }
+
+    @Test
     public void testRecentsNotRotatingWithFixedRotation() {
         final DisplayRotation displayRotation = mDisplayContent.getDisplayRotation();
         doCallRealMethod().when(displayRotation).updateRotationUnchecked(anyBoolean());
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index cb9b49a..58d4104 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -45,6 +45,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
 import static android.view.WindowManagerPolicyConstants.ALT_BAR_BOTTOM;
 import static android.view.WindowManagerPolicyConstants.ALT_BAR_LEFT;
@@ -753,6 +754,51 @@
     }
 
     @Test
+    public void layoutWindowLw_withFlexibleSystemBars_adjustStableFrame() {
+        mDisplayPolicy.removeWindowLw(mStatusBarWindow);
+        mDisplayPolicy.removeWindowLw(mNavBarWindow);
+
+        WindowState statusWin = spy(createWindow(null, TYPE_STATUS_BAR_ADDITIONAL,
+                "StatusBarAdditional"));
+        doNothing().when(statusWin).computeFrameLw();
+        statusWin.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR};
+        statusWin.mAttrs.gravity = Gravity.TOP;
+        statusWin.mAttrs.height = STATUS_BAR_HEIGHT;
+        statusWin.mAttrs.width = MATCH_PARENT;
+        statusWin.getFrameLw().set(0, 0, DISPLAY_WIDTH, STATUS_BAR_HEIGHT);
+        addWindow(statusWin);
+
+        WindowState navWin = spy(createWindow(null, TYPE_NAVIGATION_BAR_PANEL,
+                "NavigationBarPanel"));
+        doNothing().when(navWin).computeFrameLw();
+        navWin.mAttrs.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR};
+        navWin.mAttrs.gravity = Gravity.BOTTOM;
+        navWin.mAttrs.height = NAV_BAR_HEIGHT;
+        navWin.mAttrs.width = MATCH_PARENT;
+        navWin.getFrameLw().set(0, DISPLAY_HEIGHT - NAV_BAR_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT);
+        addWindow(navWin);
+
+        WindowState climateWin = spy(createWindow(null, TYPE_NAVIGATION_BAR_PANEL,
+                "ClimatePanel"));
+        doNothing().when(climateWin).computeFrameLw();
+        climateWin.mAttrs.providesInsetsTypes = new int[]{ITYPE_CLIMATE_BAR};
+        climateWin.mAttrs.gravity = Gravity.LEFT;
+        climateWin.mAttrs.height = MATCH_PARENT;
+        climateWin.mAttrs.width = 20;
+        climateWin.getFrameLw().set(0, 0, 20, DISPLAY_HEIGHT);
+        addWindow(climateWin);
+
+        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        mDisplayPolicy.layoutWindowLw(statusWin, null, mFrames);
+        mDisplayPolicy.layoutWindowLw(navWin, null, mFrames);
+        mDisplayPolicy.layoutWindowLw(climateWin, null, mFrames);
+
+        assertThat(mFrames.mStable,
+                is(new Rect(20, STATUS_BAR_HEIGHT, DISPLAY_WIDTH,
+                        DISPLAY_HEIGHT - NAV_BAR_HEIGHT)));
+    }
+
+    @Test
     public void layoutHint_appWindow() {
         mWindow.mAttrs.flags =
                 FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;