Merge "Suppress startActivity warning for PipMenuActivity"
diff --git a/Android.bp b/Android.bp
index 7219ef5..7693a66 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1420,7 +1420,6 @@
     libs: [
         "ext",
         "framework",
-        "voip-common",
     ],
     local_sourcepaths: frameworks_base_subdirs,
     installable: false,
diff --git a/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java b/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java
index 1f12ae6..f0c474b 100644
--- a/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java
+++ b/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java
@@ -39,7 +39,6 @@
 import androidx.test.filters.LargeTest;
 import androidx.test.rule.ActivityTestRule;
 
-import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -51,9 +50,7 @@
 
 @RunWith(Parameterized.class)
 @LargeTest
-public class RelayoutPerfTest {
-    private static final IWindowSession sSession = WindowManagerGlobal.getWindowSession();
-
+public class RelayoutPerfTest extends WindowManagerPerfTestBase {
     private int mIteration;
 
     @Rule
@@ -85,12 +82,6 @@
         });
     }
 
-    @Before
-    public void setUp() {
-        getInstrumentation().getUiAutomation().executeShellCommand("input keyevent KEYCODE_WAKEUP");
-        getInstrumentation().getUiAutomation().executeShellCommand("wm dismiss-keyguard");
-    }
-
     @Test
     public void testRelayout() throws Throwable {
         final Activity activity = mActivityRule.getActivity();
@@ -154,8 +145,9 @@
         }
 
         void runBenchmark(BenchmarkState state) throws RemoteException {
+            final IWindowSession session = WindowManagerGlobal.getWindowSession();
             while (state.keepRunning()) {
-                sSession.relayout(mWindow, mSeq, mParams, mWidth, mHeight,
+                session.relayout(mWindow, mSeq, mParams, mWidth, mHeight,
                         mViewVisibility.getAsInt(), mFlags, mFrameNumber, mOutFrame,
                         mOutOverscanInsets, mOutContentInsets, mOutVisibleInsets, mOutStableInsets,
                         mOutOutsets, mOutBackDropFrame, mOutDisplayCutout, mOutMergedConfiguration,
diff --git a/apct-tests/perftests/core/src/android/wm/WindowAddRemovePerfTest.java b/apct-tests/perftests/core/src/android/wm/WindowAddRemovePerfTest.java
new file mode 100644
index 0000000..a951869
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/wm/WindowAddRemovePerfTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.wm;
+
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+
+import android.graphics.Rect;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.perftests.utils.ManualBenchmarkState;
+import android.perftests.utils.ManualBenchmarkState.ManualBenchmarkTest;
+import android.perftests.utils.PerfManualStatusReporter;
+import android.view.Display;
+import android.view.DisplayCutout;
+import android.view.IWindowSession;
+import android.view.InputChannel;
+import android.view.InsetsState;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+
+import androidx.test.filters.LargeTest;
+
+import com.android.internal.view.BaseIWindow;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+
+@LargeTest
+public class WindowAddRemovePerfTest extends WindowManagerPerfTestBase {
+    @Rule
+    public final PerfManualStatusReporter mPerfStatusReporter = new PerfManualStatusReporter();
+
+    @BeforeClass
+    public static void setUpClass() {
+        // Get the permission to use most window types.
+        sUiAutomation.adoptShellPermissionIdentity();
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+        sUiAutomation.dropShellPermissionIdentity();
+    }
+
+    @Test
+    @ManualBenchmarkTest(warmupDurationNs = WARMUP_DURATION, targetTestDurationNs = TEST_DURATION)
+    public void testAddRemoveWindow() throws Throwable {
+        new TestWindow().runBenchmark(mPerfStatusReporter.getBenchmarkState());
+    }
+
+    private static class TestWindow extends BaseIWindow {
+        final WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams();
+        final Rect mOutFrame = new Rect();
+        final Rect mOutContentInsets = new Rect();
+        final Rect mOutStableInsets = new Rect();
+        final Rect mOutOutsets = new Rect();
+        final DisplayCutout.ParcelableWrapper mOutDisplayCutout =
+                new DisplayCutout.ParcelableWrapper();
+        final InsetsState mOutInsetsState = new InsetsState();
+
+        TestWindow() {
+            mLayoutParams.setTitle(TestWindow.class.getName());
+            mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+            // Simulate as common phone window.
+            mLayoutParams.flags = FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
+        }
+
+        void runBenchmark(ManualBenchmarkState state) throws RemoteException {
+            final IWindowSession session = WindowManagerGlobal.getWindowSession();
+            long elapsedTimeNs = 0;
+            while (state.keepRunning(elapsedTimeNs)) {
+                // InputChannel cannot be reused.
+                final InputChannel inputChannel = new InputChannel();
+
+                long startTime = SystemClock.elapsedRealtimeNanos();
+                session.addToDisplay(this, mSeq, mLayoutParams, View.VISIBLE,
+                        Display.DEFAULT_DISPLAY, mOutFrame, mOutContentInsets, mOutStableInsets,
+                        mOutOutsets, mOutDisplayCutout, inputChannel, mOutInsetsState);
+                final long elapsedTimeNsOfAdd = SystemClock.elapsedRealtimeNanos() - startTime;
+                state.addExtraResult("add", elapsedTimeNsOfAdd);
+
+                startTime = SystemClock.elapsedRealtimeNanos();
+                session.remove(this);
+                final long elapsedTimeNsOfRemove = SystemClock.elapsedRealtimeNanos() - startTime;
+                state.addExtraResult("remove", elapsedTimeNsOfRemove);
+
+                elapsedTimeNs = elapsedTimeNsOfAdd + elapsedTimeNsOfRemove;
+            }
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/wm/WindowManagerPerfTestBase.java b/apct-tests/perftests/core/src/android/wm/WindowManagerPerfTestBase.java
new file mode 100644
index 0000000..b2c6168
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/wm/WindowManagerPerfTestBase.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.wm;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import android.app.UiAutomation;
+
+import org.junit.Before;
+
+public class WindowManagerPerfTestBase {
+    static final UiAutomation sUiAutomation = getInstrumentation().getUiAutomation();
+    static final long NANOS_PER_S = 1000L * 1000 * 1000;
+    static final long WARMUP_DURATION = 1 * NANOS_PER_S;
+    static final long TEST_DURATION = 5 * NANOS_PER_S;
+
+    @Before
+    public void setUp() {
+        // In order to be closer to the real use case.
+        sUiAutomation.executeShellCommand("input keyevent KEYCODE_WAKEUP");
+        sUiAutomation.executeShellCommand("wm dismiss-keyguard");
+    }
+}
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/ManualBenchmarkState.java b/apct-tests/perftests/utils/src/android/perftests/utils/ManualBenchmarkState.java
index 40778de..dd43ae7 100644
--- a/apct-tests/perftests/utils/src/android/perftests/utils/ManualBenchmarkState.java
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/ManualBenchmarkState.java
@@ -19,8 +19,13 @@
 import android.app.Activity;
 import android.app.Instrumentation;
 import android.os.Bundle;
+import android.util.ArrayMap;
 import android.util.Log;
 
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 import java.util.ArrayList;
 import java.util.concurrent.TimeUnit;
 
@@ -71,6 +76,8 @@
 
     private int mState = NOT_STARTED;  // Current benchmark state.
 
+    private long mWarmupDurationNs = WARMUP_DURATION_NS;
+    private long mTargetTestDurationNs = TARGET_TEST_DURATION_NS;
     private long mWarmupStartTime = 0;
     private int mWarmupIterations = 0;
 
@@ -79,12 +86,30 @@
     // Individual duration in nano seconds.
     private ArrayList<Long> mResults = new ArrayList<>();
 
+    /** @see #addExtraResult(String, long) */
+    private ArrayMap<String, ArrayList<Long>> mExtraResults;
+
     // Statistics. These values will be filled when the benchmark has finished.
     // The computation needs double precision, but long int is fine for final reporting.
     private Stats mStats;
 
+    void configure(ManualBenchmarkTest testAnnotation) {
+        if (testAnnotation == null) {
+            return;
+        }
+
+        final long warmupDurationNs = testAnnotation.warmupDurationNs();
+        if (warmupDurationNs >= 0) {
+            mWarmupDurationNs = warmupDurationNs;
+        }
+        final long targetTestDurationNs = testAnnotation.targetTestDurationNs();
+        if (targetTestDurationNs >= 0) {
+            mTargetTestDurationNs = targetTestDurationNs;
+        }
+    }
+
     private void beginBenchmark(long warmupDuration, int iterations) {
-        mMaxIterations = (int) (TARGET_TEST_DURATION_NS / (warmupDuration / iterations));
+        mMaxIterations = (int) (mTargetTestDurationNs / (warmupDuration / iterations));
         mMaxIterations = Math.min(MAX_TEST_ITERATIONS,
                 Math.max(mMaxIterations, MIN_TEST_ITERATIONS));
         mState = RUNNING;
@@ -108,7 +133,7 @@
                 final long timeSinceStartingWarmup = System.nanoTime() - mWarmupStartTime;
                 ++mWarmupIterations;
                 if (mWarmupIterations >= WARMUP_MIN_ITERATIONS
-                        && timeSinceStartingWarmup >= WARMUP_DURATION_NS) {
+                        && timeSinceStartingWarmup >= mWarmupDurationNs) {
                     beginBenchmark(timeSinceStartingWarmup, mWarmupIterations);
                 }
                 return true;
@@ -129,31 +154,69 @@
         }
     }
 
-    private String summaryLine() {
-        final StringBuilder sb = new StringBuilder();
-        sb.append("Summary: ");
-        sb.append("median=").append(mStats.getMedian()).append("ns, ");
-        sb.append("mean=").append(mStats.getMean()).append("ns, ");
-        sb.append("min=").append(mStats.getMin()).append("ns, ");
-        sb.append("max=").append(mStats.getMax()).append("ns, ");
-        sb.append("sigma=").append(mStats.getStandardDeviation()).append(", ");
-        sb.append("iteration=").append(mResults.size()).append(", ");
-        sb.append("values=").append(mResults.toString());
+    /**
+     * Adds additional result while this benchmark is running. It is used when a sequence of
+     * operations is executed consecutively, the duration of each operation can also be recorded.
+     */
+    public void addExtraResult(String key, long duration) {
+        if (mState != RUNNING) {
+            return;
+        }
+        if (mExtraResults == null) {
+            mExtraResults = new ArrayMap<>();
+        }
+        mExtraResults.computeIfAbsent(key, k -> new ArrayList<>()).add(duration);
+    }
+
+    private static String summaryLine(String key, Stats stats, ArrayList<Long> results) {
+        final StringBuilder sb = new StringBuilder(key);
+        sb.append(" Summary: ");
+        sb.append("median=").append(stats.getMedian()).append("ns, ");
+        sb.append("mean=").append(stats.getMean()).append("ns, ");
+        sb.append("min=").append(stats.getMin()).append("ns, ");
+        sb.append("max=").append(stats.getMax()).append("ns, ");
+        sb.append("sigma=").append(stats.getStandardDeviation()).append(", ");
+        sb.append("iteration=").append(results.size()).append(", ");
+        sb.append("values=");
+        if (results.size() > 100) {
+            sb.append(results.subList(0, 100)).append(" ...");
+        } else {
+            sb.append(results);
+        }
         return sb.toString();
     }
 
+    private static void fillStatus(Bundle status, String key, Stats stats) {
+        status.putLong(key + "_median", stats.getMedian());
+        status.putLong(key + "_mean", (long) stats.getMean());
+        status.putLong(key + "_percentile90", stats.getPercentile90());
+        status.putLong(key + "_percentile95", stats.getPercentile95());
+        status.putLong(key + "_stddev", (long) stats.getStandardDeviation());
+    }
+
     public void sendFullStatusReport(Instrumentation instrumentation, String key) {
         if (mState != FINISHED) {
             throw new IllegalStateException("The benchmark hasn't finished");
         }
-        Log.i(TAG, key + summaryLine());
+        Log.i(TAG, summaryLine(key, mStats, mResults));
         final Bundle status = new Bundle();
-        status.putLong(key + "_median", mStats.getMedian());
-        status.putLong(key + "_mean", (long) mStats.getMean());
-        status.putLong(key + "_percentile90", mStats.getPercentile90());
-        status.putLong(key + "_percentile95", mStats.getPercentile95());
-        status.putLong(key + "_stddev", (long) mStats.getStandardDeviation());
+        fillStatus(status, key, mStats);
+        if (mExtraResults != null) {
+            for (int i = 0; i < mExtraResults.size(); i++) {
+                final String subKey = key + "_" + mExtraResults.keyAt(i);
+                final Stats stats = new Stats(mExtraResults.valueAt(i));
+                Log.i(TAG, summaryLine(subKey, mStats, mResults));
+                fillStatus(status, subKey, stats);
+            }
+        }
         instrumentation.sendStatus(Activity.RESULT_OK, status);
     }
-}
 
+    /** The annotation to customize the test, e.g. the duration of warm-up and target test. */
+    @Target(ElementType.METHOD)
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface ManualBenchmarkTest {
+        long warmupDurationNs() default -1;
+        long targetTestDurationNs() default -1;
+    }
+}
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/PerfManualStatusReporter.java b/apct-tests/perftests/utils/src/android/perftests/utils/PerfManualStatusReporter.java
index 8187c6f..8ff6a16 100644
--- a/apct-tests/perftests/utils/src/android/perftests/utils/PerfManualStatusReporter.java
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/PerfManualStatusReporter.java
@@ -16,7 +16,7 @@
 
 package android.perftests.utils;
 
-import androidx.test.InstrumentationRegistry;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
@@ -59,15 +59,15 @@
 
     @Override
     public Statement apply(Statement base, Description description) {
+        mState.configure(description.getAnnotation(ManualBenchmarkState.ManualBenchmarkTest.class));
+
         return new Statement() {
             @Override
             public void evaluate() throws Throwable {
                 base.evaluate();
 
-                mState.sendFullStatusReport(InstrumentationRegistry.getInstrumentation(),
-                        description.getMethodName());
+                mState.sendFullStatusReport(getInstrumentation(), description.getMethodName());
             }
         };
     }
 }
-
diff --git a/api/current.txt b/api/current.txt
index 7c13dc1..0a8db46 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -13123,8 +13123,11 @@
     method @Nullable public android.database.sqlite.SQLiteDatabase.CursorFactory getCursorFactory();
     method @Nullable public java.util.Map<java.lang.String,java.lang.String> getProjectionMap();
     method @Nullable public String getTables();
+    method public long insert(@NonNull android.database.sqlite.SQLiteDatabase, @NonNull android.content.ContentValues);
     method public boolean isDistinct();
     method public boolean isStrict();
+    method public boolean isStrictColumns();
+    method public boolean isStrictGrammar();
     method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, String[], String, String[], String, String, String);
     method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, String[], String, String[], String, String, String, String);
     method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, String[], String, String[], String, String, String, String, android.os.CancellationSignal);
@@ -13132,6 +13135,8 @@
     method public void setDistinct(boolean);
     method public void setProjectionMap(@Nullable java.util.Map<java.lang.String,java.lang.String>);
     method public void setStrict(boolean);
+    method public void setStrictColumns(boolean);
+    method public void setStrictGrammar(boolean);
     method public void setTables(@Nullable String);
     method public int update(@NonNull android.database.sqlite.SQLiteDatabase, @NonNull android.content.ContentValues, @Nullable String, @Nullable String[]);
   }
@@ -41053,6 +41058,7 @@
     method public int getType();
     field public static final int TYPE_AUTHENTICATION_SELECTED = 2; // 0x2
     field public static final int TYPE_CONTEXT_COMMITTED = 4; // 0x4
+    field public static final int TYPE_DATASETS_SHOWN = 5; // 0x5
     field public static final int TYPE_DATASET_AUTHENTICATION_SELECTED = 1; // 0x1
     field public static final int TYPE_DATASET_SELECTED = 0; // 0x0
     field public static final int TYPE_SAVE_SHOWN = 3; // 0x3
@@ -52435,6 +52441,7 @@
     method public int getId();
     method public int getLayer();
     method public android.view.accessibility.AccessibilityWindowInfo getParent();
+    method public void getRegionInScreen(@NonNull android.graphics.Region);
     method public android.view.accessibility.AccessibilityNodeInfo getRoot();
     method @Nullable public CharSequence getTitle();
     method public int getType();
diff --git a/api/removed.txt b/api/removed.txt
index 7b1d241..b075f9e 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -73,10 +73,6 @@
 
 package android.content {
 
-  public class ClipData implements android.os.Parcelable {
-    method @Deprecated public void addItem(android.content.ClipData.Item, android.content.ContentResolver);
-  }
-
   public abstract class Context {
     method public abstract android.content.SharedPreferences getSharedPreferences(java.io.File, int);
     method public abstract java.io.File getSharedPreferencesPath(String);
diff --git a/api/system-current.txt b/api/system-current.txt
index 48804b6..eef6b3f 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5179,7 +5179,8 @@
     method @NonNull public static java.io.File getOdmDirectory();
     method @NonNull public static java.io.File getOemDirectory();
     method @NonNull public static java.io.File getProductDirectory();
-    method @NonNull public static java.io.File getProductServicesDirectory();
+    method @Deprecated @NonNull public static java.io.File getProductServicesDirectory();
+    method @NonNull public static java.io.File getSystemExtDirectory();
     method @NonNull public static java.io.File getVendorDirectory();
   }
 
diff --git a/api/test-current.txt b/api/test-current.txt
index 050ec52..b393fcc 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -54,6 +54,7 @@
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getPackageImportance(String);
     method public long getTotalRam();
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getUidImportance(int);
+    method public static boolean isHighEndGfx();
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener);
     method public static void resumeAppSwitches() throws android.os.RemoteException;
     method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public void scheduleApplicationInfoChanged(java.util.List<java.lang.String>, int);
@@ -696,6 +697,7 @@
     method public void setEnableRollback(boolean);
     method @RequiresPermission("android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS") public void setGrantedRuntimePermissions(String[]);
     method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setInstallAsApex();
+    method public void setRequestDowngrade(boolean);
     method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setStaged();
   }
 
@@ -3492,11 +3494,6 @@
     method public boolean isInputMethodPickerShown();
   }
 
-  public class InputMethodSystemProperty {
-    ctor public InputMethodSystemProperty();
-    field public static final boolean MULTI_CLIENT_IME_ENABLED;
-  }
-
 }
 
 package android.view.inspector {
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index 680ccfc..76b905d 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -64,6 +64,10 @@
 
     private static final String BMGR_NOT_RUNNING_ERR =
             "Error: Could not access the Backup Manager.  Is the system running?";
+    private static final String BMGR_NOT_ACTIVATED_FOR_USER =
+            "Error: Backup Manager is not activated for user ";
+    private static final String BMGR_ERR_NO_RESTORESESSION_FOR_USER =
+            "Error: Could not get restore session for user ";
     private static final String TRANSPORT_NOT_RUNNING_ERR =
             "Error: Could not access the backup transport.  Is the system running?";
     private static final String PM_NOT_RUNNING_ERR =
@@ -190,15 +194,19 @@
         showUsage();
     }
 
-    boolean isBackupActive(@UserIdInt int userId) {
+    private void handleRemoteException(RemoteException e) {
+        System.err.println(e.toString());
+        System.err.println(BMGR_NOT_RUNNING_ERR);
+    }
+
+    private boolean isBackupActive(@UserIdInt int userId) {
         try {
             if (!mBmgr.isBackupServiceActive(userId)) {
-                System.err.println(BMGR_NOT_RUNNING_ERR);
+                System.err.println(BMGR_NOT_ACTIVATED_FOR_USER + userId);
                 return false;
             }
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
             return false;
         }
 
@@ -214,8 +222,7 @@
             System.out.println("Backup Manager currently "
                     + activatedToString(mBmgr.isBackupServiceActive(userId)));
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
 
     }
@@ -230,8 +237,7 @@
             System.out.println("Backup Manager currently "
                     + enableToString(isEnabled));
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -250,8 +256,7 @@
             showUsage();
             return;
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -259,8 +264,7 @@
         try {
             mBmgr.backupNowForUser(userId);
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -274,8 +278,7 @@
         try {
             mBmgr.dataChangedForUser(userId, pkg);
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -292,8 +295,7 @@
                 mBmgr.fullTransportBackupForUser(
                         userId, allPkgs.toArray(new String[allPkgs.size()]));
             } catch (RemoteException e) {
-                System.err.println(e.toString());
-                System.err.println(BMGR_NOT_RUNNING_ERR);
+                handleRemoteException(e);
             }
         }
     }
@@ -421,8 +423,7 @@
             try {
                 filteredPackages = mBmgr.filterAppsEligibleForBackupForUser(userId, packages);
             } catch (RemoteException e) {
-                System.err.println(e.toString());
-                System.err.println(BMGR_NOT_RUNNING_ERR);
+                handleRemoteException(e);
             }
             backupNowPackages(userId, Arrays.asList(filteredPackages), nonIncrementalBackup,
                     monitorState);
@@ -455,8 +456,7 @@
                 System.err.println("Unable to run backup");
             }
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -506,8 +506,7 @@
             try {
                 mBmgr.cancelBackupsForUser(userId);
             } catch (RemoteException e) {
-                System.err.println(e.toString());
-                System.err.println(BMGR_NOT_RUNNING_ERR);
+                handleRemoteException(e);
             }
             return;
         }
@@ -537,8 +536,7 @@
             }
 
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -569,8 +567,7 @@
                         }
                     });
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
             return;
         }
 
@@ -598,8 +595,7 @@
             mBmgr.clearBackupDataForUser(userId, transport, pkg);
             System.out.println("Wiped backup data for " + pkg + " on " + transport);
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -632,8 +628,7 @@
             observer.waitForCompletion(30*1000L);
             System.out.println("Initialization result: " + observer.result);
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -648,7 +643,7 @@
         try {
             mRestore = mBmgr.beginRestoreSessionForUser(userId, null, null);
             if (mRestore == null) {
-                System.err.println(BMGR_NOT_RUNNING_ERR);
+                System.err.println(BMGR_ERR_NO_RESTORESESSION_FOR_USER + userId);
                 return;
             }
 
@@ -658,8 +653,7 @@
 
             mRestore.endRestoreSession();
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -686,8 +680,7 @@
                 System.out.println(pad + t);
             }
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -805,7 +798,7 @@
             boolean didRestore = false;
             mRestore = mBmgr.beginRestoreSessionForUser(userId, null, null);
             if (mRestore == null) {
-                System.err.println(BMGR_NOT_RUNNING_ERR);
+                System.err.println(BMGR_ERR_NO_RESTORESESSION_FOR_USER + userId);
                 return;
             }
             RestoreSet[] sets = null;
@@ -851,8 +844,7 @@
 
             System.out.println("done");
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -865,8 +857,7 @@
                 }
             }
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -886,8 +877,7 @@
                             + " for user "
                             + userId);
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
diff --git a/cmds/bootanimation/Android.bp b/cmds/bootanimation/Android.bp
index 31bd612..c1f8654 100644
--- a/cmds/bootanimation/Android.bp
+++ b/cmds/bootanimation/Android.bp
@@ -79,7 +79,6 @@
         "libEGL",
         "libGLESv1_CM",
         "libgui",
-        "libtinyalsa",
     ],
 
     product_variables: {
diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp
index cfac5f3..0b349e1 100644
--- a/cmds/idmap2/idmap2/Scan.cpp
+++ b/cmds/idmap2/idmap2/Scan.cpp
@@ -103,6 +103,7 @@
       {"/oem/", kPolicyOem},
       {"/product/", kPolicyProduct},
       {"/system/", kPolicySystem},
+      {"/system_ext/", kPolicySystem},
       {"/vendor/", kPolicyVendor},
   };
 
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 2f0dc3c..6df0a8e 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -71,7 +71,6 @@
         "src/config/ConfigManager.cpp",
         "src/external/GpuStatsPuller.cpp",
         "src/external/Perfetto.cpp",
-        "src/external/Perfprofd.cpp",
         "src/external/StatsPuller.cpp",
         "src/external/StatsCallbackPuller.cpp",
         "src/external/StatsCompanionServicePuller.cpp",
@@ -109,8 +108,6 @@
         "src/socket/StatsSocketListener.cpp",
         "src/shell/ShellSubscriber.cpp",
         "src/shell/shell_config.proto",
-
-        ":perfprofd_aidl",
     ],
 
     local_include_dirs: [
diff --git a/cmds/statsd/src/anomaly/subscriber_util.cpp b/cmds/statsd/src/anomaly/subscriber_util.cpp
index 548a686..e09d575 100644
--- a/cmds/statsd/src/anomaly/subscriber_util.cpp
+++ b/cmds/statsd/src/anomaly/subscriber_util.cpp
@@ -22,7 +22,6 @@
 #include <binder/IServiceManager.h>
 
 #include "external/Perfetto.h"
-#include "external/Perfprofd.h"
 #include "subscriber/IncidentdReporter.h"
 #include "subscriber/SubscriberReporter.h"
 
@@ -64,12 +63,6 @@
                 SubscriberReporter::getInstance().alertBroadcastSubscriber(configKey, subscription,
                                                                            dimensionKey);
                 break;
-            case Subscription::SubscriberInformationCase::kPerfprofdDetails:
-                if (!CollectPerfprofdTraceAndUploadToDropbox(subscription.perfprofd_details(),
-                                                             ruleId, configKey)) {
-                    ALOGW("Failed to generate perfprofd traces.");
-                }
-                break;
             default:
                 break;
         }
diff --git a/cmds/statsd/src/external/Perfprofd.cpp b/cmds/statsd/src/external/Perfprofd.cpp
deleted file mode 100644
index 1678f10..0000000
--- a/cmds/statsd/src/external/Perfprofd.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#include "Perfprofd.h"
-
-#define DEBUG false  // STOPSHIP if true
-#include "config/ConfigKey.h"
-#include "Log.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <string>
-
-#include <binder/IServiceManager.h>
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"  // Alert
-
-#include "android/os/IPerfProfd.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-bool CollectPerfprofdTraceAndUploadToDropbox(const PerfprofdDetails& config,
-                                             int64_t alert_id,
-                                             const ConfigKey& configKey) {
-    VLOG("Starting trace collection through perfprofd");
-
-    if (!config.has_perfprofd_config()) {
-      ALOGE("The perfprofd trace config is empty, aborting");
-      return false;
-    }
-
-    sp<IPerfProfd> service = interface_cast<IPerfProfd>(
-        defaultServiceManager()->getService(android::String16("perfprofd")));
-    if (service == NULL) {
-      ALOGE("Could not find perfprofd service");
-      return false;
-    }
-
-    auto* data = reinterpret_cast<const uint8_t*>(config.perfprofd_config().data());
-    std::vector<uint8_t> proto_serialized(data, data + config.perfprofd_config().size());
-
-    // TODO: alert-id etc?
-
-    binder::Status status = service->startProfilingProtobuf(proto_serialized);
-    if (status.isOk()) {
-      return true;
-    }
-
-    ALOGE("Error starting perfprofd profiling: %s", status.toString8().c_str());
-    return false;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/Perfprofd.h b/cmds/statsd/src/external/Perfprofd.h
deleted file mode 100644
index b93fdf8..0000000
--- a/cmds/statsd/src/external/Perfprofd.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#pragma once
-
-#include <inttypes.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class ConfigKey;
-class PerfprofdDetails;  // Declared in statsd_config.pb.h
-
-// Starts the collection of a Perfprofd trace with the given |config|.
-// The trace is uploaded to Dropbox by the perfprofd service once done.
-// This method returns immediately after passing the config and does NOT wait
-// for the full duration of the trace.
-bool CollectPerfprofdTraceAndUploadToDropbox(const PerfprofdDetails& config,
-                                             int64_t alert_id,
-                                             const ConfigKey& configKey);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index a2fd9d4..79c06b9 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -343,15 +343,6 @@
   optional bytes trace_config = 1;
 }
 
-message PerfprofdDetails {
-  // The |perfprofd_config| field is a proto-encoded message of type
-  // android.perfprofd.ProfilingConfig defined in
-  // //system/extras/perfprofd/. On device, statsd doesn't need to
-  // deserialize the message as it's just passed binary-encoded to
-  // the perfprofd service.
-  optional bytes perfprofd_config = 1;
-}
-
 message BroadcastSubscriberDetails {
   optional int64 subscriber_id = 1;
   repeated string cookie = 2;
@@ -373,10 +364,12 @@
     IncidentdDetails incidentd_details = 4;
     PerfettoDetails perfetto_details = 5;
     BroadcastSubscriberDetails broadcast_subscriber_details = 6;
-    PerfprofdDetails perfprofd_details = 8;
   }
 
   optional float probability_of_informing = 7 [default = 1.1];
+
+  // This was used for perfprofd historically.
+  reserved 8;
 }
 
 enum ActivationType {
diff --git a/config/preloaded-classes b/config/preloaded-classes
index b4fd031..03e3b82 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -2696,6 +2696,7 @@
 android.os.-$$Lambda$Trace$2zLZ-Lc2kAXsVjw_nLYeNhqmGq0
 android.os.-$$Lambda$q1UvBdLgHRZVzc68BxdksTmbuCw
 android.os.AsyncResult
+android.os.AsyncTask
 android.os.AsyncTask$1
 android.os.AsyncTask$2
 android.os.AsyncTask$3
diff --git a/config/preloaded-classes-blacklist b/config/preloaded-classes-blacklist
index b5f9950..f05edee 100644
--- a/config/preloaded-classes-blacklist
+++ b/config/preloaded-classes-blacklist
@@ -1,6 +1,5 @@
 android.content.AsyncTaskLoader$LoadTask
 android.net.ConnectivityThread$Singleton
-android.os.AsyncTask
 android.os.FileObserver
 android.speech.tts.TextToSpeech$Connection$SetupConnectionAsyncTask
 android.widget.Magnifier
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index cebe6e12..4aafa53 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -644,6 +644,32 @@
         }
     }
 
+    @Override
+    public Context createDisplayContext(Display display) {
+        final Context context = super.createDisplayContext(display);
+        final int displayId = display.getDisplayId();
+        setDefaultTokenInternal(context, displayId);
+        return context;
+    }
+
+    private void setDefaultTokenInternal(Context context, int displayId) {
+        final WindowManagerImpl wm = (WindowManagerImpl) context.getSystemService(WINDOW_SERVICE);
+        final IAccessibilityServiceConnection connection =
+                AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
+        IBinder token = null;
+        if (connection != null) {
+            synchronized (mLock) {
+                try {
+                    token = connection.getOverlayWindowToken(displayId);
+                } catch (RemoteException re) {
+                    Log.w(LOG_TAG, "Failed to get window token", re);
+                    re.rethrowFromSystemServer();
+                }
+            }
+            wm.setDefaultToken(token);
+        }
+    }
+
     /**
      * Returns the magnification controller, which may be used to query and
      * modify the state of display magnification.
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 8c38fe4..c8e0132 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -96,4 +96,6 @@
     void sendGesture(int sequence, in ParceledListSlice gestureSteps);
 
     boolean isFingerprintGestureDetectionAvailable();
+
+    IBinder getOverlayWindowToken(int displayid);
 }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 17368b7..cb99a3a 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -925,7 +925,7 @@
      * (which tends to consume a lot more RAM).
      * @hide
      */
-    @UnsupportedAppUsage
+    @TestApi
     static public boolean isHighEndGfx() {
         return !isLowRamDeviceStatic()
                 && !RoSystemProperties.CONFIG_AVOID_GFX_ACCEL
@@ -1822,7 +1822,8 @@
      * @hide
      */
     public static class TaskSnapshot implements Parcelable {
-
+        // Identifier of this snapshot
+        private final long mId;
         // Top activity in task when snapshot was taken
         private final ComponentName mTopActivityComponent;
         private final GraphicBuffer mSnapshot;
@@ -1841,10 +1842,12 @@
         // Must be one of the named color spaces, otherwise, always use SRGB color space.
         private final ColorSpace mColorSpace;
 
-        public TaskSnapshot(@NonNull ComponentName topActivityComponent, GraphicBuffer snapshot,
+        public TaskSnapshot(long id,
+                @NonNull ComponentName topActivityComponent, GraphicBuffer snapshot,
                 @NonNull ColorSpace colorSpace, int orientation, Rect contentInsets,
                 boolean reducedResolution, float scale, boolean isRealSnapshot, int windowingMode,
                 int systemUiVisibility, boolean isTranslucent) {
+            mId = id;
             mTopActivityComponent = topActivityComponent;
             mSnapshot = snapshot;
             mColorSpace = colorSpace.getId() < 0
@@ -1860,6 +1863,7 @@
         }
 
         private TaskSnapshot(Parcel source) {
+            mId = source.readLong();
             mTopActivityComponent = ComponentName.readFromParcel(source);
             mSnapshot = source.readParcelable(null /* classLoader */);
             int colorSpaceId = source.readInt();
@@ -1877,6 +1881,13 @@
         }
 
         /**
+         * @return Identifier of this snapshot.
+         */
+        public long getId() {
+            return mId;
+        }
+
+        /**
          * @return The top activity component for the task at the point this snapshot was taken.
          */
         public ComponentName getTopActivityComponent() {
@@ -1970,6 +1981,7 @@
 
         @Override
         public void writeToParcel(Parcel dest, int flags) {
+            dest.writeLong(mId);
             ComponentName.writeToParcel(mTopActivityComponent, dest);
             dest.writeParcelable(mSnapshot, 0);
             dest.writeInt(mColorSpace.getId());
@@ -1988,6 +2000,7 @@
             final int width = mSnapshot != null ? mSnapshot.getWidth() : 0;
             final int height = mSnapshot != null ? mSnapshot.getHeight() : 0;
             return "TaskSnapshot{"
+                    + " mId=" + mId
                     + " mTopActivityComponent=" + mTopActivityComponent.flattenToShortString()
                     + " mSnapshot=" + mSnapshot + " (" + width + "x" + height + ")"
                     + " mColorSpace=" + mColorSpace.toString()
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index f8e6ae5..69e7118 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -26,6 +26,7 @@
 import android.content.pm.ActivityPresentationInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.UserInfo;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.TransactionTooLargeException;
@@ -52,6 +53,12 @@
      */
     public abstract String checkContentProviderAccess(String authority, int userId);
 
+    /**
+     * Verify that calling UID has access to the given provider.
+     */
+    public abstract int checkContentProviderUriPermission(Uri uri, int userId,
+            int callingUid, int modeFlags);
+
     // Called by the power manager.
     public abstract void onWakefulnessChanged(int wakefulness);
 
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index d741b61..2b4d4f8b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -791,6 +791,8 @@
         @Nullable
         ContentCaptureOptions contentCaptureOptions;
 
+        long[] disabledCompatChanges;
+
         @Override
         public String toString() {
             return "AppBindData{appInfo=" + appInfo + "}";
@@ -1003,7 +1005,7 @@
                 boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                 CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
                 String buildSerial, AutofillOptions autofillOptions,
-                ContentCaptureOptions contentCaptureOptions) {
+                ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges) {
             if (services != null) {
                 if (false) {
                     // Test code to make sure the app could see the passed-in services.
@@ -1051,6 +1053,7 @@
             data.buildSerial = buildSerial;
             data.autofillOptions = autofillOptions;
             data.contentCaptureOptions = contentCaptureOptions;
+            data.disabledCompatChanges = disabledCompatChanges;
             sendMessage(H.BIND_APPLICATION, data);
         }
 
@@ -6144,10 +6147,10 @@
         if (data.trackAllocation) {
             DdmVmInternal.enableRecentAllocations(true);
         }
-
         // Note when this process has started.
         Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
 
+        AppCompatCallbacks.install(data.disabledCompatChanges);
         mBoundApplication = data;
         mConfiguration = new Configuration(data.config);
         mCompatConfiguration = new Configuration(data.config);
diff --git a/core/java/android/app/AppCompatCallbacks.java b/core/java/android/app/AppCompatCallbacks.java
new file mode 100644
index 0000000..17697db
--- /dev/null
+++ b/core/java/android/app/AppCompatCallbacks.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.compat.Compatibility;
+import android.os.Process;
+import android.util.Log;
+
+import java.util.Arrays;
+
+/**
+ * App process implementation of the {@link Compatibility} API.
+ *
+ * @hide
+ */
+public final class AppCompatCallbacks extends Compatibility.Callbacks {
+
+    private static final String TAG = "Compatibility";
+
+    private final long[] mDisabledChanges;
+
+    /**
+     * Install this class into the current process.
+     *
+     * @param disabledChanges Set of compatibility changes that are disabled for this process.
+     */
+    public static void install(long[] disabledChanges) {
+        Compatibility.setCallbacks(new AppCompatCallbacks(disabledChanges));
+    }
+
+    private AppCompatCallbacks(long[] disabledChanges) {
+        mDisabledChanges = Arrays.copyOf(disabledChanges, disabledChanges.length);
+        Arrays.sort(mDisabledChanges);
+    }
+
+    protected void reportChange(long changeId) {
+        Log.d(TAG, "Compat change reported: " + changeId + "; UID " + Process.myUid());
+        // TODO log via StatsLog
+    }
+
+    protected boolean isChangeEnabled(long changeId) {
+        if (Arrays.binarySearch(mDisabledChanges, changeId) < 0) {
+            // Not present in the disabled array
+            reportChange(changeId);
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 416aaa3..0478ac8 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -635,7 +635,7 @@
     @Override
     public boolean isPermissionRevokedByPolicy(String permName, String pkgName) {
         try {
-            return mPM.isPermissionRevokedByPolicy(permName, pkgName, getUserId());
+            return mPermissionManager.isPermissionRevokedByPolicy(permName, pkgName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -795,10 +795,11 @@
 
     @Override
     @UnsupportedAppUsage
-    public boolean shouldShowRequestPermissionRationale(String permission) {
+    public boolean shouldShowRequestPermissionRationale(String permName) {
         try {
-            return mPM.shouldShowRequestPermissionRationale(permission,
-                    mContext.getPackageName(), getUserId());
+            final String packageName = mContext.getPackageName();
+            return mPermissionManager
+                    .shouldShowRequestPermissionRationale(permName, packageName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2049,7 +2050,7 @@
     @Override
     public String getDefaultBrowserPackageNameAsUser(int userId) {
         try {
-            return mPM.getDefaultBrowserPackageName(userId);
+            return mPermissionManager.getDefaultBrowser(userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2058,7 +2059,7 @@
     @Override
     public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
         try {
-            return mPM.setDefaultBrowserPackageName(packageName, userId);
+            return mPermissionManager.setDefaultBrowser(packageName, userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index 66c4383..cfa065b 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -73,7 +73,7 @@
             boolean restrictedBackupMode, boolean persistent, in Configuration config,
             in CompatibilityInfo compatInfo, in Map services,
             in Bundle coreSettings, in String buildSerial, in AutofillOptions autofillOptions,
-            in ContentCaptureOptions contentCaptureOptions);
+            in ContentCaptureOptions contentCaptureOptions, in long[] disabledCompatChanges);
     void runIsolatedEntryPoint(in String entryPoint, in String[] entryPointArgs);
     void scheduleExit();
     void scheduleServiceArgs(IBinder token, in ParceledListSlice args);
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index 88e2c22..fdef2a1 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -892,12 +892,6 @@
         mItems.add(item);
     }
 
-    /** @removed use #addItem(ContentResolver, Item) instead */
-    @Deprecated
-    public void addItem(Item item, ContentResolver resolver) {
-        addItem(resolver, item);
-    }
-
     /**
      * Add a new Item to the overall ClipData container.
      * <p> Unlike {@link #addItem(Item)}, this method will update the list of available MIME types
diff --git a/core/java/android/content/ContentInterface.java b/core/java/android/content/ContentInterface.java
index d41d8d9..197de97 100644
--- a/core/java/android/content/ContentInterface.java
+++ b/core/java/android/content/ContentInterface.java
@@ -56,6 +56,9 @@
     public boolean refresh(@NonNull Uri uri, @Nullable Bundle args,
             @Nullable CancellationSignal cancellationSignal) throws RemoteException;
 
+    public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags)
+            throws RemoteException;
+
     public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues initialValues)
             throws RemoteException;
 
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 7cdd268..3c79991 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -28,6 +28,7 @@
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.app.AppOpsManager;
+import android.content.pm.PackageManager;
 import android.content.pm.PathPermission;
 import android.content.pm.ProviderInfo;
 import android.content.res.AssetFileDescriptor;
@@ -582,6 +583,22 @@
             }
         }
 
+        @Override
+        public int checkUriPermission(String callingPkg, Uri uri, int uid, int modeFlags) {
+            uri = validateIncomingUri(uri);
+            uri = maybeGetUriWithoutUserId(uri);
+            Trace.traceBegin(TRACE_TAG_DATABASE, "checkUriPermission");
+            final String original = setCallingPackage(callingPkg);
+            try {
+                return mInterface.checkUriPermission(uri, uid, modeFlags);
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            } finally {
+                setCallingPackage(original);
+                Trace.traceEnd(TRACE_TAG_DATABASE);
+            }
+        }
+
         private void enforceFilePermission(String callingPkg, Uri uri, String mode,
                 IBinder callerToken) throws FileNotFoundException, SecurityException {
             if (mode != null && mode.indexOf('w') != -1) {
@@ -1416,6 +1433,12 @@
         return false;
     }
 
+    /** {@hide} */
+    @Override
+    public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags) {
+        return PackageManager.PERMISSION_DENIED;
+    }
+
     /**
      * @hide
      * Implementation when a caller has performed an insert on the content
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index 93bf518..8a4330e 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -307,6 +307,25 @@
         }
     }
 
+    /** {@hide} */
+    @Override
+    public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags)
+            throws RemoteException {
+        Preconditions.checkNotNull(uri, "uri");
+
+        beforeRemote();
+        try {
+            return mContentProvider.checkUriPermission(mPackageName, uri, uid, modeFlags);
+        } catch (DeadObjectException e) {
+            if (!mStable) {
+                mContentResolver.unstableProviderDied(mContentProvider);
+            }
+            throw e;
+        } finally {
+            afterRemote();
+        }
+    }
+
     /** See {@link ContentProvider#insert ContentProvider.insert} */
     @Override
     public @Nullable Uri insert(@NonNull Uri url, @Nullable ContentValues initialValues)
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index 9948338..cd735d4 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -363,6 +363,19 @@
                     reply.writeInt(out ? 0 : -1);
                     return true;
                 }
+
+                case CHECK_URI_PERMISSION_TRANSACTION: {
+                    data.enforceInterface(IContentProvider.descriptor);
+                    String callingPkg = data.readString();
+                    Uri uri = Uri.CREATOR.createFromParcel(data);
+                    int uid = data.readInt();
+                    int modeFlags = data.readInt();
+
+                    int out = checkUriPermission(callingPkg, uri, uid, modeFlags);
+                    reply.writeNoException();
+                    reply.writeInt(out);
+                    return true;
+                }
             }
         } catch (Exception e) {
             DatabaseUtils.writeExceptionToParcel(reply, e);
@@ -800,6 +813,29 @@
         }
     }
 
+    @Override
+    public int checkUriPermission(String callingPkg, Uri url, int uid, int modeFlags)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        try {
+            data.writeInterfaceToken(IContentProvider.descriptor);
+
+            data.writeString(callingPkg);
+            url.writeToParcel(data, 0);
+            data.writeInt(uid);
+            data.writeInt(modeFlags);
+
+            mRemote.transact(IContentProvider.CHECK_URI_PERMISSION_TRANSACTION, data, reply, 0);
+
+            DatabaseUtils.readExceptionFromParcel(reply);
+            return reply.readInt();
+        } finally {
+            data.recycle();
+            reply.recycle();
+        }
+    }
+
     @UnsupportedAppUsage
     private IBinder mRemote;
 }
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 0a1bc85..9c86359 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -31,6 +31,7 @@
 import android.app.ActivityThread;
 import android.app.AppGlobals;
 import android.app.UriGrantsManager;
+import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
@@ -1146,6 +1147,24 @@
         }
     }
 
+    /** {@hide} */
+    @Override
+    public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags) {
+        Preconditions.checkNotNull(uri, "uri");
+
+        try {
+            if (mWrapped != null) return mWrapped.checkUriPermission(uri, uid, modeFlags);
+        } catch (RemoteException e) {
+            return PackageManager.PERMISSION_DENIED;
+        }
+
+        try (ContentProviderClient client = acquireUnstableContentProviderClient(uri)) {
+            return client.checkUriPermission(uri, uid, modeFlags);
+        } catch (RemoteException e) {
+            return PackageManager.PERMISSION_DENIED;
+        }
+    }
+
     /**
      * Open a stream on to the content associated with a content URI.  If there
      * is no data associated with the URI, FileNotFoundException is thrown.
diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java
index 0427c2f..fade0ab 100644
--- a/core/java/android/content/IContentProvider.java
+++ b/core/java/android/content/IContentProvider.java
@@ -16,6 +16,7 @@
 
 package android.content;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.content.res.AssetFileDescriptor;
@@ -82,6 +83,9 @@
     public Bundle call(String callingPkg, String authority, String method,
             @Nullable String arg, @Nullable Bundle extras) throws RemoteException;
 
+    public int checkUriPermission(String callingPkg, Uri uri, int uid, int modeFlags)
+            throws RemoteException;
+
     public ICancellationSignal createCancellationSignal() throws RemoteException;
 
     public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException;
@@ -116,4 +120,5 @@
     static final int CANONICALIZE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 24;
     static final int UNCANONICALIZE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 25;
     static final int REFRESH_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 26;
+    static final int CHECK_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 27;
 }
diff --git a/core/java/android/content/LoggingContentInterface.java b/core/java/android/content/LoggingContentInterface.java
index 83c0c91..1df1c4f 100644
--- a/core/java/android/content/LoggingContentInterface.java
+++ b/core/java/android/content/LoggingContentInterface.java
@@ -165,6 +165,19 @@
     }
 
     @Override
+    public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags)
+            throws RemoteException {
+        try (Logger l = new Logger("checkUriPermission", uri, uid, modeFlags)) {
+            try {
+                return l.setResult(delegate.checkUriPermission(uri, uid, modeFlags));
+            } catch (Exception res) {
+                l.setResult(res);
+                throw res;
+            }
+        }
+    }
+
+    @Override
     public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues initialValues)
             throws RemoteException {
         try (Logger l = new Logger("insert", uri, initialValues)) {
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index f75cd23..d0a61eb 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -614,10 +614,10 @@
 
     /**
      * Value for {@link #privateFlags}: whether this app is pre-installed on the
-     * google partition of the system image.
+     * system_ext partition of the system image.
      * @hide
      */
-    public static final int PRIVATE_FLAG_PRODUCT_SERVICES = 1 << 21;
+    public static final int PRIVATE_FLAG_SYSTEM_EXT = 1 << 21;
 
     /**
      * Indicates whether this package requires access to non-SDK APIs.
@@ -713,7 +713,7 @@
             PRIVATE_FLAG_USE_EMBEDDED_DEX,
             PRIVATE_FLAG_PRIVILEGED,
             PRIVATE_FLAG_PRODUCT,
-            PRIVATE_FLAG_PRODUCT_SERVICES,
+            PRIVATE_FLAG_SYSTEM_EXT,
             PRIVATE_FLAG_PROFILEABLE_BY_SHELL,
             PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER,
             PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY,
@@ -2046,8 +2046,8 @@
     }
 
     /** @hide */
-    public boolean isProductServices() {
-        return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0;
+    public boolean isSystemExt() {
+        return (privateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0;
     }
 
     /** @hide */
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 904bd16..c6beee2 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -94,8 +94,6 @@
 
     @UnsupportedAppUsage
     ProviderInfo getProviderInfo(in ComponentName className, int flags, int userId);
-    boolean shouldShowRequestPermissionRationale(String permName,
-            String packageName, int userId);
 
     boolean isProtectedBroadcast(String actionName);
 
@@ -594,18 +592,12 @@
     ParceledListSlice getIntentFilterVerifications(String packageName);
     ParceledListSlice getAllIntentFilters(String packageName);
 
-    boolean setDefaultBrowserPackageName(String packageName, int userId);
-    String getDefaultBrowserPackageName(int userId);
-
     VerifierDeviceIdentity getVerifierDeviceIdentity();
 
     boolean isFirstBoot();
     boolean isOnlyCoreApps();
     boolean isDeviceUpgrading();
 
-    void setPermissionEnforced(String permission, boolean enforced);
-    boolean isPermissionEnforced(String permission);
-
     /** Reflects current DeviceStorageMonitorService state */
     @UnsupportedAppUsage
     boolean isStorageLow();
@@ -629,17 +621,6 @@
     boolean isPackageSignedByKeySet(String packageName, in KeySet ks);
     boolean isPackageSignedByKeySetExactly(String packageName, in KeySet ks);
 
-    void grantDefaultPermissionsToEnabledCarrierApps(in String[] packageNames, int userId);
-    void grantDefaultPermissionsToEnabledImsServices(in String[] packageNames, int userId);
-    void grantDefaultPermissionsToEnabledTelephonyDataServices(
-            in String[] packageNames, int userId);
-    void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
-            in String[] packageNames, int userId);
-    void grantDefaultPermissionsToActiveLuiApp(in String packageName, int userId);
-    void revokeDefaultPermissionsFromLuiApps(in String[] packageNames, int userId);
-
-    boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId);
-
     @UnsupportedAppUsage
     String getPermissionControllerPackageName();
 
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 3cecd7f..1099d8b 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1565,7 +1565,7 @@
         }
 
         /** {@hide} */
-        @SystemApi
+        @SystemApi @TestApi
         public void setRequestDowngrade(boolean requestDowngrade) {
             if (requestDowngrade) {
                 installFlags |= PackageManager.INSTALL_REQUEST_DOWNGRADE;
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index b845a37..4d8a0c4 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3571,7 +3571,7 @@
     /**
      * Retrieve all of the information we know about a particular permission.
      *
-     * @param permissionName The fully qualified name (i.e. com.google.permission.LOGIN)
+     * @param permName The fully qualified name (i.e. com.google.permission.LOGIN)
      *            of the permission you are interested in.
      * @param flags Additional option flags to modify the data returned.
      * @return Returns a {@link PermissionInfo} containing information about the
@@ -3579,7 +3579,7 @@
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
      */
-    public abstract PermissionInfo getPermissionInfo(@NonNull String permissionName,
+    public abstract PermissionInfo getPermissionInfo(@NonNull String permName,
             @PermissionInfoFlags int flags) throws NameNotFoundException;
 
     /**
@@ -3620,7 +3620,7 @@
      * Retrieve all of the information we know about a particular group of
      * permissions.
      *
-     * @param permissionName The fully qualified name (i.e.
+     * @param permName The fully qualified name (i.e.
      *            com.google.permission_group.APPS) of the permission you are
      *            interested in.
      * @param flags Additional option flags to modify the data returned.
@@ -3630,7 +3630,7 @@
      *             found on the system.
      */
     @NonNull
-    public abstract PermissionGroupInfo getPermissionGroupInfo(@NonNull String permissionName,
+    public abstract PermissionGroupInfo getPermissionGroupInfo(@NonNull String permName,
             @PermissionGroupInfoFlags int flags) throws NameNotFoundException;
 
     /**
@@ -3858,7 +3858,7 @@
      * Check whether a particular package has been granted a particular
      * permission.
      *
-     * @param permissionName The name of the permission you are checking for.
+     * @param permName The name of the permission you are checking for.
      * @param packageName The name of the package you are checking against.
      *
      * @return If the package has the permission, PERMISSION_GRANTED is
@@ -3870,7 +3870,7 @@
      */
     @CheckResult
     @PermissionResult
-    public abstract int checkPermission(@NonNull String permissionName,
+    public abstract int checkPermission(@NonNull String permName,
             @NonNull String packageName);
 
     /**
@@ -3880,13 +3880,13 @@
      * permissions, hence the only way for an app to get such a permission
      * is by a policy change.
      *
-     * @param permissionName The name of the permission you are checking for.
+     * @param permName The name of the permission you are checking for.
      * @param packageName The name of the package you are checking against.
      *
      * @return Whether the permission is restricted by policy.
      */
     @CheckResult
-    public abstract boolean isPermissionRevokedByPolicy(@NonNull String permissionName,
+    public abstract boolean isPermissionRevokedByPolicy(@NonNull String permName,
             @NonNull String packageName);
 
     /**
@@ -3949,14 +3949,14 @@
      * -- you are only allowed to remove permissions that you are allowed
      * to add.
      *
-     * @param permissionName The name of the permission to remove.
+     * @param permName The name of the permission to remove.
      *
      * @throws SecurityException if you are not allowed to remove the
      * given permission name.
      *
      * @see #addPermission(PermissionInfo)
      */
-    public abstract void removePermission(@NonNull String permissionName);
+    public abstract void removePermission(@NonNull String permName);
 
     /**
      * Permission flags set when granting or revoking a permission.
@@ -3998,7 +3998,7 @@
      * </p>
      *
      * @param packageName The package to which to grant the permission.
-     * @param permissionName The permission name to grant.
+     * @param permName The permission name to grant.
      * @param user The user for which to grant the permission.
      *
      * @see #revokeRuntimePermission(String, String, android.os.UserHandle)
@@ -4009,7 +4009,7 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
     public abstract void grantRuntimePermission(@NonNull String packageName,
-            @NonNull String permissionName, @NonNull UserHandle user);
+            @NonNull String permName, @NonNull UserHandle user);
 
     /**
      * Revoke a runtime permission that was previously granted by {@link
@@ -4025,7 +4025,7 @@
      * </p>
      *
      * @param packageName The package from which to revoke the permission.
-     * @param permissionName The permission name to revoke.
+     * @param permName The permission name to revoke.
      * @param user The user for which to revoke the permission.
      *
      * @see #grantRuntimePermission(String, String, android.os.UserHandle)
@@ -4036,12 +4036,12 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
     public abstract void revokeRuntimePermission(@NonNull String packageName,
-            @NonNull String permissionName, @NonNull UserHandle user);
+            @NonNull String permName, @NonNull UserHandle user);
 
     /**
      * Gets the state flags associated with a permission.
      *
-     * @param permissionName The permission for which to get the flags.
+     * @param permName The permission for which to get the flags.
      * @param packageName The package name for which to get the flags.
      * @param user The user for which to get permission flags.
      * @return The permission flags.
@@ -4056,14 +4056,14 @@
             android.Manifest.permission.GET_RUNTIME_PERMISSIONS
     })
     @PermissionFlags
-    public abstract int getPermissionFlags(@NonNull String permissionName,
+    public abstract int getPermissionFlags(@NonNull String permName,
             @NonNull String packageName, @NonNull UserHandle user);
 
     /**
      * Updates the flags associated with a permission by replacing the flags in
      * the specified mask with the provided flag values.
      *
-     * @param permissionName The permission for which to update the flags.
+     * @param permName The permission for which to update the flags.
      * @param packageName The package name for which to update the flags.
      * @param flagMask The flags which to replace.
      * @param flagValues The flags with which to replace.
@@ -4077,7 +4077,7 @@
             android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
             android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS
     })
-    public abstract void updatePermissionFlags(@NonNull String permissionName,
+    public abstract void updatePermissionFlags(@NonNull String permName,
             @NonNull String packageName, @PermissionFlags int flagMask,
             @PermissionFlags int flagValues, @NonNull UserHandle user);
 
@@ -4164,7 +4164,7 @@
      * provided ones.
      *
      * @param packageName The app for which to get whitelisted permissions.
-     * @param permission The whitelisted permission to add.
+     * @param permName The whitelisted permission to add.
      * @param whitelistFlags The whitelists to which to add. Passing multiple flags
      * updates all specified whitelists.
      * @return Whether the permission was added to the whitelist.
@@ -4180,7 +4180,7 @@
     @RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS,
             conditional = true)
     public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
-            @NonNull String permission, @PermissionWhitelistFlags int whitelistFlags) {
+            @NonNull String permName, @PermissionWhitelistFlags int whitelistFlags) {
         return false;
     }
 
@@ -4218,7 +4218,7 @@
      * provided ones.
      *
      * @param packageName The app for which to get whitelisted permissions.
-     * @param permission The whitelisted permission to remove.
+     * @param permName The whitelisted permission to remove.
      * @param whitelistFlags The whitelists from which to remove. Passing multiple flags
      * updates all specified whitelists.
      * @return Whether the permission was removed from the whitelist.
@@ -4234,7 +4234,7 @@
     @RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS,
         conditional = true)
     public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
-        @NonNull String permission, @PermissionWhitelistFlags int whitelistFlags) {
+            @NonNull String permName, @PermissionWhitelistFlags int whitelistFlags) {
         return false;
     }
 
@@ -4244,13 +4244,13 @@
      * which the permission is requested does not clearly communicate to the user
      * what would be the benefit from grating this permission.
      *
-     * @param permissionName A permission your app wants to request.
+     * @param permName A permission your app wants to request.
      * @return Whether you can show permission rationale UI.
      *
      * @hide
      */
     @UnsupportedAppUsage
-    public abstract boolean shouldShowRequestPermissionRationale(@NonNull String permissionName);
+    public abstract boolean shouldShowRequestPermissionRationale(@NonNull String permName);
 
     /**
      * Returns an {@link android.content.Intent} suitable for passing to
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index e21d4c41..2f198ac 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -84,139 +84,6 @@
     }
 
     /**
-     * Provider for package names.
-     */
-    public interface PackagesProvider {
-
-        /**
-         * Gets the packages for a given user.
-         * @param userId The user id.
-         * @return The package names.
-         */
-        public String[] getPackages(int userId);
-    }
-
-    /**
-     * Provider for package names.
-     */
-    public interface SyncAdapterPackagesProvider {
-
-        /**
-         * Gets the sync adapter packages for given authority and user.
-         * @param authority The authority.
-         * @param userId The user id.
-         * @return The package names.
-         */
-        public String[] getPackages(String authority, int userId);
-    }
-
-    /**
-     * Provider for default browser
-     */
-    public interface DefaultBrowserProvider {
-
-        /**
-         * Get the package name of the default browser.
-         *
-         * @param userId the user id
-         *
-         * @return the package name of the default browser, or {@code null} if none
-         */
-        @Nullable
-        String getDefaultBrowser(@UserIdInt int userId);
-
-        /**
-         * Set the package name of the default browser.
-         *
-         * @param packageName package name of the default browser, or {@code null} to remove
-         * @param userId the user id
-         *
-         * @return whether the default browser was successfully set.
-         */
-        boolean setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId);
-
-        /**
-         * Set the package name of the default browser asynchronously.
-         *
-         * @param packageName package name of the default browser, or {@code null} to remove
-         * @param userId the user id
-         */
-        void setDefaultBrowserAsync(@Nullable String packageName, @UserIdInt int userId);
-    }
-
-    /**
-     * Provider for default dialer
-     */
-    public interface DefaultDialerProvider {
-
-        /**
-         * Get the package name of the default dialer.
-         *
-         * @param userId the user id
-         *
-         * @return the package name of the default dialer, or {@code null} if none
-         */
-        @Nullable
-        String getDefaultDialer(@UserIdInt int userId);
-    }
-
-    /**
-     * Provider for default home
-     */
-    public interface DefaultHomeProvider {
-
-        /**
-         * Get the package name of the default home.
-         *
-         * @param userId the user id
-         *
-         * @return the package name of the default home, or {@code null} if none
-         */
-        @Nullable
-        String getDefaultHome(@UserIdInt int userId);
-
-        /**
-         * Set the package name of the default home.
-         *
-         * @param packageName package name of the default home, or {@code null} to remove
-         * @param userId the user id
-         * @param callback the callback made after the default home as been updated
-         */
-        void setDefaultHomeAsync(@Nullable String packageName, @UserIdInt int userId,
-                @NonNull Consumer<Boolean> callback);
-    }
-
-    /**
-     * Sets the location provider packages provider.
-     * @param provider The packages provider.
-     */
-    public abstract void setLocationPackagesProvider(PackagesProvider provider);
-
-    /**
-     * Set the location extra packages provider.
-     * @param provider The packages provider.
-     */
-    public abstract  void setLocationExtraPackagesProvider(PackagesProvider provider);
-
-    /**
-     * Sets the voice interaction packages provider.
-     * @param provider The packages provider.
-     */
-    public abstract void setVoiceInteractionPackagesProvider(PackagesProvider provider);
-
-    /**
-     * Sets the Use Open Wifi packages provider.
-     * @param provider The packages provider.
-     */
-    public abstract void setUseOpenWifiAppPackagesProvider(PackagesProvider provider);
-
-    /**
-     * Sets the sync adapter packages provider.
-     * @param provider The provider.
-     */
-    public abstract void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider);
-
-    /**
      * Called when the package for the default SMS handler changed
      *
      * @param packageName the new sms package
@@ -233,14 +100,6 @@
     public void onDefaultSimCallManagerAppChanged(String packageName, int userId) {}
 
     /**
-     * Requests granting of the default permissions to the current default Use Open Wifi app.
-     * @param packageName The default use open wifi package name.
-     * @param userId The user for which to grant the permissions.
-     */
-    public abstract void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName,
-            int userId);
-
-    /**
      * Sets a list of apps to keep in PM's internal data structures and as APKs even if no user has
      * currently installed it. The apps are not preloaded.
      * @param packageList List of package names to keep cached.
@@ -697,7 +556,15 @@
      * @see #canAccessInstantApps
      */
     public abstract boolean filterAppAccess(
-            @Nullable PackageParser.Package pkg, int callingUid, int userId);
+            @NonNull PackageParser.Package pkg, int callingUid, int userId);
+
+    /**
+     * Returns whether or not access to the application should be filtered.
+     *
+     * @see #filterAppAccess(android.content.pm.PackageParser.Package, int, int)
+     */
+    public abstract boolean filterAppAccess(
+            @NonNull String packageName, int callingUid, int userId);
 
     /** Returns whether the given package was signed by the platform */
     public abstract boolean isPlatformSigned(String pkg);
@@ -872,27 +739,6 @@
     public abstract String removeLegacyDefaultBrowserPackageName(int userId);
 
     /**
-     * Sets the default browser provider.
-     *
-     * @param provider the provider
-     */
-    public abstract void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider);
-
-    /**
-     * Sets the default dialer provider.
-     *
-     * @param provider the provider
-     */
-    public abstract void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider);
-
-    /**
-     * Sets the default home provider.
-     *
-     * @param provider the provider
-     */
-    public abstract void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider);
-
-    /**
      * Returns {@code true} if given {@code packageName} is an apex package.
      */
     public abstract boolean isApexPackage(String packageName);
@@ -910,15 +756,6 @@
             IntentSender intentSender);
 
     /**
-     * Whether default permission grants have been performed for a user
-     * since the device booted.
-     *
-     * @param userId The user id.
-     * @return true if default permissions
-     */
-    public abstract boolean wereDefaultPermissionsGrantedSinceBoot(int userId);
-
-    /**
      * Get fingerprint of build that updated the runtime permissions for a user.
      *
      * @param userId The user to update
@@ -960,4 +797,10 @@
      */
     public abstract boolean isCallerInstallerOfRecord(
             @NonNull PackageParser.Package pkg, int callingUid);
+
+    /** Returns whether or not default runtime permissions are granted for the given user */
+    public abstract boolean areDefaultRuntimePermissionsGranted(@UserIdInt int userId);
+
+    /** Sets the enforcement of reading external storage */
+    public abstract void setReadExternalStorageEnforced(boolean enforced);
 }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index a74c34f..e690a7f 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -254,6 +254,8 @@
 
     /** @hide */
     public static final String APK_FILE_EXTENSION = ".apk";
+    /** @hide */
+    public static final String APEX_FILE_EXTENSION = ".apex";
 
     /** @hide */
     public static class NewPermissionInfo {
@@ -6897,8 +6899,8 @@
         }
 
         /** @hide */
-        public boolean isProductServices() {
-            return applicationInfo.isProductServices();
+        public boolean isSystemExt() {
+            return applicationInfo.isSystemExt();
         }
 
         /** @hide */
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index 2b1b32e..30d87f4 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -19,10 +19,11 @@
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 
+import com.android.internal.os.RoSystemProperties;
+
 /**
  * Per-user information.
  * @hide
@@ -232,7 +233,9 @@
         if (isManagedProfile() || isGuest() || isRestricted()) {
             return false;
         }
-        if (UserManager.isSplitSystemUser()) {
+        boolean splitOrHeadlessSystemUser = UserManager.isSplitSystemUser()
+                || RoSystemProperties.MULTIUSER_HEADLESS_SYSTEM_USER;
+        if (splitOrHeadlessSystemUser) {
             return id != UserHandle.USER_SYSTEM;
         } else {
             return id == UserHandle.USER_SYSTEM;
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index a99a0b5..f3b7553 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -32,8 +32,8 @@
 import android.view.WindowManager.LayoutParams;
 
 /**
- * CompatibilityInfo class keeps the information about compatibility mode that the application is
- * running under.
+ * CompatibilityInfo class keeps the information about the screen compatibility mode that the
+ * application is running under.
  * 
  *  {@hide} 
  */
diff --git a/core/java/android/database/sqlite/SQLiteQueryBuilder.java b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
index 3523e95..48d8867 100644
--- a/core/java/android/database/sqlite/SQLiteQueryBuilder.java
+++ b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
@@ -30,11 +30,14 @@
 import android.util.ArrayMap;
 import android.util.Log;
 
+import com.android.internal.util.ArrayUtils;
+
 import libcore.util.EmptyArray;
 
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
@@ -49,14 +52,11 @@
 public class SQLiteQueryBuilder {
     private static final String TAG = "SQLiteQueryBuilder";
 
-    private static final Pattern sLimitPattern =
-            Pattern.compile("\\s*\\d+\\s*(,\\s*\\d+\\s*)?");
     private static final Pattern sAggregationPattern = Pattern.compile(
             "(?i)(AVG|COUNT|MAX|MIN|SUM|TOTAL|GROUP_CONCAT)\\((.+)\\)");
 
     private Map<String, String> mProjectionMap = null;
     private List<Pattern> mProjectionGreylist = null;
-    private boolean mProjectionAggregationAllowed = false;
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     private String mTables = "";
@@ -65,7 +65,12 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     private boolean mDistinct;
     private SQLiteDatabase.CursorFactory mFactory;
-    private boolean mStrict;
+
+    private static final int STRICT_PARENTHESES = 1 << 0;
+    private static final int STRICT_COLUMNS = 1 << 1;
+    private static final int STRICT_GRAMMAR = 1 << 2;
+
+    private int mStrictFlags;
 
     public SQLiteQueryBuilder() {
         mDistinct = false;
@@ -209,13 +214,14 @@
     }
 
     /** {@hide} */
+    @Deprecated
     public void setProjectionAggregationAllowed(boolean projectionAggregationAllowed) {
-        mProjectionAggregationAllowed = projectionAggregationAllowed;
     }
 
     /** {@hide} */
+    @Deprecated
     public boolean isProjectionAggregationAllowed() {
-        return mProjectionAggregationAllowed;
+        return true;
     }
 
     /**
@@ -258,8 +264,12 @@
      * </ul>
      * By default, this value is false.
      */
-    public void setStrict(boolean flag) {
-        mStrict = flag;
+    public void setStrict(boolean strict) {
+        if (strict) {
+            mStrictFlags |= STRICT_PARENTHESES;
+        } else {
+            mStrictFlags &= ~STRICT_PARENTHESES;
+        }
     }
 
     /**
@@ -267,7 +277,67 @@
      * {@link #setStrict(boolean)}.
      */
     public boolean isStrict() {
-        return mStrict;
+        return (mStrictFlags & STRICT_PARENTHESES) != 0;
+    }
+
+    /**
+     * When enabled, verify that all projections and {@link ContentValues} only
+     * contain valid columns as defined by {@link #setProjectionMap(Map)}.
+     * <p>
+     * This enforcement applies to {@link #insert}, {@link #query}, and
+     * {@link #update} operations. Any enforcement failures will throw an
+     * {@link IllegalArgumentException}.
+     */
+    public void setStrictColumns(boolean strictColumns) {
+        if (strictColumns) {
+            mStrictFlags |= STRICT_COLUMNS;
+        } else {
+            mStrictFlags &= ~STRICT_COLUMNS;
+        }
+    }
+
+    /**
+     * Get if the query is marked as strict, as last configured by
+     * {@link #setStrictColumns(boolean)}.
+     */
+    public boolean isStrictColumns() {
+        return (mStrictFlags & STRICT_COLUMNS) != 0;
+    }
+
+    /**
+     * When enabled, verify that all untrusted SQL conforms to a restricted SQL
+     * grammar. Here are the restrictions applied:
+     * <ul>
+     * <li>In {@code WHERE} and {@code HAVING} clauses: subqueries, raising, and
+     * windowing terms are rejected.
+     * <li>In {@code GROUP BY} clauses: only valid columns are allowed.
+     * <li>In {@code ORDER BY} clauses: only valid columns, collation, and
+     * ordering terms are allowed.
+     * <li>In {@code LIMIT} clauses: only numerical values and offset terms are
+     * allowed.
+     * </ul>
+     * All column references must be valid as defined by
+     * {@link #setProjectionMap(Map)}.
+     * <p>
+     * This enforcement applies to {@link #query}, {@link #update} and
+     * {@link #delete} operations. This enforcement does not apply to trusted
+     * inputs, such as those provided by {@link #appendWhere}. Any enforcement
+     * failures will throw an {@link IllegalArgumentException}.
+     */
+    public void setStrictGrammar(boolean strictGrammar) {
+        if (strictGrammar) {
+            mStrictFlags |= STRICT_GRAMMAR;
+        } else {
+            mStrictFlags &= ~STRICT_GRAMMAR;
+        }
+    }
+
+    /**
+     * Get if the query is marked as strict, as last configured by
+     * {@link #setStrictGrammar(boolean)}.
+     */
+    public boolean isStrictGrammar() {
+        return (mStrictFlags & STRICT_GRAMMAR) != 0;
     }
 
     /**
@@ -303,9 +373,6 @@
             throw new IllegalArgumentException(
                     "HAVING clauses are only permitted when using a groupBy clause");
         }
-        if (!TextUtils.isEmpty(limit) && !sLimitPattern.matcher(limit).matches()) {
-            throw new IllegalArgumentException("invalid LIMIT clauses:" + limit);
-        }
 
         StringBuilder query = new StringBuilder(120);
 
@@ -479,7 +546,13 @@
                 projectionIn, selection, groupBy, having,
                 sortOrder, limit);
 
-        if (mStrict && selection != null && selection.length() > 0) {
+        if (isStrictColumns()) {
+            enforceStrictColumns(projectionIn);
+        }
+        if (isStrictGrammar()) {
+            enforceStrictGrammar(selection, groupBy, having, sortOrder, limit);
+        }
+        if (isStrict()) {
             // Validate the user-supplied selection to detect syntactic anomalies
             // in the selection string that could indicate a SQL injection attempt.
             // The idea is to ensure that the selection clause is a valid SQL expression
@@ -497,7 +570,7 @@
 
             // Execute wrapped query for extra protection
             final String wrappedSql = buildQuery(projectionIn, wrap(selection), groupBy,
-                    having, sortOrder, limit);
+                    wrap(having), sortOrder, limit);
             sql = wrappedSql;
         } else {
             // Execute unwrapped query
@@ -519,6 +592,40 @@
     }
 
     /**
+     * Perform an insert by combining all current settings and the
+     * information passed into this method.
+     *
+     * @param db the database to insert on
+     * @return the row ID of the newly inserted row, or -1 if an error occurred
+     */
+    public long insert(@NonNull SQLiteDatabase db, @NonNull ContentValues values) {
+        Objects.requireNonNull(mTables, "No tables defined");
+        Objects.requireNonNull(db, "No database defined");
+        Objects.requireNonNull(values, "No values defined");
+
+        if (isStrictColumns()) {
+            enforceStrictColumns(values);
+        }
+
+        final String sql = buildInsert(values);
+
+        final ArrayMap<String, Object> rawValues = values.getValues();
+        final int valuesLength = rawValues.size();
+        final Object[] sqlArgs = new Object[valuesLength];
+        for (int i = 0; i < sqlArgs.length; i++) {
+            sqlArgs[i] = rawValues.valueAt(i);
+        }
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            if (Build.IS_DEBUGGABLE) {
+                Log.d(TAG, sql + " with args " + Arrays.toString(sqlArgs));
+            } else {
+                Log.d(TAG, sql);
+            }
+        }
+        return db.executeSql(sql, sqlArgs);
+    }
+
+    /**
      * Perform an update by combining all current settings and the
      * information passed into this method.
      *
@@ -541,7 +648,13 @@
         final String sql;
         final String unwrappedSql = buildUpdate(values, selection);
 
-        if (mStrict) {
+        if (isStrictColumns()) {
+            enforceStrictColumns(values);
+        }
+        if (isStrictGrammar()) {
+            enforceStrictGrammar(selection, null, null, null, null);
+        }
+        if (isStrict()) {
             // Validate the user-supplied selection to detect syntactic anomalies
             // in the selection string that could indicate a SQL injection attempt.
             // The idea is to ensure that the selection clause is a valid SQL expression
@@ -610,7 +723,10 @@
         final String sql;
         final String unwrappedSql = buildDelete(selection);
 
-        if (mStrict) {
+        if (isStrictGrammar()) {
+            enforceStrictGrammar(selection, null, null, null, null);
+        }
+        if (isStrict()) {
             // Validate the user-supplied selection to detect syntactic anomalies
             // in the selection string that could indicate a SQL injection attempt.
             // The idea is to ensure that the selection clause is a valid SQL expression
@@ -645,6 +761,81 @@
         return db.executeSql(sql, sqlArgs);
     }
 
+    private void enforceStrictColumns(@Nullable String[] projection) {
+        Objects.requireNonNull(mProjectionMap, "No projection map defined");
+
+        computeProjection(projection);
+    }
+
+    private void enforceStrictColumns(@NonNull ContentValues values) {
+        Objects.requireNonNull(mProjectionMap, "No projection map defined");
+
+        final ArrayMap<String, Object> rawValues = values.getValues();
+        for (int i = 0; i < rawValues.size(); i++) {
+            final String column = rawValues.keyAt(i);
+            if (!mProjectionMap.containsKey(column)) {
+                throw new IllegalArgumentException("Invalid column " + column);
+            }
+        }
+    }
+
+    private void enforceStrictGrammar(@Nullable String selection, @Nullable String groupBy,
+            @Nullable String having, @Nullable String sortOrder, @Nullable String limit) {
+        SQLiteTokenizer.tokenize(selection, SQLiteTokenizer.OPTION_NONE,
+                this::enforceStrictGrammarWhereHaving);
+        SQLiteTokenizer.tokenize(groupBy, SQLiteTokenizer.OPTION_NONE,
+                this::enforceStrictGrammarGroupBy);
+        SQLiteTokenizer.tokenize(having, SQLiteTokenizer.OPTION_NONE,
+                this::enforceStrictGrammarWhereHaving);
+        SQLiteTokenizer.tokenize(sortOrder, SQLiteTokenizer.OPTION_NONE,
+                this::enforceStrictGrammarOrderBy);
+        SQLiteTokenizer.tokenize(limit, SQLiteTokenizer.OPTION_NONE,
+                this::enforceStrictGrammarLimit);
+    }
+
+    private void enforceStrictGrammarWhereHaving(@NonNull String token) {
+        if (isTableOrColumn(token)) return;
+        if (SQLiteTokenizer.isFunction(token)) return;
+        if (SQLiteTokenizer.isType(token)) return;
+
+        // NOTE: we explicitly don't allow SELECT subqueries, since they could
+        // leak data that should have been filtered by the trusted where clause
+        switch (token.toUpperCase(Locale.US)) {
+            case "AND": case "AS": case "BETWEEN": case "BINARY":
+            case "CASE": case "CAST": case "COLLATE": case "DISTINCT":
+            case "ELSE": case "END": case "ESCAPE": case "EXISTS":
+            case "GLOB": case "IN": case "IS": case "ISNULL":
+            case "LIKE": case "MATCH": case "NOCASE": case "NOT":
+            case "NOTNULL": case "NULL": case "OR": case "REGEXP":
+            case "RTRIM": case "THEN": case "WHEN":
+                return;
+        }
+        throw new IllegalArgumentException("Invalid token " + token);
+    }
+
+    private void enforceStrictGrammarGroupBy(@NonNull String token) {
+        if (isTableOrColumn(token)) return;
+        throw new IllegalArgumentException("Invalid token " + token);
+    }
+
+    private void enforceStrictGrammarOrderBy(@NonNull String token) {
+        if (isTableOrColumn(token)) return;
+        switch (token.toUpperCase(Locale.US)) {
+            case "COLLATE": case "ASC": case "DESC":
+            case "BINARY": case "RTRIM": case "NOCASE":
+                return;
+        }
+        throw new IllegalArgumentException("Invalid token " + token);
+    }
+
+    private void enforceStrictGrammarLimit(@NonNull String token) {
+        switch (token.toUpperCase(Locale.US)) {
+            case "OFFSET":
+                return;
+        }
+        throw new IllegalArgumentException("Invalid token " + token);
+    }
+
     /**
      * Construct a {@code SELECT} statement suitable for use in a group of
      * {@code SELECT} statements that will be joined through {@code UNION} operators
@@ -698,6 +889,35 @@
     }
 
     /** {@hide} */
+    public String buildInsert(ContentValues values) {
+        if (values == null || values.isEmpty()) {
+            throw new IllegalArgumentException("Empty values");
+        }
+
+        StringBuilder sql = new StringBuilder(120);
+        sql.append("INSERT INTO ");
+        sql.append(SQLiteDatabase.findEditTable(mTables));
+        sql.append(" (");
+
+        final ArrayMap<String, Object> rawValues = values.getValues();
+        for (int i = 0; i < rawValues.size(); i++) {
+            if (i > 0) {
+                sql.append(',');
+            }
+            sql.append(rawValues.keyAt(i));
+        }
+        sql.append(") VALUES (");
+        for (int i = 0; i < rawValues.size(); i++) {
+            if (i > 0) {
+                sql.append(',');
+            }
+            sql.append('?');
+        }
+        sql.append(")");
+        return sql.toString();
+    }
+
+    /** {@hide} */
     public String buildUpdate(ContentValues values, String selection) {
         if (values == null || values.isEmpty()) {
             throw new IllegalArgumentException("Empty values");
@@ -705,7 +925,7 @@
 
         StringBuilder sql = new StringBuilder(120);
         sql.append("UPDATE ");
-        sql.append(mTables);
+        sql.append(SQLiteDatabase.findEditTable(mTables));
         sql.append(" SET ");
 
         final ArrayMap<String, Object> rawValues = values.getValues();
@@ -726,7 +946,7 @@
     public String buildDelete(String selection) {
         StringBuilder sql = new StringBuilder(120);
         sql.append("DELETE FROM ");
-        sql.append(mTables);
+        sql.append(SQLiteDatabase.findEditTable(mTables));
 
         final String where = computeWhere(selection);
         appendClause(sql, " WHERE ", where);
@@ -868,65 +1088,13 @@
 
     /** {@hide} */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    public String[] computeProjection(String[] projectionIn) {
-        if (projectionIn != null && projectionIn.length > 0) {
-            if (mProjectionMap != null) {
-                String[] projection = new String[projectionIn.length];
-                int length = projectionIn.length;
-
-                for (int i = 0; i < length; i++) {
-                    String operator = null;
-                    String userColumn = projectionIn[i];
-                    String column = mProjectionMap.get(userColumn);
-
-                    // If aggregation is allowed, extract the underlying column
-                    // that may be aggregated
-                    if (mProjectionAggregationAllowed) {
-                        final Matcher matcher = sAggregationPattern.matcher(userColumn);
-                        if (matcher.matches()) {
-                            operator = matcher.group(1);
-                            userColumn = matcher.group(2);
-                            column = mProjectionMap.get(userColumn);
-                        }
-                    }
-
-                    if (column != null) {
-                        projection[i] = maybeWithOperator(operator, column);
-                        continue;
-                    }
-
-                    if (!mStrict &&
-                            ( userColumn.contains(" AS ") || userColumn.contains(" as "))) {
-                        /* A column alias already exist */
-                        projection[i] = maybeWithOperator(operator, userColumn);
-                        continue;
-                    }
-
-                    // If greylist is configured, we might be willing to let
-                    // this custom column bypass our strict checks.
-                    if (mProjectionGreylist != null) {
-                        boolean match = false;
-                        for (Pattern p : mProjectionGreylist) {
-                            if (p.matcher(userColumn).matches()) {
-                                match = true;
-                                break;
-                            }
-                        }
-
-                        if (match) {
-                            Log.w(TAG, "Allowing abusive custom column: " + userColumn);
-                            projection[i] = maybeWithOperator(operator, userColumn);
-                            continue;
-                        }
-                    }
-
-                    throw new IllegalArgumentException("Invalid column "
-                            + projectionIn[i]);
-                }
-                return projection;
-            } else {
-                return projectionIn;
+    public @Nullable String[] computeProjection(@Nullable String[] projectionIn) {
+        if (!ArrayUtils.isEmpty(projectionIn)) {
+            String[] projectionOut = new String[projectionIn.length];
+            for (int i = 0; i < projectionIn.length; i++) {
+                projectionOut[i] = computeSingleProjectionOrThrow(projectionIn[i]);
             }
+            return projectionOut;
         } else if (mProjectionMap != null) {
             // Return all columns in projection map.
             Set<Entry<String, String>> entrySet = mProjectionMap.entrySet();
@@ -948,6 +1116,69 @@
         return null;
     }
 
+    private @NonNull String computeSingleProjectionOrThrow(@NonNull String userColumn) {
+        final String column = computeSingleProjection(userColumn);
+        if (column != null) {
+            return column;
+        } else {
+            throw new IllegalArgumentException("Invalid column " + userColumn);
+        }
+    }
+
+    private @Nullable String computeSingleProjection(@NonNull String userColumn) {
+        // When no mapping provided, anything goes
+        if (mProjectionMap == null) {
+            return userColumn;
+        }
+
+        String operator = null;
+        String column = mProjectionMap.get(userColumn);
+
+        // When no direct match found, look for aggregation
+        if (column == null) {
+            final Matcher matcher = sAggregationPattern.matcher(userColumn);
+            if (matcher.matches()) {
+                operator = matcher.group(1);
+                userColumn = matcher.group(2);
+                column = mProjectionMap.get(userColumn);
+            }
+        }
+
+        if (column != null) {
+            return maybeWithOperator(operator, column);
+        }
+
+        if (mStrictFlags == 0 &&
+                (userColumn.contains(" AS ") || userColumn.contains(" as "))) {
+            /* A column alias already exist */
+            return maybeWithOperator(operator, userColumn);
+        }
+
+        // If greylist is configured, we might be willing to let
+        // this custom column bypass our strict checks.
+        if (mProjectionGreylist != null) {
+            boolean match = false;
+            for (Pattern p : mProjectionGreylist) {
+                if (p.matcher(userColumn).matches()) {
+                    match = true;
+                    break;
+                }
+            }
+
+            if (match) {
+                Log.w(TAG, "Allowing abusive custom column: " + userColumn);
+                return maybeWithOperator(operator, userColumn);
+            }
+        }
+
+        return null;
+    }
+
+    private boolean isTableOrColumn(String token) {
+        if (mTables.equals(token)) return true;
+        return computeSingleProjection(token) != null;
+    }
+
     /** {@hide} */
     public @Nullable String computeWhere(@Nullable String selection) {
         final boolean hasInternal = !TextUtils.isEmpty(mWhereClause);
diff --git a/core/java/android/database/sqlite/SQLiteTokenizer.java b/core/java/android/database/sqlite/SQLiteTokenizer.java
new file mode 100644
index 0000000..7e7c3fb
--- /dev/null
+++ b/core/java/android/database/sqlite/SQLiteTokenizer.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.function.Consumer;
+
+/**
+ * SQL Tokenizer specialized to extract tokens from SQL (snippets).
+ * <p>
+ * Based on sqlite3GetToken() in tokenzie.c in SQLite.
+ * <p>
+ * Source for v3.8.6 (which android uses): http://www.sqlite.org/src/artifact/ae45399d6252b4d7
+ * (Latest source as of now: http://www.sqlite.org/src/artifact/78c8085bc7af1922)
+ * <p>
+ * Also draft spec: http://www.sqlite.org/draft/tokenreq.html
+ *
+ * @hide
+ */
+public class SQLiteTokenizer {
+    private static boolean isAlpha(char ch) {
+        return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || (ch == '_');
+    }
+
+    private static boolean isNum(char ch) {
+        return ('0' <= ch && ch <= '9');
+    }
+
+    private static boolean isAlNum(char ch) {
+        return isAlpha(ch) || isNum(ch);
+    }
+
+    private static boolean isAnyOf(char ch, String set) {
+        return set.indexOf(ch) >= 0;
+    }
+
+    private static IllegalArgumentException genException(String message, String sql) {
+        throw new IllegalArgumentException(message + " in '" + sql + "'");
+    }
+
+    private static char peek(String s, int index) {
+        return index < s.length() ? s.charAt(index) : '\0';
+    }
+
+    public static final int OPTION_NONE = 0;
+
+    /**
+     * Require that SQL contains only tokens; any comments or values will result
+     * in an exception.
+     */
+    public static final int OPTION_TOKEN_ONLY = 1 << 0;
+
+    /**
+     * Tokenize the given SQL, returning the list of each encountered token.
+     *
+     * @throws IllegalArgumentException if invalid SQL is encountered.
+     */
+    public static List<String> tokenize(@Nullable String sql, int options) {
+        final ArrayList<String> res = new ArrayList<>();
+        tokenize(sql, options, res::add);
+        return res;
+    }
+
+    /**
+     * Tokenize the given SQL, sending each encountered token to the given
+     * {@link Consumer}.
+     *
+     * @throws IllegalArgumentException if invalid SQL is encountered.
+     */
+    public static void tokenize(@Nullable String sql, int options, Consumer<String> checker) {
+        if (sql == null) {
+            return;
+        }
+        int pos = 0;
+        final int len = sql.length();
+        while (pos < len) {
+            final char ch = peek(sql, pos);
+
+            // Regular token.
+            if (isAlpha(ch)) {
+                final int start = pos;
+                pos++;
+                while (isAlNum(peek(sql, pos))) {
+                    pos++;
+                }
+                final int end = pos;
+
+                final String token = sql.substring(start, end);
+                checker.accept(token);
+
+                continue;
+            }
+
+            // Handle quoted tokens
+            if (isAnyOf(ch, "'\"`")) {
+                final int quoteStart = pos;
+                pos++;
+
+                for (;;) {
+                    pos = sql.indexOf(ch, pos);
+                    if (pos < 0) {
+                        throw genException("Unterminated quote", sql);
+                    }
+                    if (peek(sql, pos + 1) != ch) {
+                        break;
+                    }
+                    // Quoted quote char -- e.g. "abc""def" is a single string.
+                    pos += 2;
+                }
+                final int quoteEnd = pos;
+                pos++;
+
+                if (ch != '\'') {
+                    // Extract the token
+                    final String tokenUnquoted = sql.substring(quoteStart + 1, quoteEnd);
+
+                    final String token;
+
+                    // Unquote if needed. i.e. "aa""bb" -> aa"bb
+                    if (tokenUnquoted.indexOf(ch) >= 0) {
+                        token = tokenUnquoted.replaceAll(
+                                String.valueOf(ch) + ch, String.valueOf(ch));
+                    } else {
+                        token = tokenUnquoted;
+                    }
+                    checker.accept(token);
+                } else {
+                    if ((options &= OPTION_TOKEN_ONLY) != 0) {
+                        throw genException("Non-token detected", sql);
+                    }
+                }
+                continue;
+            }
+            // Handle tokens enclosed in [...]
+            if (ch == '[') {
+                final int quoteStart = pos;
+                pos++;
+
+                pos = sql.indexOf(']', pos);
+                if (pos < 0) {
+                    throw genException("Unterminated quote", sql);
+                }
+                final int quoteEnd = pos;
+                pos++;
+
+                final String token = sql.substring(quoteStart + 1, quoteEnd);
+
+                checker.accept(token);
+                continue;
+            }
+            if ((options &= OPTION_TOKEN_ONLY) != 0) {
+                throw genException("Non-token detected", sql);
+            }
+
+            // Detect comments.
+            if (ch == '-' && peek(sql, pos + 1) == '-') {
+                pos += 2;
+                pos = sql.indexOf('\n', pos);
+                if (pos < 0) {
+                    // We disallow strings ending in an inline comment.
+                    throw genException("Unterminated comment", sql);
+                }
+                pos++;
+
+                continue;
+            }
+            if (ch == '/' && peek(sql, pos + 1) == '*') {
+                pos += 2;
+                pos = sql.indexOf("*/", pos);
+                if (pos < 0) {
+                    throw genException("Unterminated comment", sql);
+                }
+                pos += 2;
+
+                continue;
+            }
+
+            // Semicolon is never allowed.
+            if (ch == ';') {
+                throw genException("Semicolon is not allowed", sql);
+            }
+
+            // For this purpose, we can simply ignore other characters.
+            // (Note it doesn't handle the X'' literal properly and reports this X as a token,
+            // but that should be fine...)
+            pos++;
+        }
+    }
+
+    /**
+     * Test if given token is a
+     * <a href="https://www.sqlite.org/lang_keywords.html">SQLite reserved
+     * keyword</a>.
+     */
+    public static boolean isKeyword(@NonNull String token) {
+        switch (token.toUpperCase(Locale.US)) {
+            case "ABORT": case "ACTION": case "ADD": case "AFTER":
+            case "ALL": case "ALTER": case "ANALYZE": case "AND":
+            case "AS": case "ASC": case "ATTACH": case "AUTOINCREMENT":
+            case "BEFORE": case "BEGIN": case "BETWEEN": case "BINARY":
+            case "BY": case "CASCADE": case "CASE": case "CAST":
+            case "CHECK": case "COLLATE": case "COLUMN": case "COMMIT":
+            case "CONFLICT": case "CONSTRAINT": case "CREATE": case "CROSS":
+            case "CURRENT": case "CURRENT_DATE": case "CURRENT_TIME": case "CURRENT_TIMESTAMP":
+            case "DATABASE": case "DEFAULT": case "DEFERRABLE": case "DEFERRED":
+            case "DELETE": case "DESC": case "DETACH": case "DISTINCT":
+            case "DO": case "DROP": case "EACH": case "ELSE":
+            case "END": case "ESCAPE": case "EXCEPT": case "EXCLUDE":
+            case "EXCLUSIVE": case "EXISTS": case "EXPLAIN": case "FAIL":
+            case "FILTER": case "FOLLOWING": case "FOR": case "FOREIGN":
+            case "FROM": case "FULL": case "GLOB": case "GROUP":
+            case "GROUPS": case "HAVING": case "IF": case "IGNORE":
+            case "IMMEDIATE": case "IN": case "INDEX": case "INDEXED":
+            case "INITIALLY": case "INNER": case "INSERT": case "INSTEAD":
+            case "INTERSECT": case "INTO": case "IS": case "ISNULL":
+            case "JOIN": case "KEY": case "LEFT": case "LIKE":
+            case "LIMIT": case "MATCH": case "NATURAL": case "NO":
+            case "NOCASE": case "NOT": case "NOTHING": case "NOTNULL":
+            case "NULL": case "OF": case "OFFSET": case "ON":
+            case "OR": case "ORDER": case "OTHERS": case "OUTER":
+            case "OVER": case "PARTITION": case "PLAN": case "PRAGMA":
+            case "PRECEDING": case "PRIMARY": case "QUERY": case "RAISE":
+            case "RANGE": case "RECURSIVE": case "REFERENCES": case "REGEXP":
+            case "REINDEX": case "RELEASE": case "RENAME": case "REPLACE":
+            case "RESTRICT": case "RIGHT": case "ROLLBACK": case "ROW":
+            case "ROWS": case "RTRIM": case "SAVEPOINT": case "SELECT":
+            case "SET": case "TABLE": case "TEMP": case "TEMPORARY":
+            case "THEN": case "TIES": case "TO": case "TRANSACTION":
+            case "TRIGGER": case "UNBOUNDED": case "UNION": case "UNIQUE":
+            case "UPDATE": case "USING": case "VACUUM": case "VALUES":
+            case "VIEW": case "VIRTUAL": case "WHEN": case "WHERE":
+            case "WINDOW": case "WITH": case "WITHOUT":
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Test if given token is a
+     * <a href="https://www.sqlite.org/lang_corefunc.html">SQLite reserved
+     * function</a>.
+     */
+    public static boolean isFunction(@NonNull String token) {
+        switch (token.toLowerCase(Locale.US)) {
+            case "abs": case "avg": case "char": case "coalesce":
+            case "count": case "glob": case "group_concat": case "hex":
+            case "ifnull": case "instr": case "length": case "like":
+            case "likelihood": case "likely": case "lower": case "ltrim":
+            case "max": case "min": case "nullif": case "random":
+            case "randomblob": case "replace": case "round": case "rtrim":
+            case "substr": case "sum": case "total": case "trim":
+            case "typeof": case "unicode": case "unlikely": case "upper":
+            case "zeroblob":
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Test if given token is a
+     * <a href="https://www.sqlite.org/datatype3.html">SQLite reserved type</a>.
+     */
+    public static boolean isType(@NonNull String token) {
+        switch (token.toUpperCase(Locale.US)) {
+            case "INT": case "INTEGER": case "TINYINT": case "SMALLINT":
+            case "MEDIUMINT": case "BIGINT": case "INT2": case "INT8":
+            case "CHARACTER": case "VARCHAR": case "NCHAR": case "NVARCHAR":
+            case "TEXT": case "CLOB": case "BLOB": case "REAL":
+            case "DOUBLE": case "FLOAT": case "NUMERIC": case "DECIMAL":
+            case "BOOLEAN": case "DATE": case "DATETIME":
+                return true;
+            default:
+                return false;
+        }
+    }
+}
diff --git a/core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl b/core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl
index d22e7e2..62d727c 100644
--- a/core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl
@@ -22,5 +22,5 @@
  * @hide
  */
 oneway interface IBiometricEnabledOnKeyguardCallback {
-    void onChanged(in BiometricSourceType type, boolean enabled);
+    void onChanged(in BiometricSourceType type, boolean enabled, int userId);
 }
\ No newline at end of file
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 9f4118e..b3125d8 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1191,7 +1191,7 @@
         ArrayList<Partition> partitions = new ArrayList();
 
         String[] names = new String[] {
-            "bootimage", "odm", "product", "product_services", Partition.PARTITION_NAME_SYSTEM,
+            "bootimage", "odm", "product", "system_ext", Partition.PARTITION_NAME_SYSTEM,
             "vendor"
         };
         for (String name : names) {
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 0ee9a11..3462d1f 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -54,7 +54,7 @@
     private static final String ENV_ODM_ROOT = "ODM_ROOT";
     private static final String ENV_VENDOR_ROOT = "VENDOR_ROOT";
     private static final String ENV_PRODUCT_ROOT = "PRODUCT_ROOT";
-    private static final String ENV_PRODUCT_SERVICES_ROOT = "PRODUCT_SERVICES_ROOT";
+    private static final String ENV_SYSTEM_EXT_ROOT = "SYSTEM_EXT_ROOT";
 
     /** {@hide} */
     public static final String DIR_ANDROID = "Android";
@@ -77,8 +77,8 @@
     private static final File DIR_ODM_ROOT = getDirectory(ENV_ODM_ROOT, "/odm");
     private static final File DIR_VENDOR_ROOT = getDirectory(ENV_VENDOR_ROOT, "/vendor");
     private static final File DIR_PRODUCT_ROOT = getDirectory(ENV_PRODUCT_ROOT, "/product");
-    private static final File DIR_PRODUCT_SERVICES_ROOT = getDirectory(ENV_PRODUCT_SERVICES_ROOT,
-                                                           "/product_services");
+    private static final File DIR_SYSTEM_EXT_ROOT = getDirectory(ENV_SYSTEM_EXT_ROOT,
+                                                           "/system_ext");
 
     @UnsupportedAppUsage
     private static UserEnvironment sCurrentUser;
@@ -222,11 +222,26 @@
      * Return root directory of the "product_services" partition holding middleware
      * services if any. If present, the partition is mounted read-only.
      *
+     * @deprecated This directory is not guaranteed to exist.
+     *             Its name is changed to "system_ext" because the partition's purpose is changed.
+     *             {@link #getSystemExtDirectory()}
      * @hide
      */
     @SystemApi
+    @Deprecated
     public static @NonNull File getProductServicesDirectory() {
-        return DIR_PRODUCT_SERVICES_ROOT;
+        return getDirectory("PRODUCT_SERVICES_ROOT", "/product_services");
+    }
+
+    /**
+     * Return root directory of the "system_ext" partition holding system partition's extension
+     * If present, the partition is mounted read-only.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static @NonNull File getSystemExtDirectory() {
+        return DIR_SYSTEM_EXT_ROOT;
     }
 
     /**
diff --git a/core/java/android/permission/IPermissionManager.aidl b/core/java/android/permission/IPermissionManager.aidl
index d31cee0..9fa5f16 100644
--- a/core/java/android/permission/IPermissionManager.aidl
+++ b/core/java/android/permission/IPermissionManager.aidl
@@ -70,4 +70,31 @@
     void revokeRuntimePermission(String packageName, String permName, int userId);
 
     void resetRuntimePermissions();
+
+    boolean setDefaultBrowser(String packageName, int userId);
+
+    String getDefaultBrowser(int userId);
+
+    void grantDefaultPermissionsToEnabledCarrierApps(in String[] packageNames, int userId);
+
+    void grantDefaultPermissionsToEnabledImsServices(in String[] packageNames, int userId);
+
+    void grantDefaultPermissionsToEnabledTelephonyDataServices(
+            in String[] packageNames, int userId);
+
+    void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
+            in String[] packageNames, int userId);
+
+    void grantDefaultPermissionsToActiveLuiApp(in String packageName, int userId);
+
+    void revokeDefaultPermissionsFromLuiApps(in String[] packageNames, int userId);
+
+    void setPermissionEnforced(String permName, boolean enforced);
+
+    boolean isPermissionEnforced(String permName);
+
+    boolean shouldShowRequestPermissionRationale(String permName,
+            String packageName, int userId);
+
+    boolean isPermissionRevokedByPolicy(String permName, String packageName, int userId);
 }
diff --git a/core/java/android/service/autofill/FillEventHistory.java b/core/java/android/service/autofill/FillEventHistory.java
index c65e773..1cd2d62 100644
--- a/core/java/android/service/autofill/FillEventHistory.java
+++ b/core/java/android/service/autofill/FillEventHistory.java
@@ -224,13 +224,21 @@
          */
         public static final int TYPE_CONTEXT_COMMITTED = 4;
 
+        /**
+         * A dataset selector was shown.
+         *
+         * <p>This event is fired whenever the autofill UI was presented to the user.</p>
+         */
+        public static final int TYPE_DATASETS_SHOWN = 5;
+
         /** @hide */
         @IntDef(prefix = { "TYPE_" }, value = {
                 TYPE_DATASET_SELECTED,
                 TYPE_DATASET_AUTHENTICATION_SELECTED,
                 TYPE_AUTHENTICATION_SELECTED,
                 TYPE_SAVE_SHOWN,
-                TYPE_CONTEXT_COMMITTED
+                TYPE_CONTEXT_COMMITTED,
+                TYPE_DATASETS_SHOWN
         })
         @Retention(RetentionPolicy.SOURCE)
         @interface EventIds{}
@@ -473,7 +481,7 @@
                 @Nullable ArrayList<ArrayList<String>> manuallyFilledDatasetIds,
                 @Nullable AutofillId[] detectedFieldIds,
                 @Nullable FieldClassification[] detectedFieldClassifications) {
-            mEventType = Preconditions.checkArgumentInRange(eventType, 0, TYPE_CONTEXT_COMMITTED,
+            mEventType = Preconditions.checkArgumentInRange(eventType, 0, TYPE_DATASETS_SHOWN,
                     "eventType");
             mDatasetId = datasetId;
             mClientState = clientState;
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 4bfd138..f73f28a 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -308,7 +308,7 @@
     /**
      * Called when the system gesture exclusion has changed.
      */
-    void reportSystemGestureExclusionChanged(IWindow window, in List<Rect> exclusionRects);
+    oneway void reportSystemGestureExclusionChanged(IWindow window, in List<Rect> exclusionRects);
 
     /**
     * Request the server to call setInputWindowInfo on a given Surface, and return
diff --git a/core/java/android/view/WindowInfo.java b/core/java/android/view/WindowInfo.java
index abf5e3f..57dfc62 100644
--- a/core/java/android/view/WindowInfo.java
+++ b/core/java/android/view/WindowInfo.java
@@ -16,7 +16,7 @@
 
 package android.view;
 
-import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -44,7 +44,7 @@
     public IBinder parentToken;
     public IBinder activityToken;
     public boolean focused;
-    public final Rect boundsInScreen = new Rect();
+    public Region regionInScreen = new Region();
     public List<IBinder> childTokens;
     public CharSequence title;
     public long accessibilityIdOfAnchor = AccessibilityNodeInfo.UNDEFINED_NODE_ID;
@@ -73,7 +73,7 @@
         window.parentToken = other.parentToken;
         window.activityToken = other.activityToken;
         window.focused = other.focused;
-        window.boundsInScreen.set(other.boundsInScreen);
+        window.regionInScreen.set(other.regionInScreen);
         window.title = other.title;
         window.accessibilityIdOfAnchor = other.accessibilityIdOfAnchor;
         window.inPictureInPicture = other.inPictureInPicture;
@@ -109,7 +109,7 @@
         parcel.writeStrongBinder(parentToken);
         parcel.writeStrongBinder(activityToken);
         parcel.writeInt(focused ? 1 : 0);
-        boundsInScreen.writeToParcel(parcel, flags);
+        regionInScreen.writeToParcel(parcel, flags);
         parcel.writeCharSequence(title);
         parcel.writeLong(accessibilityIdOfAnchor);
         parcel.writeInt(inPictureInPicture ? 1 : 0);
@@ -132,7 +132,8 @@
         builder.append(", type=").append(type);
         builder.append(", layer=").append(layer);
         builder.append(", token=").append(token);
-        builder.append(", bounds=").append(boundsInScreen);
+        builder.append(", region=").append(regionInScreen);
+        builder.append(", bounds=").append(regionInScreen.getBounds());
         builder.append(", parent=").append(parentToken);
         builder.append(", focused=").append(focused);
         builder.append(", children=").append(childTokens);
@@ -151,7 +152,7 @@
         parentToken = parcel.readStrongBinder();
         activityToken = parcel.readStrongBinder();
         focused = (parcel.readInt() == 1);
-        boundsInScreen.readFromParcel(parcel);
+        regionInScreen = Region.CREATOR.createFromParcel(parcel);
         title = parcel.readCharSequence();
         accessibilityIdOfAnchor = parcel.readLong();
         inPictureInPicture = (parcel.readInt() == 1);
@@ -174,7 +175,7 @@
         parentToken = null;
         activityToken = null;
         focused = false;
-        boundsInScreen.setEmpty();
+        regionInScreen.setEmpty();
         if (childTokens != null) {
             childTokens.clear();
         }
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 985effb..fd09a87 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -622,6 +622,10 @@
     /**
      * Change type for {@link #TYPE_WINDOWS_CHANGED} event:
      * The window's bounds changed.
+     * <p>
+     * Starting in {@link android.os.Build.VERSION_CODES#R R}, this event implies the window's
+     * region changed. It's also possible that region changed but bounds doesn't.
+     * </p>
      */
     public static final int WINDOWS_CHANGE_BOUNDS = 0x00000008;
 
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
index ea61ef8..6a3af34 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
@@ -16,9 +16,11 @@
 
 package android.view.accessibility;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
@@ -107,7 +109,7 @@
     private int mBooleanProperties;
     private int mId = UNDEFINED_WINDOW_ID;
     private int mParentId = UNDEFINED_WINDOW_ID;
-    private final Rect mBoundsInScreen = new Rect();
+    private Region mRegionInScreen = new Region();
     private LongArray mChildIds;
     private CharSequence mTitle;
     private long mAnchorId = AccessibilityNodeInfo.UNDEFINED_NODE_ID;
@@ -305,23 +307,33 @@
     }
 
     /**
-     * Gets the bounds of this window in the screen.
+     * Gets the touchable region of this window in the screen.
+     *
+     * @param outRegion The out window region.
+     */
+    public void getRegionInScreen(@NonNull Region outRegion) {
+        outRegion.set(mRegionInScreen);
+    }
+
+    /**
+     * Sets the touchable region of this window in the screen.
+     *
+     * @param region The window region.
+     *
+     * @hide
+     */
+    public void setRegionInScreen(Region region) {
+        mRegionInScreen.set(region);
+    }
+
+    /**
+     * Gets the bounds of this window in the screen. This is equivalent to get the bounds of the
+     * Region from {@link #getRegionInScreen(Region)}.
      *
      * @param outBounds The out window bounds.
      */
     public void getBoundsInScreen(Rect outBounds) {
-        outBounds.set(mBoundsInScreen);
-    }
-
-    /**
-     * Sets the bounds of this window in the screen.
-     *
-     * @param bounds The out window bounds.
-     *
-     * @hide
-     */
-    public void setBoundsInScreen(Rect bounds) {
-        mBoundsInScreen.set(bounds);
+        outBounds.set(mRegionInScreen.getBounds());
     }
 
     /**
@@ -522,7 +534,7 @@
         parcel.writeInt(mBooleanProperties);
         parcel.writeInt(mId);
         parcel.writeInt(mParentId);
-        mBoundsInScreen.writeToParcel(parcel, flags);
+        mRegionInScreen.writeToParcel(parcel, flags);
         parcel.writeCharSequence(mTitle);
         parcel.writeLong(mAnchorId);
 
@@ -552,7 +564,7 @@
         mBooleanProperties = other.mBooleanProperties;
         mId = other.mId;
         mParentId = other.mParentId;
-        mBoundsInScreen.set(other.mBoundsInScreen);
+        mRegionInScreen.set(other.mRegionInScreen);
         mTitle = other.mTitle;
         mAnchorId = other.mAnchorId;
 
@@ -574,7 +586,7 @@
         mBooleanProperties = parcel.readInt();
         mId = parcel.readInt();
         mParentId = parcel.readInt();
-        mBoundsInScreen.readFromParcel(parcel);
+        mRegionInScreen = Region.CREATOR.createFromParcel(parcel);
         mTitle = parcel.readCharSequence();
         mAnchorId = parcel.readLong();
 
@@ -621,7 +633,8 @@
         builder.append(", id=").append(mId);
         builder.append(", type=").append(typeToString(mType));
         builder.append(", layer=").append(mLayer);
-        builder.append(", bounds=").append(mBoundsInScreen);
+        builder.append(", region=").append(mRegionInScreen);
+        builder.append(", bounds=").append(mRegionInScreen.getBounds());
         builder.append(", focused=").append(isFocused());
         builder.append(", active=").append(isActive());
         builder.append(", pictureInPicture=").append(isInPictureInPictureMode());
@@ -661,7 +674,7 @@
         mBooleanProperties = 0;
         mId = UNDEFINED_WINDOW_ID;
         mParentId = UNDEFINED_WINDOW_ID;
-        mBoundsInScreen.setEmpty();
+        mRegionInScreen.setEmpty();
         mChildIds = null;
         mConnectionId = UNDEFINED_WINDOW_ID;
         mAnchorId = AccessibilityNodeInfo.UNDEFINED_NODE_ID;
@@ -716,7 +729,6 @@
         }
     }
 
-
     /**
      * Reports how this window differs from a possibly different state of the same window. The
      * argument must have the same id and type as neither of those properties may change.
@@ -739,8 +751,7 @@
         if (!TextUtils.equals(mTitle, other.mTitle)) {
             changes |= AccessibilityEvent.WINDOWS_CHANGE_TITLE;
         }
-
-        if (!mBoundsInScreen.equals(other.mBoundsInScreen)) {
+        if (!mRegionInScreen.equals(other.mRegionInScreen)) {
             changes |= AccessibilityEvent.WINDOWS_CHANGE_BOUNDS;
         }
         if (mLayer != other.mLayer) {
diff --git a/core/java/android/view/inputmethod/InputMethodSystemProperty.java b/core/java/android/view/inputmethod/InputMethodSystemProperty.java
index 0689806..e20c2fd 100644
--- a/core/java/android/view/inputmethod/InputMethodSystemProperty.java
+++ b/core/java/android/view/inputmethod/InputMethodSystemProperty.java
@@ -17,7 +17,6 @@
 package android.view.inputmethod;
 
 import android.annotation.Nullable;
-import android.annotation.TestApi;
 import android.content.ComponentName;
 import android.os.Build;
 import android.os.SystemProperties;
@@ -27,7 +26,6 @@
  *
  * @hide
  */
-@TestApi
 public class InputMethodSystemProperty {
     /**
      * System property key for the production use. The value must be either empty or a valid
@@ -78,6 +76,5 @@
      *
      * @hide
      */
-    @TestApi
     public static final boolean MULTI_CLIENT_IME_ENABLED = (sMultiClientImeComponentName != null);
 }
diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java
index c3c2c0d..2bf1ba5 100644
--- a/core/java/android/widget/ArrayAdapter.java
+++ b/core/java/android/widget/ArrayAdapter.java
@@ -50,7 +50,7 @@
  * override {@link #getView(int, View, ViewGroup)}
  * and inflate a view resource.
  * For a code example, see
- * the <a href="https://developer.android.com/samples/CustomChoiceList/index.html">
+ * the <a href="https://github.com/googlesamples/android-CustomChoiceList/#readme">
  * CustomChoiceList</a> sample.
  * </p>
  * <p>
diff --git a/core/java/com/android/internal/infra/ServiceConnector.java b/core/java/com/android/internal/infra/ServiceConnector.java
index 8136cfc..d6862f0 100644
--- a/core/java/com/android/internal/infra/ServiceConnector.java
+++ b/core/java/com/android/internal/infra/ServiceConnector.java
@@ -228,7 +228,7 @@
         private final int mUserId;
         private final @Nullable Function<IBinder, I> mBinderAsInterface;
 
-        private I mService = null;
+        private volatile I mService = null;
         private boolean mBinding = false;
         private boolean mUnbinding = false;
 
@@ -506,11 +506,12 @@
 
         void unbindJobThread() {
             cancelTimeout();
-            boolean wasBound = isBound();
+            I service = mService;
+            boolean wasBound = service != null;
             if (wasBound) {
-                onServiceConnectionStatusChanged(mService, false);
+                onServiceConnectionStatusChanged(service, false);
                 mContext.unbindService(mServiceConnection);
-                mService.asBinder().unlinkToDeath(this, 0);
+                service.asBinder().unlinkToDeath(this, 0);
                 mService = null;
             }
             mBinding = false;
@@ -543,7 +544,7 @@
         }
 
         @Override
-        public void onServiceConnected(@NonNull ComponentName name, @NonNull IBinder service) {
+        public void onServiceConnected(@NonNull ComponentName name, @NonNull IBinder binder) {
             if (mUnbinding) {
                 Log.i(LOG_TAG, "Ignoring onServiceConnected due to ongoing unbinding: " + this);
                 return;
@@ -551,14 +552,15 @@
             if (DEBUG) {
                 logTrace();
             }
-            mService = binderAsInterface(service);
+            I service = binderAsInterface(binder);
+            mService = service;
             mBinding = false;
             try {
-                service.linkToDeath(ServiceConnector.Impl.this, 0);
+                binder.linkToDeath(ServiceConnector.Impl.this, 0);
             } catch (RemoteException e) {
                 Log.e(LOG_TAG, "onServiceConnected " + name + ": ", e);
             }
-            onServiceConnectionStatusChanged(mService, true);
+            onServiceConnectionStatusChanged(service, true);
             processQueue();
         }
 
@@ -568,8 +570,11 @@
                 logTrace();
             }
             mBinding = true;
-            onServiceConnectionStatusChanged(mService, false);
-            mService = null;
+            I service = mService;
+            if (service != null) {
+                onServiceConnectionStatusChanged(service, false);
+                mService = null;
+            }
         }
 
         @Override
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 9b51c12..9d4cdc7 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -106,6 +106,14 @@
      */
     public static final int USE_APP_IMAGE_STARTUP_CACHE = 1 << 16;
 
+    /**
+     * When set, application specified signal handlers are not chained (i.e, ignored)
+     * by the runtime.
+     *
+     * Used for debugging only. Usage: set debug.ignoreappsignalhandler to 1.
+     */
+    public static final int DEBUG_IGNORE_APP_SIGNAL_HANDLER = 1 << 17;
+
     /** No external storage should be mounted. */
     public static final int MOUNT_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE;
     /** Default external storage should be mounted. */
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index fe66cf9..480ff4d 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -983,14 +983,7 @@
 
     @Override
     public void setBackgroundDrawable(Drawable background) {
-
-        // TODO: This should route through setWindowBackground, but late in the release to make this
-        // change.
-        if (mOriginalBackgroundDrawable != background) {
-            mOriginalBackgroundDrawable = background;
-            updateBackgroundDrawable();
-            drawableChanged();
-        }
+        setWindowBackground(background);
     }
 
     public void setWindowFrame(Drawable drawable) {
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 9fc79cb..364278d 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -194,9 +194,8 @@
     final ArrayMap<String, ArraySet<String>> mProductPrivAppPermissions = new ArrayMap<>();
     final ArrayMap<String, ArraySet<String>> mProductPrivAppDenyPermissions = new ArrayMap<>();
 
-    final ArrayMap<String, ArraySet<String>> mProductServicesPrivAppPermissions = new ArrayMap<>();
-    final ArrayMap<String, ArraySet<String>> mProductServicesPrivAppDenyPermissions =
-            new ArrayMap<>();
+    final ArrayMap<String, ArraySet<String>> mSystemExtPrivAppPermissions = new ArrayMap<>();
+    final ArrayMap<String, ArraySet<String>> mSystemExtPrivAppDenyPermissions = new ArrayMap<>();
 
     final ArrayMap<String, ArrayMap<String, Boolean>> mOemPermissions = new ArrayMap<>();
 
@@ -321,12 +320,20 @@
         return mProductPrivAppDenyPermissions.get(packageName);
     }
 
-    public ArraySet<String> getProductServicesPrivAppPermissions(String packageName) {
-        return mProductServicesPrivAppPermissions.get(packageName);
+    /**
+     * Read from "permission" tags in /system_ext/etc/permissions/*.xml
+     * @return Set of privileged permissions that are explicitly granted.
+     */
+    public ArraySet<String> getSystemExtPrivAppPermissions(String packageName) {
+        return mSystemExtPrivAppPermissions.get(packageName);
     }
 
-    public ArraySet<String> getProductServicesPrivAppDenyPermissions(String packageName) {
-        return mProductServicesPrivAppDenyPermissions.get(packageName);
+    /**
+     * Read from "deny-permission" tags in /system_ext/etc/permissions/*.xml
+     * @return Set of privileged permissions that are explicitly denied.
+     */
+    public ArraySet<String> getSystemExtPrivAppDenyPermissions(String packageName) {
+        return mSystemExtPrivAppDenyPermissions.get(packageName);
     }
 
     public Map<String, Boolean> getOemPermissions(String packageName) {
@@ -398,11 +405,11 @@
         readPermissions(Environment.buildPath(
                 Environment.getProductDirectory(), "etc", "permissions"), ALLOW_ALL);
 
-        // Allow /product_services to customize all system configs
+        // Allow /system_ext to customize all system configs
         readPermissions(Environment.buildPath(
-                Environment.getProductServicesDirectory(), "etc", "sysconfig"), ALLOW_ALL);
+                Environment.getSystemExtDirectory(), "etc", "sysconfig"), ALLOW_ALL);
         readPermissions(Environment.buildPath(
-                Environment.getProductServicesDirectory(), "etc", "permissions"), ALLOW_ALL);
+                Environment.getSystemExtDirectory(), "etc", "permissions"), ALLOW_ALL);
     }
 
     void readPermissions(File libraryDir, int permissionFlag) {
@@ -848,7 +855,7 @@
                     } break;
                     case "privapp-permissions": {
                         if (allowPrivappPermissions) {
-                            // privapp permissions from system, vendor, product and product_services
+                            // privapp permissions from system, vendor, product and system_ext
                             // partitions are stored separately. This is to prevent xml files in
                             // the vendor partition from granting permissions to priv apps in the
                             // system partition and vice versa.
@@ -858,17 +865,17 @@
                                     Environment.getOdmDirectory().toPath() + "/");
                             boolean product = permFile.toPath().startsWith(
                                     Environment.getProductDirectory().toPath() + "/");
-                            boolean productServices = permFile.toPath().startsWith(
-                                    Environment.getProductServicesDirectory().toPath() + "/");
+                            boolean systemExt = permFile.toPath().startsWith(
+                                    Environment.getSystemExtDirectory().toPath() + "/");
                             if (vendor) {
                                 readPrivAppPermissions(parser, mVendorPrivAppPermissions,
                                         mVendorPrivAppDenyPermissions);
                             } else if (product) {
                                 readPrivAppPermissions(parser, mProductPrivAppPermissions,
                                         mProductPrivAppDenyPermissions);
-                            } else if (productServices) {
-                                readPrivAppPermissions(parser, mProductServicesPrivAppPermissions,
-                                        mProductServicesPrivAppDenyPermissions);
+                            } else if (systemExt) {
+                                readPrivAppPermissions(parser, mSystemExtPrivAppPermissions,
+                                        mSystemExtPrivAppDenyPermissions);
                             } else {
                                 readPrivAppPermissions(parser, mPrivAppPermissions,
                                         mPrivAppDenyPermissions);
diff --git a/core/jni/android/graphics/Bitmap.h b/core/jni/android/graphics/Bitmap.h
index 6934d26..06e31a1 100644
--- a/core/jni/android/graphics/Bitmap.h
+++ b/core/jni/android/graphics/Bitmap.h
@@ -18,8 +18,9 @@
 
 #include <jni.h>
 #include <android/bitmap.h>
-#include <SkBitmap.h>
-#include <SkImageInfo.h>
+
+class SkBitmap;
+struct SkImageInfo;
 
 namespace android {
 
@@ -34,8 +35,8 @@
 };
 
 jobject createBitmap(JNIEnv* env, Bitmap* bitmap,
-            int bitmapCreateFlags, jbyteArray ninePatchChunk = NULL,
-            jobject ninePatchInsets = NULL, int density = -1);
+            int bitmapCreateFlags, jbyteArray ninePatchChunk = nullptr,
+            jobject ninePatchInsets = nullptr, int density = -1);
 
 
 void toSkBitmap(jlong bitmapHandle, SkBitmap* outBitmap);
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index 55abc93..58c5871 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -16,7 +16,6 @@
 
 #include "jni.h"
 #include <nativehelper/JNIHelp.h>
-#include "GraphicsJNI.h"
 
 #include <math.h>
 #include <stdio.h>
@@ -33,6 +32,7 @@
 #include <SkBitmap.h>
 
 #include "core_jni_helpers.h"
+#include "android/graphics/Bitmap.h"
 
 #undef LOG_TAG
 #define LOG_TAG "OpenGLUtil"
@@ -43,6 +43,10 @@
 
 namespace android {
 
+static void doThrowIAE(JNIEnv* env, const char* msg = nullptr) {
+    jniThrowException(env, "java/lang/IllegalArgumentException", msg);
+}
+
 static inline
 void mx4transform(float x, float y, float z, float w, const float* pM, float* pDest) {
     pDest[0] = pM[0 + 4 * 0] * x + pM[0 + 4 * 1] * y + pM[0 + 4 * 2] * z + pM[0 + 4 * 3] * w;
@@ -706,7 +710,7 @@
         jlong bitmapPtr)
 {
     SkBitmap nativeBitmap;
-    bitmap::toBitmap(bitmapPtr).getSkBitmap(&nativeBitmap);
+    bitmap::toSkBitmap(bitmapPtr, &nativeBitmap);
     return getInternalFormat(nativeBitmap.colorType());
 }
 
@@ -714,7 +718,7 @@
         jlong bitmapPtr)
 {
     SkBitmap nativeBitmap;
-    bitmap::toBitmap(bitmapPtr).getSkBitmap(&nativeBitmap);
+    bitmap::toSkBitmap(bitmapPtr, &nativeBitmap);
     return getType(nativeBitmap.colorType());
 }
 
@@ -723,7 +727,7 @@
         jlong bitmapPtr, jint type, jint border)
 {
     SkBitmap bitmap;
-    bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
+    bitmap::toSkBitmap(bitmapPtr, &bitmap);
     SkColorType colorType = bitmap.colorType();
     if (internalformat < 0) {
         internalformat = getInternalFormat(colorType);
@@ -751,7 +755,7 @@
         jlong bitmapPtr, jint format, jint type)
 {
     SkBitmap bitmap;
-    bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
+    bitmap::toSkBitmap(bitmapPtr, &bitmap);
     SkColorType colorType = bitmap.colorType();
     int internalFormat = getInternalFormat(colorType);
     if (format < 0) {
diff --git a/core/jni/android_app_ActivityThread.cpp b/core/jni/android_app_ActivityThread.cpp
index 93f2525..3a08148 100644
--- a/core/jni/android_app_ActivityThread.cpp
+++ b/core/jni/android_app_ActivityThread.cpp
@@ -15,7 +15,6 @@
  */
 
 #include "jni.h"
-#include "GraphicsJNI.h"
 #include <nativehelper/JNIHelp.h>
 
 #include <minikin/Layout.h>
diff --git a/core/jni/android_nio_utils.h b/core/jni/android_nio_utils.h
index aa75dd0..4aaa0a7 100644
--- a/core/jni/android_nio_utils.h
+++ b/core/jni/android_nio_utils.h
@@ -17,7 +17,7 @@
 #ifndef _ANDROID_NIO_UTILS_H_
 #define _ANDROID_NIO_UTILS_H_
 
-#include <android_runtime/AndroidRuntime.h>
+#include <nativehelper/JNIHelp.h>
 
 namespace android {
 
@@ -68,12 +68,12 @@
     AutoBufferPointer() = delete;
     AutoBufferPointer(AutoBufferPointer&) = delete;
     AutoBufferPointer& operator=(AutoBufferPointer&) = delete;
-    static void* operator new(std::size_t);
-    static void* operator new[](std::size_t);
-    static void* operator new(std::size_t, void*);
-    static void* operator new[](std::size_t, void*);
-    static void operator delete(void*, std::size_t);
-    static void operator delete[](void*, std::size_t);
+    static void* operator new(size_t);
+    static void* operator new[](size_t);
+    static void* operator new(size_t, void*);
+    static void* operator new[](size_t, void*);
+    static void operator delete(void*, size_t);
+    static void operator delete[](void*, size_t);
 };
 
 }   /* namespace android */
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index d6d9391..bf4ffc7 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -161,7 +161,7 @@
       }
 
       // Generic idmap parameters
-      const char* argv[10];
+      const char* argv[11];
       int argc = 0;
       struct stat st;
 
@@ -193,8 +193,8 @@
         argv[argc++] = AssetManager::PRODUCT_OVERLAY_DIR;
       }
 
-      if (stat(AssetManager::PRODUCT_SERVICES_OVERLAY_DIR, &st) == 0) {
-        argv[argc++] = AssetManager::PRODUCT_SERVICES_OVERLAY_DIR;
+      if (stat(AssetManager::SYSTEM_EXT_OVERLAY_DIR, &st) == 0) {
+        argv[argc++] = AssetManager::SYSTEM_EXT_OVERLAY_DIR;
       }
 
       if (stat(AssetManager::ODM_OVERLAY_DIR, &st) == 0) {
@@ -235,8 +235,8 @@
     input_dirs.push_back(AssetManager::PRODUCT_OVERLAY_DIR);
   }
 
-  if (stat(AssetManager::PRODUCT_SERVICES_OVERLAY_DIR, &st) == 0) {
-    input_dirs.push_back(AssetManager::PRODUCT_SERVICES_OVERLAY_DIR);
+  if (stat(AssetManager::SYSTEM_EXT_OVERLAY_DIR, &st) == 0) {
+    input_dirs.push_back(AssetManager::SYSTEM_EXT_OVERLAY_DIR);
   }
 
   if (stat(AssetManager::ODM_OVERLAY_DIR, &st) == 0) {
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index df98cdc..0afbaa0e 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -99,7 +99,9 @@
 
 static struct error_offsets_t
 {
-    jclass mClass;
+    jclass mError;
+    jclass mOutOfMemory;
+    jclass mStackOverflow;
 } gErrorOffsets;
 
 // ----------------------------------------------------------------------------
@@ -207,6 +209,16 @@
     return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL;
 }
 
+static const char* GetErrorTypeName(JNIEnv* env, jthrowable error) {
+  if (env->IsInstanceOf(error, gErrorOffsets.mOutOfMemory)) {
+    return "OutOfMemoryError";
+  }
+  if (env->IsInstanceOf(error, gErrorOffsets.mStackOverflow)) {
+    return "StackOverflowError";
+  }
+  return nullptr;
+}
+
 // Report a java.lang.Error (or subclass). This will terminate the runtime by
 // calling FatalError with a message derived from the given error.
 static void report_java_lang_error_fatal_error(JNIEnv* env, jthrowable error,
@@ -216,7 +228,7 @@
 
     // Try to get the exception string. Sometimes logcat isn't available,
     // so try to add it to the abort message.
-    std::string exc_msg = "(Unknown exception message)";
+    std::string exc_msg;
     {
         ScopedLocalRef<jclass> exc_class(env, env->GetObjectClass(error));
         jmethodID method_id = env->GetMethodID(exc_class.get(), "toString",
@@ -225,15 +237,36 @@
                 env,
                 reinterpret_cast<jstring>(
                         env->CallObjectMethod(error, method_id)));
-        env->ExceptionClear();  // Just for good measure.
+        ScopedLocalRef<jthrowable> new_error(env, nullptr);
+        bool got_jstr = false;
+        if (env->ExceptionCheck()) {
+            new_error = ScopedLocalRef<jthrowable>(env, env->ExceptionOccurred());
+            env->ExceptionClear();
+        }
         if (jstr.get() != nullptr) {
             ScopedUtfChars jstr_utf(env, jstr.get());
             if (jstr_utf.c_str() != nullptr) {
                 exc_msg = jstr_utf.c_str();
+                got_jstr = true;
             } else {
+                new_error = ScopedLocalRef<jthrowable>(env, env->ExceptionOccurred());
                 env->ExceptionClear();
             }
         }
+        if (!got_jstr) {
+            exc_msg = "(Unknown exception message)";
+            const char* orig_type = GetErrorTypeName(env, error);
+            if (orig_type != nullptr) {
+                exc_msg = base::StringPrintf("%s (Error was %s)", exc_msg.c_str(), orig_type);
+            }
+            const char* new_type =
+                new_error == nullptr ? nullptr : GetErrorTypeName(env, new_error.get());
+            if (new_type != nullptr) {
+                exc_msg = base::StringPrintf("%s (toString() error was %s)",
+                                             exc_msg.c_str(),
+                                             new_type);
+            }
+        }
     }
 
     env->Throw(error);
@@ -291,7 +324,7 @@
         ALOGE("%s", msg);
     }
 
-    if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) {
+    if (env->IsInstanceOf(excep, gErrorOffsets.mError)) {
         report_java_lang_error(env, excep, msg);
     }
 }
@@ -1440,10 +1473,13 @@
 
 static int int_register_android_os_BinderProxy(JNIEnv* env)
 {
-    jclass clazz = FindClassOrDie(env, "java/lang/Error");
-    gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
+    gErrorOffsets.mError = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/Error"));
+    gErrorOffsets.mOutOfMemory =
+        MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/OutOfMemoryError"));
+    gErrorOffsets.mStackOverflow =
+        MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/StackOverflowError"));
 
-    clazz = FindClassOrDie(env, kBinderProxyPathName);
+    jclass clazz = FindClassOrDie(env, kBinderProxyPathName);
     gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
     gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
             "(JJ)Landroid/os/BinderProxy;");
diff --git a/core/jni/android_view_RenderNodeAnimator.cpp b/core/jni/android_view_RenderNodeAnimator.cpp
index c9eac79..ca32b00 100644
--- a/core/jni/android_view_RenderNodeAnimator.cpp
+++ b/core/jni/android_view_RenderNodeAnimator.cpp
@@ -17,7 +17,6 @@
 #define LOG_TAG "OpenGLRenderer"
 
 #include "jni.h"
-#include "GraphicsJNI.h"
 #include <nativehelper/JNIHelp.h>
 #include <android_runtime/AndroidRuntime.h>
 
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 78dd1aa..a579229 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -21,10 +21,10 @@
 #include "android_util_Binder.h"
 #include "android_hardware_input_InputWindowHandle.h"
 #include "android/graphics/Bitmap.h"
-#include "android/graphics/GraphicsJNI.h"
 #include "android/graphics/Region.h"
 #include "core_jni_helpers.h"
 
+#include <android_runtime/AndroidRuntime.h>
 #include <android-base/chrono_utils.h>
 #include <nativehelper/JNIHelp.h>
 #include <nativehelper/ScopedUtfChars.h>
@@ -50,6 +50,14 @@
 
 namespace android {
 
+static void doThrowNPE(JNIEnv* env) {
+    jniThrowNullPointerException(env, NULL);
+}
+
+static void doThrowIAE(JNIEnv* env, const char* msg = nullptr) {
+    jniThrowException(env, "java/lang/IllegalArgumentException", msg);
+}
+
 static const char* const OutOfResourcesException =
     "android/view/Surface$OutOfResourcesException";
 
diff --git a/core/jni/com_android_internal_util_VirtualRefBasePtr.cpp b/core/jni/com_android_internal_util_VirtualRefBasePtr.cpp
index d20bae2..d629d63 100644
--- a/core/jni/com_android_internal_util_VirtualRefBasePtr.cpp
+++ b/core/jni/com_android_internal_util_VirtualRefBasePtr.cpp
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#include "jni.h"
 #include <nativehelper/JNIHelp.h>
+#include <utils/LightRefBase.h>
 #include "core_jni_helpers.h"
 
 namespace android {
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index 940ac22..5aea848 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -30,10 +30,6 @@
 #include <gui/GLConsumer.h>
 #include <gui/Surface.h>
 
-#include <GraphicsJNI.h>
-#include <SkBitmap.h>
-#include <SkPixelRef.h>
-
 #include <ui/ANativeObjectBase.h>
 
 namespace android {
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index e5d6393..ea4b252 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -100,8 +100,8 @@
   static const char* kVendorOverlaySubdir = "/system/vendor/overlay-subdir/";
   static const char* kSystemProductOverlayDir = "/system/product/overlay/";
   static const char* kProductOverlayDir = "/product/overlay";
-  static const char* kSystemProductServicesOverlayDir = "/system/product_services/overlay/";
-  static const char* kProductServicesOverlayDir = "/product_services/overlay";
+  static const char* kSystemSystemExtOverlayDir = "/system/system_ext/overlay/";
+  static const char* kSystemExtOverlayDir = "/system_ext/overlay";
   static const char* kSystemOdmOverlayDir = "/system/odm/overlay";
   static const char* kOdmOverlayDir = "/odm/overlay";
   static const char* kSystemOemOverlayDir = "/system/oem/overlay";
@@ -113,8 +113,8 @@
        || android::base::StartsWith(path, kVendorOverlayDir)
        || android::base::StartsWith(path, kSystemProductOverlayDir)
        || android::base::StartsWith(path, kProductOverlayDir)
-       || android::base::StartsWith(path, kSystemProductServicesOverlayDir)
-       || android::base::StartsWith(path, kProductServicesOverlayDir)
+       || android::base::StartsWith(path, kSystemSystemExtOverlayDir)
+       || android::base::StartsWith(path, kSystemExtOverlayDir)
        || android::base::StartsWith(path, kSystemOdmOverlayDir)
        || android::base::StartsWith(path, kOdmOverlayDir)
        || android::base::StartsWith(path, kSystemOemOverlayDir)
diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto
index 784e854..c534aa4 100644
--- a/core/proto/android/server/jobscheduler.proto
+++ b/core/proto/android/server/jobscheduler.proto
@@ -231,15 +231,6 @@
     // will use heartbeats, false will use a rolling window.
     optional bool use_heartbeats = 23;
 
-    message TimeController {
-        option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
-        // Whether or not TimeController should skip setting wakeup alarms for jobs that aren't
-        // ready now.
-        optional bool skip_not_ready_jobs = 1;
-    }
-    optional TimeController time_controller = 25;
-
     message QuotaController {
         option (.android.msg_privacy).dest = DEST_AUTOMATIC;
 
@@ -304,6 +295,15 @@
     }
     optional QuotaController quota_controller = 24;
 
+    message TimeController {
+        option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+        // Whether or not TimeController should skip setting wakeup alarms for jobs that aren't
+        // ready now.
+        reserved 1; // skip_not_ready_jobs
+    }
+    optional TimeController time_controller = 25;
+
     // Max number of jobs, when screen is ON.
     optional MaxJobCountsPerMemoryTrimLevelProto max_job_counts_screen_on = 26;
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index ebf5b93..40acebc 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4981,6 +4981,7 @@
         <service
                 android:name="com.android.server.autofill.AutofillCompatAccessibilityService"
                 android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
+                android:visibleToInstantApps="true"
                 android:exported="true">
             <meta-data
                     android:name="android.accessibilityservice"
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index bc7e3b7..3b12753 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1115,6 +1115,22 @@
          regularly selected color mode will be used if this value is negative. -->
     <integer name="config_accessibilityColorMode">-1</integer>
 
+    <!-- The following two arrays specify which color space to use for display composition when a
+         certain color mode is active.
+         Composition color spaces are defined in android.view.Display.COLOR_MODE_xxx, and color
+         modes are defined in ColorDisplayManager.COLOR_MODE_xxx and
+         ColorDisplayManager.VENDOR_COLOR_MODE_xxx.
+         The color space COLOR_MODE_DEFAULT (0) lets the system select the most appropriate
+         composition color space for currently displayed content. Other values (e.g.,
+         COLOR_MODE_SRGB) override system selection; these other color spaces must be supported by
+         the device for for display composition.
+         If a color mode does not have a corresponding color space specified in this array, the
+         currently set composition color space will not be modified.-->
+    <integer-array name="config_displayCompositionColorModes">
+    </integer-array>
+    <integer-array name="config_displayCompositionColorSpaces">
+    </integer-array>
+
     <!-- Indicate whether to allow the device to suspend when the screen is off
          due to the proximity sensor.  This resource should only be set to true
          if the sensor HAL correctly handles the proximity sensor as a wake-up source.
@@ -4133,8 +4149,27 @@
          for higher refresh rates to be automatically used out of the box -->
     <integer name="config_defaultPeakRefreshRate">60</integer>
 
-    <!-- The default brightness threshold that allows to switch to higher refresh rate -->
-    <integer name="config_brightnessThresholdOfPeakRefreshRate">-1</integer>
+    <!-- The display uses different gamma curves for different refresh rates. It's hard for panel
+         vendor to tune the curves to have exact same brightness for different refresh rate. So
+         flicker could be observed at switch time. The issue is worse at the gamma lower end.
+         In addition, human eyes are more sensitive to the flicker at darker environment.
+         To prevent flicker, we only support higher refresh rates if the display brightness is above
+         a threshold. And the darker environment could have higher threshold.
+         For example, no higher refresh rate if
+             display brightness <= disp0 && ambient brightness <= amb0
+             || display brightness <= disp1 && ambient brightness <= amb1 -->
+    <integer-array translatable="false" name="config_brightnessThresholdsOfPeakRefreshRate">
+         <!--
+           <item>disp0</item>
+           <item>disp1</item>
+        -->
+    </integer-array>
+    <integer-array translatable="false" name="config_ambientThresholdsOfPeakRefreshRate">
+         <!--
+           <item>amb0</item>
+           <item>amb1</item>
+        -->
+    </integer-array>
 
     <!-- The type of the light sensor to be used by the display framework for things like
          auto-brightness. If unset, then it just gets the default sensor of type TYPE_LIGHT. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b3b1b9f..c49092e 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3196,6 +3196,8 @@
   <java-symbol type="array" name="config_nightDisplayColorTemperatureCoefficientsNative" />
   <java-symbol type="array" name="config_availableColorModes" />
   <java-symbol type="integer" name="config_accessibilityColorMode" />
+  <java-symbol type="array" name="config_displayCompositionColorModes" />
+  <java-symbol type="array" name="config_displayCompositionColorSpaces" />
   <java-symbol type="bool" name="config_displayWhiteBalanceAvailable" />
   <java-symbol type="bool" name="config_displayWhiteBalanceEnabledDefault" />
   <java-symbol type="integer" name="config_displayWhiteBalanceColorTemperatureMin" />
@@ -3793,7 +3795,8 @@
 
   <!-- For high refresh rate displays -->
   <java-symbol type="integer" name="config_defaultPeakRefreshRate" />
-  <java-symbol type="integer" name="config_brightnessThresholdOfPeakRefreshRate" />
+  <java-symbol type="array" name="config_brightnessThresholdsOfPeakRefreshRate" />
+  <java-symbol type="array" name="config_ambientThresholdsOfPeakRefreshRate" />
 
   <!-- For Auto-Brightness -->
   <java-symbol type="string" name="config_displayLightSensorType" />
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index d2b18cb..51da0c8 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -416,7 +416,8 @@
                 IUiAutomationConnection iUiAutomationConnection, int i, boolean b, boolean b1,
                 boolean b2, boolean b3, Configuration configuration,
                 CompatibilityInfo compatibilityInfo, Map map, Bundle bundle1, String s1,
-                AutofillOptions ao, ContentCaptureOptions co) throws RemoteException {
+                AutofillOptions ao, ContentCaptureOptions co, long[] disableCompatChanges)
+                throws RemoteException {
         }
 
         @Override
diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteTokenizerTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteTokenizerTest.java
new file mode 100644
index 0000000..a9d1482
--- /dev/null
+++ b/core/tests/coretests/src/android/database/sqlite/SQLiteTokenizerTest.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+public class SQLiteTokenizerTest {
+    private List<String> getTokens(String sql) {
+        return SQLiteTokenizer.tokenize(sql, SQLiteTokenizer.OPTION_NONE);
+    }
+
+    private void checkTokens(String sql, String spaceSeparatedExpectedTokens) {
+        final List<String> expected = spaceSeparatedExpectedTokens == null
+                ? new ArrayList<>()
+                : Arrays.asList(spaceSeparatedExpectedTokens.split(" +"));
+
+        assertEquals(expected, getTokens(sql));
+    }
+
+    private void assertInvalidSql(String sql, String message) {
+        try {
+            getTokens(sql);
+            fail("Didn't throw InvalidSqlException");
+        } catch (IllegalArgumentException e) {
+            assertTrue("Expected " + e.getMessage() + " to contain " + message,
+                    e.getMessage().contains(message));
+        }
+    }
+
+    @Test
+    public void testWhitespaces() {
+        checkTokens("  select  \t\r\n a\n\n  ", "select a");
+        checkTokens("a b", "a b");
+    }
+
+    @Test
+    public void testComment() {
+        checkTokens("--\n", null);
+        checkTokens("a--\n", "a");
+        checkTokens("a--abcdef\n", "a");
+        checkTokens("a--abcdef\nx", "a x");
+        checkTokens("a--\nx", "a x");
+        assertInvalidSql("a--abcdef", "Unterminated comment");
+        assertInvalidSql("a--abcdef\ndef--", "Unterminated comment");
+
+        checkTokens("/**/", null);
+        assertInvalidSql("/*", "Unterminated comment");
+        assertInvalidSql("/*/", "Unterminated comment");
+        assertInvalidSql("/*\n* /*a", "Unterminated comment");
+        checkTokens("a/**/", "a");
+        checkTokens("/**/b", "b");
+        checkTokens("a/**/b", "a b");
+        checkTokens("a/* -- \n* /* **/b", "a b");
+    }
+
+    @Test
+    public void testStrings() {
+        assertInvalidSql("'", "Unterminated quote");
+        assertInvalidSql("a'", "Unterminated quote");
+        assertInvalidSql("a'''", "Unterminated quote");
+        assertInvalidSql("a''' ", "Unterminated quote");
+        checkTokens("''", null);
+        checkTokens("''''", null);
+        checkTokens("a''''b", "a b");
+        checkTokens("a' '' 'b", "a b");
+        checkTokens("'abc'", null);
+        checkTokens("'abc\ndef'", null);
+        checkTokens("a'abc\ndef'", "a");
+        checkTokens("'abc\ndef'b", "b");
+        checkTokens("a'abc\ndef'b", "a b");
+        checkTokens("a'''abc\nd''ef'''b", "a b");
+    }
+
+    @Test
+    public void testDoubleQuotes() {
+        assertInvalidSql("\"", "Unterminated quote");
+        assertInvalidSql("a\"", "Unterminated quote");
+        assertInvalidSql("a\"\"\"", "Unterminated quote");
+        assertInvalidSql("a\"\"\" ", "Unterminated quote");
+        checkTokens("\"\"", "");
+        checkTokens("\"\"\"\"", "\"");
+        checkTokens("a\"\"\"\"b", "a \" b");
+        checkTokens("a\"\t\"\"\t\"b", "a  \t\"\t  b");
+        checkTokens("\"abc\"", "abc");
+        checkTokens("\"abc\ndef\"", "abc\ndef");
+        checkTokens("a\"abc\ndef\"", "a abc\ndef");
+        checkTokens("\"abc\ndef\"b", "abc\ndef b");
+        checkTokens("a\"abc\ndef\"b", "a abc\ndef b");
+        checkTokens("a\"\"\"abc\nd\"\"ef\"\"\"b", "a \"abc\nd\"ef\" b");
+    }
+
+    @Test
+    public void testBackQuotes() {
+        assertInvalidSql("`", "Unterminated quote");
+        assertInvalidSql("a`", "Unterminated quote");
+        assertInvalidSql("a```", "Unterminated quote");
+        assertInvalidSql("a``` ", "Unterminated quote");
+        checkTokens("``", "");
+        checkTokens("````", "`");
+        checkTokens("a````b", "a ` b");
+        checkTokens("a`\t``\t`b", "a  \t`\t  b");
+        checkTokens("`abc`", "abc");
+        checkTokens("`abc\ndef`", "abc\ndef");
+        checkTokens("a`abc\ndef`", "a abc\ndef");
+        checkTokens("`abc\ndef`b", "abc\ndef b");
+        checkTokens("a`abc\ndef`b", "a abc\ndef b");
+        checkTokens("a```abc\nd``ef```b", "a `abc\nd`ef` b");
+    }
+
+    @Test
+    public void testBrackets() {
+        assertInvalidSql("[", "Unterminated quote");
+        assertInvalidSql("a[", "Unterminated quote");
+        assertInvalidSql("a[ ", "Unterminated quote");
+        assertInvalidSql("a[[ ", "Unterminated quote");
+        checkTokens("[]", "");
+        checkTokens("[[]", "[");
+        checkTokens("a[[]b", "a [ b");
+        checkTokens("a[\t[\t]b", "a  \t[\t  b");
+        checkTokens("[abc]", "abc");
+        checkTokens("[abc\ndef]", "abc\ndef");
+        checkTokens("a[abc\ndef]", "a abc\ndef");
+        checkTokens("[abc\ndef]b", "abc\ndef b");
+        checkTokens("a[abc\ndef]b", "a abc\ndef b");
+        checkTokens("a[[abc\nd[ef[]b", "a [abc\nd[ef[ b");
+    }
+
+    @Test
+    public void testSemicolons() {
+        assertInvalidSql(";", "Semicolon is not allowed");
+        assertInvalidSql("  ;", "Semicolon is not allowed");
+        assertInvalidSql(";  ", "Semicolon is not allowed");
+        assertInvalidSql("-;-", "Semicolon is not allowed");
+        checkTokens("--;\n", null);
+        checkTokens("/*;*/", null);
+        checkTokens("';'", null);
+        checkTokens("[;]", ";");
+        checkTokens("`;`", ";");
+    }
+
+    @Test
+    public void testTokens() {
+        checkTokens("a,abc,a00b,_1,_123,abcdef", "a abc a00b _1 _123 abcdef");
+        checkTokens("a--\nabc/**/a00b''_1'''ABC'''`_123`abc[d]\"e\"f",
+                "a abc a00b _1 _123 abc d e f");
+    }
+}
diff --git a/core/tests/coretests/src/android/view/WindowInfoTest.java b/core/tests/coretests/src/android/view/WindowInfoTest.java
index 037a0d9..05e8bd8 100644
--- a/core/tests/coretests/src/android/view/WindowInfoTest.java
+++ b/core/tests/coretests/src/android/view/WindowInfoTest.java
@@ -91,7 +91,7 @@
         assertFalse(w.focused);
         assertFalse(w.inPictureInPicture);
         assertFalse(w.hasFlagWatchOutsideTouch);
-        assertTrue(w.boundsInScreen.isEmpty());
+        assertTrue(w.regionInScreen.isEmpty());
     }
 
     @SmallTest
@@ -114,7 +114,7 @@
         equality &= w1.childTokens.equals(w2.childTokens);
         equality &= w1.parentToken == w2.parentToken;
         equality &= w1.activityToken == w2.activityToken;
-        equality &= w1.boundsInScreen.equals(w2.boundsInScreen);
+        equality &= w1.regionInScreen.equals(w2.regionInScreen);
         return equality;
     }
 
@@ -132,6 +132,6 @@
         windowInfo.focused = true;
         windowInfo.inPictureInPicture = true;
         windowInfo.hasFlagWatchOutsideTouch = true;
-        windowInfo.boundsInScreen.set(0, 0, 1080, 1080);
+        windowInfo.regionInScreen.set(0, 0, 1080, 1080);
     }
 }
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
index 683d16b..adaae5c 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
@@ -21,6 +21,7 @@
 import android.content.pm.ParceledListSlice;
 import android.graphics.Region;
 import android.os.Bundle;
+import android.os.IBinder;
 
 import java.util.List;
 
@@ -134,4 +135,8 @@
     public boolean isFingerprintGestureDetectionAvailable() {
         return false;
     }
+
+    public IBinder getOverlayWindowToken(int displayId) {
+        return null;
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
index aadfcbc..abee1da2 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
@@ -71,7 +71,7 @@
 import com.android.internal.accessibility.AccessibilityShortcutController.FrameworkObjectProvider;
 import com.android.internal.util.test.FakeSettingsProvider;
 
-import org.junit.After;
+import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -136,6 +136,7 @@
 
         mContentResolver = new MockContentResolver(mContext);
         mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+        FakeSettingsProvider.clearSettingsProvider();
         when(mContext.getContentResolver()).thenReturn(mContentResolver);
 
         when(mAccessibilityManagerService.getInstalledAccessibilityServiceList(anyInt()))
@@ -193,8 +194,9 @@
         when(mTextToSpeech.getVoice()).thenReturn(mVoice);
     }
 
-    @After
-    public void tearDown() {
+    @AfterClass
+    public static void cleanUpSettingsProvider() {
+        FakeSettingsProvider.clearSettingsProvider();
     }
 
     @Test
diff --git a/core/tests/coretests/src/com/android/internal/policy/DecorViewTest.java b/core/tests/coretests/src/com/android/internal/policy/DecorViewTest.java
new file mode 100644
index 0000000..f66717e
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/policy/DecorViewTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.policy;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.frameworks.coretests.R;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+
+public class DecorViewTest {
+
+    private Context mContext;
+    private DecorView mDecorView;
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getInstrumentation().getContext();
+        PhoneWindow phoneWindow = new PhoneWindow(mContext);
+        mDecorView = (DecorView) phoneWindow.getDecorView();
+    }
+
+    @Test
+    public void setBackgroundDrawableSameAsSetWindowBackground() {
+        Drawable bitmapDrawable = mContext.getResources()
+                .getDrawable(R.drawable.test16x12, mContext.getTheme());
+        int w = 16;
+        int h = 12;
+        Bitmap expectedBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+
+        mDecorView.setWindowBackground(bitmapDrawable);
+        Canvas testCanvas = new Canvas(expectedBitmap);
+        mDecorView.draw(testCanvas);
+        testCanvas.release();
+
+        Drawable expectedBackground = mDecorView.getBackground();
+
+        mDecorView.setBackgroundDrawable(bitmapDrawable);
+        Bitmap resultBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+        Canvas resCanvas = new Canvas(resultBitmap);
+        mDecorView.draw(resCanvas);
+        resCanvas.release();
+
+        // Check that the drawable is the same.
+        assertThat(mDecorView.getBackground()).isEqualTo(expectedBackground);
+        assertThat(mDecorView.getBackground()).isEqualTo(bitmapDrawable);
+
+        // Check that canvas is the same.
+        int[] expPixels = new int[w * h];
+        int[] resPixels = new int[w * h];
+        resultBitmap.getPixels(resPixels, 0, w, 0, 0, w, h);
+        expectedBitmap.getPixels(expPixels, 0, w, 0, 0, w, h);
+        assertThat(Arrays.toString(expPixels)).isEqualTo(Arrays.toString(resPixels));
+    }
+}
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 4755cb8..f7c8337 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -74,7 +74,7 @@
 const char* AssetManager::IDMAP_BIN = "/system/bin/idmap";
 const char* AssetManager::VENDOR_OVERLAY_DIR = "/vendor/overlay";
 const char* AssetManager::PRODUCT_OVERLAY_DIR = "/product/overlay";
-const char* AssetManager::PRODUCT_SERVICES_OVERLAY_DIR = "/product_services/overlay";
+const char* AssetManager::SYSTEM_EXT_OVERLAY_DIR = "/system_ext/overlay";
 const char* AssetManager::ODM_OVERLAY_DIR = "/odm/overlay";
 const char* AssetManager::OEM_OVERLAY_DIR = "/oem/overlay";
 const char* AssetManager::OVERLAY_THEME_DIR_PROPERTY = "ro.boot.vendor.overlay.theme";
@@ -575,7 +575,7 @@
                         mZipSet.setZipResourceTableAsset(ap.path, ass);
                 }
             }
-            
+
             if (nextEntryIdx == 0 && ass != NULL) {
                 // If this is the first resource table in the asset
                 // manager, then we are going to cache it so that we
diff --git a/libs/androidfw/include/androidfw/AssetManager.h b/libs/androidfw/include/androidfw/AssetManager.h
index 66fba26b..ce0985b 100644
--- a/libs/androidfw/include/androidfw/AssetManager.h
+++ b/libs/androidfw/include/androidfw/AssetManager.h
@@ -61,7 +61,7 @@
     static const char* IDMAP_BIN;
     static const char* VENDOR_OVERLAY_DIR;
     static const char* PRODUCT_OVERLAY_DIR;
-    static const char* PRODUCT_SERVICES_OVERLAY_DIR;
+    static const char* SYSTEM_EXT_OVERLAY_DIR;
     static const char* ODM_OVERLAY_DIR;
     static const char* OEM_OVERLAY_DIR;
     /*
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 7269bca..16ec877 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -29,7 +29,6 @@
 #include "SkPaint.h"
 #include "SkPath.h"
 #include "SkRect.h"
-#include "SkTDArray.h"
 #include "SkTemplates.h"
 
 #include <vector>
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index e50428b..40fbdff 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -16,6 +16,8 @@
 
 #include "RenderProxy.h"
 
+#include <gui/Surface.h>
+
 #include "DeferredLayerUpdater.h"
 #include "DisplayList.h"
 #include "Properties.h"
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index a0f08cb..c3eb6ed 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -19,7 +19,6 @@
 
 #include <SkBitmap.h>
 #include <cutils/compiler.h>
-#include <gui/Surface.h>
 #include <utils/Functor.h>
 
 #include "../FrameMetricsObserver.h"
@@ -30,6 +29,7 @@
 
 namespace android {
 class GraphicBuffer;
+class Surface;
 
 namespace uirenderer {
 
diff --git a/libs/hwui/renderthread/VulkanSurface.h b/libs/hwui/renderthread/VulkanSurface.h
index 5fa860a..5717bb3 100644
--- a/libs/hwui/renderthread/VulkanSurface.h
+++ b/libs/hwui/renderthread/VulkanSurface.h
@@ -17,6 +17,7 @@
 
 #include <system/graphics.h>
 #include <system/window.h>
+#include <ui/BufferQueueDefs.h>
 #include <vulkan/vulkan.h>
 
 #include <SkRefCnt.h>
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index f5330b4..1cc246b 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -191,19 +191,6 @@
     public static final String MODE_CHANGED_ACTION = "android.location.MODE_CHANGED";
 
     /**
-     * Broadcast intent action when {@link android.provider.Settings.Secure#LOCATION_MODE} is
-     * about to be changed through Settings app or Quick Settings.
-     * For use with the {@link android.provider.Settings.Secure#LOCATION_MODE} API.
-     * If you're interacting with {@link #isProviderEnabled(String)}, use
-     * {@link #PROVIDERS_CHANGED_ACTION} instead.
-     *
-     * @deprecated Do not use.
-     * @hide
-     */
-    @Deprecated
-    public static final String MODE_CHANGING_ACTION = "com.android.settings.location.MODE_CHANGING";
-
-    /**
      * Broadcast intent action indicating that a high power location requests
      * has either started or stopped being active.  The current state of
      * active location requests should be read from AppOpsManager using
@@ -216,17 +203,10 @@
 
     /**
      * Broadcast intent action for Settings app to inject a footer at the bottom of location
-     * settings.
+     * settings. This is for use only by apps that are included in the system image.
      *
-     * <p>This broadcast is used for two things:
-     * <ol>
-     *     <li>For receivers to inject a footer with provided text. This is for use only by apps
-     *         that are included in the system image. </li>
-     *     <li>For receivers to know their footer is injected under location settings.</li>
-     * </ol>
-     *
-     * <p>To inject a footer to location settings, you must declare a broadcast receiver of
-     * {@link LocationManager#SETTINGS_FOOTER_DISPLAYED_ACTION} in the manifest as so:
+     * <p>To inject a footer to location settings, you must declare a broadcast receiver for
+     * this action in the manifest:
      * <pre>
      *     &lt;receiver android:name="com.example.android.footer.MyFooterInjector"&gt;
      *         &lt;intent-filter&gt;
@@ -238,10 +218,8 @@
      *     &lt;/receiver&gt;
      * </pre>
      *
-     * <p>On entering location settings, Settings app will send a
-     * {@link #SETTINGS_FOOTER_DISPLAYED_ACTION} broadcast to receivers whose footer is successfully
-     * injected. On leaving location settings, the footer becomes not visible to users. Settings app
-     * will send a {@link #SETTINGS_FOOTER_REMOVED_ACTION} broadcast to those receivers.
+     * <p>This broadcast receiver will never actually be invoked. See also
+     * {#METADATA_SETTINGS_FOOTER_STRING}.
      *
      * @hide
      */
@@ -249,16 +227,6 @@
             "com.android.settings.location.DISPLAYED_FOOTER";
 
     /**
-     * Broadcast intent action when location settings footer is not visible to users.
-     *
-     * <p>See {@link #SETTINGS_FOOTER_DISPLAYED_ACTION} for more detail on how to use.
-     *
-     * @hide
-     */
-    public static final String SETTINGS_FOOTER_REMOVED_ACTION =
-            "com.android.settings.location.REMOVED_FOOTER";
-
-    /**
      * Metadata name for {@link LocationManager#SETTINGS_FOOTER_DISPLAYED_ACTION} broadcast
      * receivers to specify a string resource id as location settings footer text. This is for use
      * only by apps that are included in the system image.
diff --git a/media/Android.bp b/media/Android.bp
index 4f9671f..29064ad 100644
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -33,6 +33,8 @@
         "framework_media_annotation",
         "android_system_stubs_current",
     ],
+
+    plugins: ["java_api_finder"],
 }
 
 filegroup {
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index ce9b07d..0254c97 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -1788,6 +1788,9 @@
      * @hide
      */
     public int getPortId() {
+        if (mNativeRecorderInJavaObj == 0) {
+            return 0;
+        }
         return native_getPortId();
     }
 
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 63b22df..bf7da23 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -720,7 +720,7 @@
 
     /**
      * Sets the width and height of the video to be captured.  Must be called
-     * after setVideoSource(). Call this after setOutFormat() but before
+     * after setVideoSource(). Call this after setOutputFormat() but before
      * prepare().
      *
      * @param width the width of the video to be captured
@@ -733,7 +733,7 @@
 
     /**
      * Sets the frame rate of the video to be captured.  Must be called
-     * after setVideoSource(). Call this after setOutFormat() but before
+     * after setVideoSource(). Call this after setOutputFormat() but before
      * prepare().
      *
      * @param rate the number of frames per second of video to capture
@@ -748,7 +748,7 @@
 
     /**
      * Sets the maximum duration (in ms) of the recording session.
-     * Call this after setOutFormat() but before prepare().
+     * Call this after setOutputFormat() but before prepare().
      * After recording reaches the specified duration, a notification
      * will be sent to the {@link android.media.MediaRecorder.OnInfoListener}
      * with a "what" code of {@link #MEDIA_RECORDER_INFO_MAX_DURATION_REACHED}
@@ -769,7 +769,7 @@
 
     /**
      * Sets the maximum filesize (in bytes) of the recording session.
-     * Call this after setOutFormat() but before prepare().
+     * Call this after setOutputFormat() but before prepare().
      * After recording reaches the specified filesize, a notification
      * will be sent to the {@link android.media.MediaRecorder.OnInfoListener}
      * with a "what" code of {@link #MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED}
@@ -1624,6 +1624,9 @@
      * @hide
      */
     public int getPortId() {
+        if (mNativeContext == 0) {
+            return 0;
+        }
         return native_getPortId();
     }
 
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index f13a64c..5dcbb05 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -23,6 +23,9 @@
 import android.os.Parcelable;
 import android.text.TextUtils;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -53,6 +56,8 @@
     final String mDescription;
     @Nullable
     final String mClientPackageName;
+    @NonNull
+    final List<String> mSupportedCategories;
     @Nullable
     final Bundle mExtras;
 
@@ -62,6 +67,7 @@
         mName = builder.mName;
         mDescription = builder.mDescription;
         mClientPackageName = builder.mClientPackageName;
+        mSupportedCategories = builder.mSupportedCategories;
         mExtras = builder.mExtras;
     }
 
@@ -71,6 +77,7 @@
         mName = in.readString();
         mDescription = in.readString();
         mClientPackageName = in.readString();
+        mSupportedCategories = in.createStringArrayList();
         mExtras = in.readBundle();
     }
 
@@ -103,13 +110,14 @@
                 && Objects.equals(mName, other.mName)
                 && Objects.equals(mDescription, other.mDescription)
                 && Objects.equals(mClientPackageName, other.mClientPackageName)
+                && Objects.equals(mSupportedCategories, other.mSupportedCategories)
                 //TODO: This will be evaluated as false in most cases. Try not to.
                 && Objects.equals(mExtras, other.mExtras);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mId, mName, mDescription);
+        return Objects.hash(mId, mName, mDescription, mSupportedCategories);
     }
 
     @NonNull
@@ -146,11 +154,38 @@
         return mClientPackageName;
     }
 
+    /**
+     * Gets the supported categories of the route.
+     */
+    @NonNull
+    public List<String> getSupportedCategories() {
+        return mSupportedCategories;
+    }
+
     @Nullable
     public Bundle getExtras() {
         return mExtras;
     }
 
+    //TODO: Move this if we re-define control category / selector things.
+    /**
+     * Returns true if the route supports at least one of the specified control categories
+     *
+     * @param controlCategories the list of control categories to consider
+     * @return true if the route supports at least one category
+     */
+    public boolean supportsControlCategory(@NonNull Collection<String> controlCategories) {
+        Objects.requireNonNull(controlCategories, "control categories must not be null");
+        for (String controlCategory : controlCategories) {
+            for (String supportedCategory : getSupportedCategories()) {
+                if (TextUtils.equals(controlCategory, supportedCategory)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -163,6 +198,7 @@
         dest.writeString(mName);
         dest.writeString(mDescription);
         dest.writeString(mClientPackageName);
+        dest.writeStringList(mSupportedCategories);
         dest.writeBundle(mExtras);
     }
 
@@ -187,6 +223,7 @@
         String mName;
         String mDescription;
         String mClientPackageName;
+        List<String> mSupportedCategories;
         Bundle mExtras;
 
         public Builder(@NonNull String id, @NonNull String name) {
@@ -198,6 +235,7 @@
             }
             setId(id);
             setName(name);
+            mSupportedCategories = new ArrayList<>();
         }
 
         public Builder(@NonNull MediaRoute2Info routeInfo) {
@@ -212,6 +250,7 @@
             setName(routeInfo.mName);
             mDescription = routeInfo.mDescription;
             setClientPackageName(routeInfo.mClientPackageName);
+            setSupportedCategories(routeInfo.mSupportedCategories);
             if (routeInfo.mExtras != null) {
                 mExtras = new Bundle(routeInfo.mExtras);
             }
@@ -273,6 +312,39 @@
         }
 
         /**
+         * Sets the supported categories of the route.
+         */
+        @NonNull
+        public Builder setSupportedCategories(@NonNull Collection<String> categories) {
+            mSupportedCategories = new ArrayList<>();
+            return addSupportedCategories(categories);
+        }
+
+        /**
+         * Adds supported categories for the route.
+         */
+        @NonNull
+        public Builder addSupportedCategories(@NonNull Collection<String> categories) {
+            Objects.requireNonNull(categories, "categories must not be null");
+            for (String category: categories) {
+                addSupportedCategory(category);
+            }
+            return this;
+        }
+
+        /**
+         * Add a supported category for the route.
+         */
+        @NonNull
+        public Builder addSupportedCategory(@NonNull String category) {
+            if (TextUtils.isEmpty(category)) {
+                throw new IllegalArgumentException("category must not be null or empty");
+            }
+            mSupportedCategories.add(category);
+            return this;
+        }
+
+        /**
          * Sets a bundle of extras for the route.
          */
         @NonNull
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index 5fc37a5..85105e0 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -38,6 +38,8 @@
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.Executor;
 
@@ -66,6 +68,8 @@
     List<MediaRoute2ProviderInfo> mProviders = Collections.emptyList();
     @NonNull
     List<MediaRoute2Info> mRoutes = Collections.emptyList();
+    @NonNull
+    ConcurrentMap<String, List<String>> mControlCategoryMap = new ConcurrentHashMap<>();
 
     /**
      * Gets an instance of media router manager that controls media route of other applications.
@@ -160,6 +164,8 @@
         return -1;
     }
 
+    //TODO: Use cache not to create array. For now, it's unclear when to purge the cache.
+    //Do this when we finalize how to set control categories.
     /**
      * Gets available routes for an application.
      *
@@ -167,8 +173,17 @@
      */
     @NonNull
     public List<MediaRoute2Info> getAvailableRoutes(@NonNull String packageName) {
-        //TODO: filter irrelevant routes.
-        return Collections.unmodifiableList(mRoutes);
+        List<String> controlCategories = mControlCategoryMap.get(packageName);
+        if (controlCategories == null) {
+            return Collections.emptyList();
+        }
+        List<MediaRoute2Info> routes = new ArrayList<>();
+        for (MediaRoute2Info route : mRoutes) {
+            if (route.supportsControlCategory(controlCategories)) {
+                routes.add(route);
+            }
+        }
+        return routes;
     }
 
     /**
@@ -310,11 +325,8 @@
         }
     }
 
-    void notifyControlCategoriesChanged(String packageName, List<String> categories) {
-        for (CallbackRecord record : mCallbacks) {
-            record.mExecutor.execute(
-                    () -> record.mCallback.onControlCategoriesChanged(packageName, categories));
-        }
+    void updateControlCategories(String packageName, List<String> categories) {
+        mControlCategoryMap.put(packageName, categories);
     }
 
     /**
@@ -346,15 +358,6 @@
         public void onRouteSelected(@NonNull String packageName, @Nullable MediaRoute2Info route) {}
 
         /**
-         * Called when the control categories of an application is changed.
-         *
-         * @param packageName the package name of the app that changed control categories
-         * @param categories the changed categories
-         */
-        public void onControlCategoriesChanged(@NonNull String packageName,
-                @NonNull List<String> categories) {}
-
-        /**
          * Called when the list of routes are changed.
          * A client may refresh available routes for each application.
          */
@@ -389,7 +392,7 @@
 
         @Override
         public void notifyControlCategoriesChanged(String packageName, List<String> categories) {
-            mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifyControlCategoriesChanged,
+            mHandler.sendMessage(obtainMessage(MediaRouter2Manager::updateControlCategories,
                     MediaRouter2Manager.this, packageName, categories));
         }
 
diff --git a/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java b/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java
index 2cdc6a8..1267aa8 100644
--- a/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java
+++ b/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java
@@ -32,19 +32,35 @@
     public static final String ROUTE_NAME1 = "Sample Route 1";
     public static final String ROUTE_ID2 = "route_id2";
     public static final String ROUTE_NAME2 = "Sample Route 2";
+
+    public static final String ROUTE_ID_SPECIAL_CATEGORY = "route_special_category";
+    public static final String ROUTE_NAME_SPECIAL_CATEGORY = "Special Category Route";
+
     public static final String ACTION_REMOVE_ROUTE =
             "com.android.mediarouteprovider.action_remove_route";
 
+    public static final String CATEGORY_SAMPLE =
+            "com.android.mediarouteprovider.CATEGORY_SAMPLE";
+    public static final String CATEGORY_SPECIAL =
+            "com.android.mediarouteprovider.CATEGORY_SPECIAL";
+
     Map<String, MediaRoute2Info> mRoutes = new HashMap<>();
 
     private void initializeRoutes() {
         MediaRoute2Info route1 = new MediaRoute2Info.Builder(ROUTE_ID1, ROUTE_NAME1)
+                .addSupportedCategory(CATEGORY_SAMPLE)
                 .build();
         MediaRoute2Info route2 = new MediaRoute2Info.Builder(ROUTE_ID2, ROUTE_NAME2)
+                .addSupportedCategory(CATEGORY_SAMPLE)
                 .build();
-
+        MediaRoute2Info routeSpecial =
+                new MediaRoute2Info.Builder(ROUTE_ID_SPECIAL_CATEGORY, ROUTE_NAME_SPECIAL_CATEGORY)
+                        .addSupportedCategory(CATEGORY_SAMPLE)
+                        .addSupportedCategory(CATEGORY_SPECIAL)
+                        .build();
         mRoutes.put(route1.getId(), route1);
         mRoutes.put(route2.getId(), route2);
+        mRoutes.put(routeSpecial.getId(), routeSpecial);
     }
 
     @Override
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
index 03b43e2..4282a5bc 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
@@ -58,9 +58,18 @@
     public static final String ROUTE_NAME1 = "Sample Route 1";
     public static final String ROUTE_ID2 = "route_id2";
     public static final String ROUTE_NAME2 = "Sample Route 2";
+
+    public static final String ROUTE_ID_SPECIAL_CATEGORY = "route_special_category";
+    public static final String ROUTE_NAME_SPECIAL_CATEGORY = "Special Category Route";
+
     public static final String ACTION_REMOVE_ROUTE =
             "com.android.mediarouteprovider.action_remove_route";
 
+    public static final String CATEGORY_SAMPLE =
+            "com.android.mediarouteprovider.CATEGORY_SAMPLE";
+    public static final String CATEGORY_SPECIAL =
+            "com.android.mediarouteprovider.CATEGORY_SPECIAL";
+
     private static final int TIMEOUT_MS = 5000;
 
     private Context mContext;
@@ -69,12 +78,13 @@
     private Executor mExecutor;
     private String mPackageName;
 
-    private static final List<String> TEST_CONTROL_CATEGORIES = new ArrayList();
-    private static final String CONTROL_CATEGORY_1 = "android.media.mediarouter.MEDIA1";
-    private static final String CONTROL_CATEGORY_2 = "android.media.mediarouter.MEDIA2";
+    private static final List<String> CONTROL_CATEGORIES_ALL = new ArrayList();
+    private static final List<String> CONTROL_CATEGORIES_SPECIAL = new ArrayList();
     static {
-        TEST_CONTROL_CATEGORIES.add(CONTROL_CATEGORY_1);
-        TEST_CONTROL_CATEGORIES.add(CONTROL_CATEGORY_2);
+        CONTROL_CATEGORIES_ALL.add(CATEGORY_SAMPLE);
+        CONTROL_CATEGORIES_ALL.add(CATEGORY_SPECIAL);
+
+        CONTROL_CATEGORIES_SPECIAL.add(CATEGORY_SPECIAL);
     }
 
     @Before
@@ -125,7 +135,7 @@
         // (Control requests shouldn't be used in this way.)
         InstrumentationRegistry.getInstrumentation().runOnMainSync(
                 (Runnable) () -> {
-                    mRouter.addCallback(TEST_CONTROL_CATEGORIES, mExecutor, mockRouterCallback);
+                    mRouter.addCallback(CONTROL_CATEGORIES_ALL, mExecutor, mockRouterCallback);
                     mRouter.sendControlRequest(
                             new MediaRoute2Info.Builder(ROUTE_ID2, ROUTE_NAME2).build(),
                             new Intent(ACTION_REMOVE_ROUTE));
@@ -138,8 +148,11 @@
         mManager.removeCallback(mockCallback);
     }
 
+    /**
+     * Tests if we get proper routes for application that has special control category.
+     */
     @Test
-    public void controlCategoryTest() throws Exception {
+    public void testControlCategory() throws Exception {
         MediaRouter2Manager.Callback mockCallback = mock(MediaRouter2Manager.Callback.class);
         mManager.addCallback(mExecutor, mockCallback);
 
@@ -147,12 +160,19 @@
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(
                 () -> {
-                    mRouter.addCallback(TEST_CONTROL_CATEGORIES, mExecutor, mockRouterCallback);
+                    mRouter.addCallback(CONTROL_CATEGORIES_SPECIAL,
+                            mExecutor, mockRouterCallback);
                     mRouter.removeCallback(mockRouterCallback);
                 }
         );
-        verify(mockCallback, timeout(TIMEOUT_MS).atLeastOnce())
-                .onControlCategoriesChanged(mPackageName, TEST_CONTROL_CATEGORIES);
+        verify(mockCallback, timeout(TIMEOUT_MS))
+                .onRouteListChanged(argThat(routes -> routes.size() > 0));
+
+        Map<String, MediaRoute2Info> routes =
+                createRouteMap(mManager.getAvailableRoutes(mPackageName));
+
+        Assert.assertEquals(1, routes.size());
+        Assert.assertNotNull(routes.get(ROUTE_ID_SPECIAL_CATEGORY));
 
         mManager.removeCallback(mockCallback);
     }
@@ -164,7 +184,7 @@
         MediaRouter2.Callback mockRouterCallback = mock(MediaRouter2.Callback.class);
         InstrumentationRegistry.getInstrumentation().runOnMainSync(
                 () -> {
-                    mRouter.addCallback(TEST_CONTROL_CATEGORIES, mExecutor, mockRouterCallback);
+                    mRouter.addCallback(CONTROL_CATEGORIES_ALL, mExecutor, mockRouterCallback);
                 }
         );
 
@@ -197,10 +217,10 @@
         mManager.removeCallback(managerCallback);
     }
 
-    @Test
     /**
      * Tests selecting and unselecting routes of a single provider.
      */
+    @Test
     public void testSingleProviderSelect() {
         MediaRouter2Manager.Callback managerCallback = mock(MediaRouter2Manager.Callback.class);
         MediaRouter2.Callback routerCallback = mock(MediaRouter2.Callback.class);
@@ -208,7 +228,7 @@
         mManager.addCallback(mExecutor, managerCallback);
         InstrumentationRegistry.getInstrumentation().runOnMainSync(
                 () -> {
-                    mRouter.addCallback(TEST_CONTROL_CATEGORIES, mExecutor, routerCallback);
+                    mRouter.addCallback(CONTROL_CATEGORIES_ALL, mExecutor, routerCallback);
                 }
         );
         verify(managerCallback, timeout(TIMEOUT_MS))
@@ -218,7 +238,8 @@
                 createRouteMap(mManager.getAvailableRoutes(mPackageName));
 
         mManager.selectRoute(mPackageName, routes.get(ROUTE_ID1));
-        verify(managerCallback, timeout(TIMEOUT_MS))
+        verify(managerCallback, timeout(TIMEOUT_MS)
+        )
                 .onRouteChanged(argThat(routeInfo -> TextUtils.equals(ROUTE_ID1, routeInfo.getId())
                         && TextUtils.equals(routeInfo.getClientPackageName(), mPackageName)));
 
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
index fc5e791..c0dcbbc 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
@@ -70,13 +70,9 @@
                 R.styleable.CarNavigationButton_unselectedAlpha, mUnselectedAlpha);
         mSelectedIconResourceId = typedArray.getResourceId(
                 R.styleable.CarNavigationButton_selectedIcon, mIconResourceId);
+        mIconResourceId = typedArray.getResourceId(
+                R.styleable.CarNavigationButton_icon, 0);
         typedArray.recycle();
-
-        // ImageView attrs
-        TypedArray a = context.obtainStyledAttributes(
-                attrs, com.android.internal.R.styleable.ImageView);
-        mIconResourceId = a.getResourceId(com.android.internal.R.styleable.ImageView_src, 0);
-        a.recycle();
     }
 
 
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index a452bae..b1f9797 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -1073,9 +1073,10 @@
             // shade is visible to the user. When the notification shade is completely open then
             // alpha value will be 1.
             float alpha = (float) height / mNotificationView.getHeight();
-            Drawable background = mNotificationView.getBackground();
+            Drawable background = mNotificationView.getBackground().mutate();
 
             background.setAlpha((int) (alpha * 255));
+            mNotificationView.setBackground(background);
         }
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
index 9a41f1d..9672fea 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
@@ -663,7 +663,8 @@
         final SpannableStringBuilder sb = new SpannableStringBuilder(textView.getText());
         removeExistingRestrictedSpans(sb);
         if (disabled) {
-            final int disabledColor = context.getColor(R.color.disabled_text_color);
+            final int disabledColor = Utils.getDisabled(context,
+                    textView.getCurrentTextColor());
             sb.setSpan(new ForegroundColorSpan(disabledColor), 0, sb.length(),
                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
             textView.setCompoundDrawables(null, null, getRestrictedPadlock(context), null);
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index d32e85f..14f233d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -35,8 +35,6 @@
 
 public class Utils {
 
-    private static final String CURRENT_MODE_KEY = "CURRENT_MODE";
-    private static final String NEW_MODE_KEY = "NEW_MODE";
     @VisibleForTesting
     static final String STORAGE_MANAGER_ENABLED_PROPERTY =
             "ro.storage_manager.enabled";
@@ -56,24 +54,11 @@
 
     public static void updateLocationEnabled(Context context, boolean enabled, int userId,
             int source) {
-        LocationManager locationManager = context.getSystemService(LocationManager.class);
-
         Settings.Secure.putIntForUser(
                 context.getContentResolver(), Settings.Secure.LOCATION_CHANGER, source,
                 userId);
 
-        Intent intent = new Intent(LocationManager.MODE_CHANGING_ACTION);
-        final int oldMode = locationManager.isLocationEnabled()
-                ? Settings.Secure.LOCATION_MODE_ON
-                : Settings.Secure.LOCATION_MODE_OFF;
-        final int newMode = enabled
-                ? Settings.Secure.LOCATION_MODE_ON
-                : Settings.Secure.LOCATION_MODE_OFF;
-        intent.putExtra(CURRENT_MODE_KEY, oldMode);
-        intent.putExtra(NEW_MODE_KEY, newMode);
-        context.sendBroadcastAsUser(
-                intent, UserHandle.of(userId), android.Manifest.permission.WRITE_SECURE_SETTINGS);
-
+        LocationManager locationManager = context.getSystemService(LocationManager.class);
         locationManager.setLocationEnabledForUser(enabled, UserHandle.of(userId));
     }
 
@@ -218,6 +203,13 @@
         return list.getDefaultColor();
     }
 
+    /**
+     * This method computes disabled color from normal color
+     *
+     * @param context
+     * @param inputColor normal color.
+     * @return disabled color.
+     */
     @ColorInt
     public static int getDisabled(Context context, int inputColor) {
         return applyAlphaAttr(context, android.R.attr.disabledAlpha, inputColor);
diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/ColorUtil.java b/packages/SettingsLib/src/com/android/settingslib/utils/ColorUtil.java
new file mode 100644
index 0000000..c54b471
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/utils/ColorUtil.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.utils;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+
+/** Utility class for getting color attribute **/
+public class ColorUtil {
+
+    /**
+     * Returns android:disabledAlpha value in context
+     */
+    public static float getDisabledAlpha(Context context) {
+        final TypedArray ta = context.obtainStyledAttributes(
+                new int[]{android.R.attr.disabledAlpha});
+        final float alpha = ta.getFloat(0, 0);
+        ta.recycle();
+        return alpha;
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
index 4d76e44..fc69b1a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
@@ -15,17 +15,13 @@
  */
 package com.android.settingslib;
 
-import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
-
 import static com.android.settingslib.Utils.STORAGE_MANAGER_ENABLED_PROPERTY;
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.ActivityManager;
@@ -45,7 +41,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentMatcher;
-import org.mockito.ArgumentMatchers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
@@ -85,15 +80,11 @@
     }
 
     @Test
-    public void testUpdateLocationEnabled_sendBroadcast() {
+    public void testUpdateLocationEnabled() {
         int currentUserId = ActivityManager.getCurrentUser();
         Utils.updateLocationEnabled(mContext, true, currentUserId,
                 Settings.Secure.LOCATION_CHANGER_QUICK_SETTINGS);
 
-        verify(mContext).sendBroadcastAsUser(
-            argThat(actionMatches(LocationManager.MODE_CHANGING_ACTION)),
-            ArgumentMatchers.eq(UserHandle.of(currentUserId)),
-            ArgumentMatchers.eq(WRITE_SECURE_SETTINGS));
         assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.LOCATION_CHANGER, Settings.Secure.LOCATION_CHANGER_UNKNOWN))
                 .isEqualTo(Settings.Secure.LOCATION_CHANGER_QUICK_SETTINGS);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/GenerationRegistry.java b/packages/SettingsProvider/src/com/android/providers/settings/GenerationRegistry.java
index 044ec86..5617331 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/GenerationRegistry.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/GenerationRegistry.java
@@ -22,14 +22,16 @@
 import android.util.MemoryIntArray;
 import android.util.Slog;
 import android.util.SparseIntArray;
+
 import com.android.internal.annotations.GuardedBy;
 
 import java.io.IOException;
 
 /**
- * This class tracks changes for global/secure/system tables on a
- * per user basis and updates a shared memory region which client
- * processes can read to determine if their local caches are stale,
+ * This class tracks changes for config/global/secure/system tables
+ * on a per user basis and updates a shared memory region which
+ * client processes can read to determine if their local caches are
+ * stale.
  */
 final class GenerationRegistry {
     private static final String LOG_TAG = "GenerationRegistry";
@@ -114,11 +116,12 @@
     @GuardedBy("mLock")
     private MemoryIntArray getBackingStoreLocked() {
         if (mBackingStore == null) {
-            // One for the global table, two for system and secure tables for a
-            // managed profile (managed profile is not included in the max user
-            // count), ten for partially deleted users if users are quickly removed,
-            // and twice max user count for system and secure.
-            final int size = 1 + 2 + 10 + 2 * UserManager.getMaxSupportedUsers();
+            // One for the config table, one for the global table, two for system
+            // and secure tables for a managed profile (managed profile is not
+            // included in the max user count), ten for partially deleted users if
+            // users are quickly removed, and twice max user count for system and
+            // secure.
+            final int size = 1 + 1 + 2 + 10 + 2 * UserManager.getMaxSupportedUsers();
             try {
                 mBackingStore = new MemoryIntArray(size);
                 if (DEBUG) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 9d398b5..b11df48 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -16,7 +16,6 @@
 
 package com.android.providers.settings;
 
-import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.backup.BackupAgentHelper;
 import android.app.backup.BackupDataInput;
@@ -41,6 +40,7 @@
 import android.util.BackupUtils;
 import android.util.Log;
 
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.widget.LockPatternUtils;
 
 import java.io.BufferedOutputStream;
@@ -586,15 +586,15 @@
         final String[] whitelist;
         Map<String, Validator> validators = null;
         if (contentUri.equals(Settings.Secure.CONTENT_URI)) {
-            whitelist = concat(Settings.Secure.SETTINGS_TO_BACKUP,
+            whitelist = ArrayUtils.concatElements(String.class, Settings.Secure.SETTINGS_TO_BACKUP,
                     Settings.Secure.LEGACY_RESTORE_SETTINGS);
             validators = Settings.Secure.VALIDATORS;
         } else if (contentUri.equals(Settings.System.CONTENT_URI)) {
-            whitelist = concat(Settings.System.SETTINGS_TO_BACKUP,
+            whitelist = ArrayUtils.concatElements(String.class, Settings.System.SETTINGS_TO_BACKUP,
                     Settings.System.LEGACY_RESTORE_SETTINGS);
             validators = Settings.System.VALIDATORS;
         } else if (contentUri.equals(Settings.Global.CONTENT_URI)) {
-            whitelist = concat(Settings.Global.SETTINGS_TO_BACKUP,
+            whitelist = ArrayUtils.concatElements(String.class, Settings.Global.SETTINGS_TO_BACKUP,
                     Settings.Global.LEGACY_RESTORE_SETTINGS);
             validators = Settings.Global.VALIDATORS;
         } else {
@@ -672,18 +672,6 @@
         return (validator != null) && validator.validate(value);
     }
 
-    private final String[] concat(String[] first, @Nullable String[] second) {
-        if (second == null || second.length == 0) {
-            return first;
-        }
-        final int firstLen = first.length;
-        final int secondLen = second.length;
-        String[] both = new String[firstLen + secondLen];
-        System.arraycopy(first, 0, both, 0, firstLen);
-        System.arraycopy(second, 0, both, firstLen, secondLen);
-        return both;
-    }
-
     /**
      * Restores the owner info enabled and other settings in LockSettings.
      *
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
index 28d5402..52ec1f0 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
@@ -30,7 +30,7 @@
  */
 @ProvidesInterface(version = FalsingManager.VERSION)
 public interface FalsingManager {
-    int VERSION = 1;
+    int VERSION = 2;
 
     void onSucccessfulUnlock();
 
@@ -103,4 +103,6 @@
     void onTouchEvent(MotionEvent ev, int width, int height);
 
     void dump(PrintWriter pw);
+
+    void cleanup();
 }
diff --git a/packages/SystemUI/res/layout/biometric_dialog.xml b/packages/SystemUI/res/layout/biometric_dialog.xml
index c560d7e..e687cdf 100644
--- a/packages/SystemUI/res/layout/biometric_dialog.xml
+++ b/packages/SystemUI/res/layout/biometric_dialog.xml
@@ -55,7 +55,8 @@
                     android:id="@+id/left_space"
                     android:layout_weight="1"
                     android:layout_width="0dp"
-                    android:layout_height="match_parent"/>
+                    android:layout_height="match_parent"
+                    android:contentDescription="@string/biometric_dialog_empty_space_description"/>
 
                     <LinearLayout
                         android:id="@+id/dialog"
@@ -177,7 +178,8 @@
                     android:id="@+id/right_space"
                     android:layout_weight="1"
                     android:layout_width="0dp"
-                    android:layout_height="match_parent" />
+                    android:layout_height="match_parent"
+                    android:contentDescription="@string/biometric_dialog_empty_space_description"/>
 
             </LinearLayout>
 
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 7fc2066..21c2c6b 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -46,6 +46,8 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:gravity="center"
+                android:paddingStart="@dimen/keyguard_indication_text_padding"
+                android:paddingEnd="@dimen/keyguard_indication_text_padding"
                 android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
                 android:visibility="gone" />
 
@@ -54,6 +56,8 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:gravity="center"
+                android:paddingStart="@dimen/keyguard_indication_text_padding"
+                android:paddingEnd="@dimen/keyguard_indication_text_padding"
                 android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
                 android:accessibilityLiveRegion="polite" />
 
diff --git a/packages/SystemUI/res/values/attrs_car.xml b/packages/SystemUI/res/values/attrs_car.xml
index ced26c9..49b87f3 100644
--- a/packages/SystemUI/res/values/attrs_car.xml
+++ b/packages/SystemUI/res/values/attrs_car.xml
@@ -62,6 +62,8 @@
         <attr name="unselectedAlpha" />
         <!-- icon to be rendered when in selected state -->
         <attr name="selectedIcon" />
+        <!-- icon to be rendered (drawable) -->
+        <attr name="icon"/>
     </declare-styleable>
 
     <!-- Custom attributes to configure hvac values -->
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 7c24130..861187f 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -154,12 +154,8 @@
     <!-- The number of milliseconds before the heads up notification accepts touches. -->
     <integer name="touch_acceptance_delay">700</integer>
 
-    <!-- The number of milliseconds before the ambient notification auto-dismisses. This will
-         override the default pulse length. -->
-    <integer name="heads_up_notification_decay_dozing">10000</integer>
-
     <!-- The number of milliseconds to extend ambient pulse by when prompted (e.g. on touch) -->
-    <integer name="ambient_notification_extension_time">6000</integer>
+    <integer name="ambient_notification_extension_time">10000</integer>
 
     <!-- In multi-window, determines whether the stack where recents lives should grow from
          the smallest position when being launched. -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index f4970d0..62089e9 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -183,6 +183,9 @@
     <!-- The padding on the bottom of the notifications on the keyguard -->
     <dimen name="keyguard_indication_bottom_padding">12sp</dimen>
 
+    <!-- The padding at start and end of indication text shown on AOD -->
+    <dimen name="keyguard_indication_text_padding">16dp</dimen>
+
     <!-- Shadows under the clock, date and other keyguard text fields -->
     <dimen name="keyguard_shadow_radius">5</dimen>
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java
index 98a8110..98b7e24 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java
@@ -38,6 +38,7 @@
     public int windowingMode;
     public int systemUiVisibility;
     public float scale;
+    public long snapshotId;
 
     public ThumbnailData() {
         thumbnail = null;
@@ -49,6 +50,7 @@
         isTranslucent = false;
         windowingMode = WINDOWING_MODE_UNDEFINED;
         systemUiVisibility = 0;
+        snapshotId = 0;
     }
 
     public ThumbnailData(TaskSnapshot snapshot) {
@@ -61,5 +63,6 @@
         isTranslucent = snapshot.isTranslucent();
         windowingMode = snapshot.getWindowingMode();
         systemUiVisibility = snapshot.getSystemUiVisibility();
+        snapshotId = snapshot.getId();
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 69630c4..4ad262f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -237,6 +237,7 @@
                     MIN_DRAG_SIZE, getResources().getDisplayMetrics())
                     && !mUpdateMonitor.isFaceDetectionRunning()) {
                 mUpdateMonitor.requestFaceAuth();
+                mCallback.userActivity();
                 showMessage(null, null);
             }
         }
@@ -512,7 +513,7 @@
                 case SimPuk:
                     // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
                     SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId);
-                    if (securityMode == SecurityMode.None || mLockPatternUtils.isLockScreenDisabled(
+                    if (securityMode == SecurityMode.None && mLockPatternUtils.isLockScreenDisabled(
                             KeyguardUpdateMonitor.getCurrentUser())) {
                         finish = true;
                         eventSubtype = BOUNCER_DISMISS_SIM;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 2eb93d3..fd618b0 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -377,14 +377,15 @@
         }
     };
 
-    private boolean mFaceSettingEnabledForUser;
+    private SparseBooleanArray mFaceSettingEnabledForUser = new SparseBooleanArray();
     private BiometricManager mBiometricManager;
     private IBiometricEnabledOnKeyguardCallback mBiometricEnabledCallback =
             new IBiometricEnabledOnKeyguardCallback.Stub() {
         @Override
-        public void onChanged(BiometricSourceType type, boolean enabled) throws RemoteException {
+        public void onChanged(BiometricSourceType type, boolean enabled, int userId)
+                throws RemoteException {
             if (type == BiometricSourceType.FACE) {
-                mFaceSettingEnabledForUser = enabled;
+                mFaceSettingEnabledForUser.put(userId, enabled);
                 updateFaceListeningState();
             }
         }
@@ -1711,7 +1712,7 @@
         // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
         return (mBouncer || mAuthInterruptActive || awakeKeyguard || shouldListenForFaceAssistant())
                 && !mSwitchingUser && !isFaceDisabled(user) && becauseCannotSkipBouncer
-                && !mKeyguardGoingAway && mFaceSettingEnabledForUser && !mLockIconPressed
+                && !mKeyguardGoingAway && mFaceSettingEnabledForUser.get(user) && !mLockIconPressed
                 && strongAuthAllowsScanning && mIsPrimaryUser
                 && !mSecureCameraLaunched;
     }
@@ -1783,13 +1784,14 @@
     }
 
     /**
-     * If face hardware is available and user has enrolled. Not considering encryption or
-     * lockdown state.
+     * If face hardware is available, user has enrolled and enabled auth via setting.
+     * Not considering encryption or lock down state.
      */
     public boolean isUnlockWithFacePossible(int userId) {
         return mFaceManager != null && mFaceManager.isHardwareDetected()
                 && !isFaceDisabled(userId)
-                && mFaceManager.hasEnrolledTemplates(userId);
+                && mFaceManager.hasEnrolledTemplates(userId)
+                && mFaceSettingEnabledForUser.get(userId);
     }
 
     private void stopListeningForFingerprint() {
@@ -2657,7 +2659,7 @@
             pw.println("    possible=" + isUnlockWithFacePossible(userId));
             pw.println("    strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
             pw.println("    trustManaged=" + getUserTrustIsManaged(userId));
-            pw.println("    enabledByUser=" + mFaceSettingEnabledForUser);
+            pw.println("    enabledByUser=" + mFaceSettingEnabledForUser.get(userId));
             pw.println("    mSecureCameraLaunched=" + mSecureCameraLaunched);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
index 0041b0c..ea175ed 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
@@ -239,4 +239,8 @@
     public void dump(PrintWriter pw) {
 
     }
+
+    @Override
+    public void cleanup() {
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java
index 67dfdca..fba0d50 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java
@@ -168,6 +168,7 @@
                     .append("enabled=").append(isEnabled() ? 1 : 0)
                     .append(" mScreenOn=").append(mScreenOn ? 1 : 0)
                     .append(" mState=").append(StatusBarState.toShortString(mState))
+                    .append(" mShowingAod=").append(mShowingAod ? 1 : 0)
                     .toString()
             );
         }
@@ -550,6 +551,14 @@
         pw.println();
     }
 
+    @Override
+    public void cleanup() {
+        mSensorManager.unregisterListener(mSensorEventListener);
+        mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
+        Dependency.get(StatusBarStateController.class).removeCallback(mStatusBarStateListener);
+        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mKeyguardUpdateCallback);
+    }
+
     public Uri reportRejectedTouch() {
         if (mDataCollector.isEnabled()) {
             return mDataCollector.reportRejectedTouch();
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
index 3cc8ec9a..8210951 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
@@ -65,6 +65,7 @@
             public void onPluginConnected(FalsingPlugin plugin, Context context) {
                 FalsingManager pluginFalsingManager = plugin.getFalsingManager(context);
                 if (pluginFalsingManager != null) {
+                    mInternalFalsingManager.cleanup();
                     mInternalFalsingManager = pluginFalsingManager;
                 }
             }
@@ -290,4 +291,9 @@
     public void dump(PrintWriter pw) {
         mInternalFalsingManager.dump(pw);
     }
+
+    @Override
+    public void cleanup() {
+        mInternalFalsingManager.cleanup();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
index 00f35aa..cee01a4 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
@@ -324,6 +324,11 @@
     public void dump(PrintWriter printWriter) {
     }
 
+    @Override
+    public void cleanup() {
+        unregisterSensors();
+    }
+
     static void logDebug(String msg) {
         logDebug(msg, null);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
index 0e93f42..d3e8b3d 100644
--- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
+++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
@@ -77,7 +77,7 @@
     protected void extractWallpaperColors() {
         super.extractWallpaperColors();
         // mTonal is final but this method will be invoked by the base class during its ctor.
-        if (mTonal == null) {
+        if (mTonal == null || mNeutralColorsLock == null) {
             return;
         }
         mTonal.applyFallback(mLockColors == null ? mSystemColors : mLockColors, mNeutralColorsLock);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index 537c09e..1bc7e63 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -30,6 +30,7 @@
 import com.android.systemui.SystemUIApplication;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.util.AsyncSensorManager;
 import com.android.systemui.util.wakelock.DelayedWakeLock;
@@ -70,7 +71,7 @@
                 new DozeScreenState(wrappedService, handler, params, wakeLock),
                 createDozeScreenBrightness(context, wrappedService, sensorManager, host, params,
                         handler),
-                new DozeWallpaperState(context),
+                new DozeWallpaperState(context, getBiometricUnlockController(dozeService)),
                 new DozeDockHandler(context, machine, host, config, handler, dockManager),
                 new DozeAuthRemover(dozeService)
         });
@@ -108,4 +109,10 @@
         final SystemUIApplication app = (SystemUIApplication) appCandidate;
         return app.getComponent(DozeHost.class);
     }
+
+    public static BiometricUnlockController getBiometricUnlockController(DozeService service) {
+        Application appCandidate = service.getApplication();
+        final SystemUIApplication app = (SystemUIApplication) appCandidate;
+        return app.getComponent(BiometricUnlockController.class);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 3c9d4a9..ae6dac5 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -50,9 +50,23 @@
      */
     void onSlpiTap(float x, float y);
 
+    /**
+     * Artificially dim down the the display by changing scrim opacities.
+     * @param scrimOpacity opacity from 0 to 1.
+     */
     default void setAodDimmingScrim(float scrimOpacity) {}
+
+    /**
+     * Sets the actual display brightness.
+     * @param value from 0 to 255.
+     */
     void setDozeScreenBrightness(int value);
 
+    /**
+     * Makes scrims black and changes animation durations.
+     */
+    default void prepareForGentleWakeUp() {}
+
     void onIgnoreTouchWhilePulsing(boolean ignore);
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
index 5be097c..38ee2fe 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
@@ -82,7 +82,10 @@
         boolean messagePending = mHandler.hasCallbacks(mApplyPendingScreenState);
         boolean pulseEnding = oldState  == DozeMachine.State.DOZE_PULSE_DONE
                 && newState == DozeMachine.State.DOZE_AOD;
-        if (messagePending || oldState == DozeMachine.State.INITIALIZED || pulseEnding) {
+        boolean turningOn = (oldState == DozeMachine.State.DOZE_AOD_PAUSED
+                || oldState  == DozeMachine.State.DOZE) && newState == DozeMachine.State.DOZE_AOD;
+        boolean justInitialized = oldState == DozeMachine.State.INITIALIZED;
+        if (messagePending || justInitialized || pulseEnding || turningOn) {
             // During initialization, we hide the navigation bar. That is however only applied after
             // a traversal; setting the screen state here is immediate however, so it can happen
             // that the screen turns on again before the navigation bar is hidden. To work around
@@ -91,7 +94,7 @@
 
             // Delay screen state transitions even longer while animations are running.
             boolean shouldDelayTransition = newState == DozeMachine.State.DOZE_AOD
-                    && mParameters.shouldControlScreenOff();
+                    && mParameters.shouldControlScreenOff() && !turningOn;
 
             if (shouldDelayTransition) {
                 mWakeLock.setAcquired(true);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index cf04b7f..6918501 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -198,7 +198,10 @@
         updateListening();
     }
 
-    private void updateListening() {
+    /**
+     * Registers/unregisters sensors based on internal state.
+     */
+    public void updateListening() {
         boolean anyListening = false;
         for (TriggerSensor s : mSensors) {
             // We don't want to be listening while we're PAUSED (prox sensor is covered)
@@ -231,7 +234,7 @@
 
     public void onUserSwitched() {
         for (TriggerSensor s : mSensors) {
-            s.updateListener();
+            s.updateListening();
         }
     }
 
@@ -246,7 +249,7 @@
                 return;
             }
             for (TriggerSensor s : mSensors) {
-                s.updateListener();
+                s.updateListening();
             }
         }
     };
@@ -409,22 +412,22 @@
         public void setListening(boolean listen) {
             if (mRequested == listen) return;
             mRequested = listen;
-            updateListener();
+            updateListening();
         }
 
         public void setDisabled(boolean disabled) {
             if (mDisabled == disabled) return;
             mDisabled = disabled;
-            updateListener();
+            updateListening();
         }
 
         public void ignoreSetting(boolean ignored) {
             if (mIgnoresSetting == ignored) return;
             mIgnoresSetting = ignored;
-            updateListener();
+            updateListening();
         }
 
-        public void updateListener() {
+        public void updateListening() {
             if (!mConfigured || mSensor == null) return;
             if (mRequested && !mDisabled && (enabledBySetting() || mIgnoresSetting)
                     && !mRegistered) {
@@ -480,7 +483,7 @@
                 mCallback.onSensorPulse(mPulseReason, mSensorPerformsProxCheck, screenX, screenY,
                         event.values);
                 if (!mRegistered) {
-                    updateListener();  // reregister, this sensor only fires once
+                    updateListening();  // reregister, this sensor only fires once
                 }
             }));
         }
@@ -541,7 +544,7 @@
         }
 
         @Override
-        public void updateListener() {
+        public void updateListening() {
             if (!mConfigured) return;
             AsyncSensorManager asyncSensorManager = (AsyncSensorManager) mSensorManager;
             if (mRequested && !mDisabled && (enabledBySetting() || mIgnoresSetting)
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 97b08d5..8ef01e8 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -201,7 +201,7 @@
             // Let's prepare the display to wake-up by drawing black.
             // This will cover the hardware wake-up sequence, where the display
             // becomes black for a few frames.
-            mDozeHost.setAodDimmingScrim(255f);
+            mDozeHost.setAodDimmingScrim(1f);
         }
         mMachine.wakeUp();
     }
@@ -314,6 +314,9 @@
                 break;
             case DOZE_PULSE_DONE:
                 mDozeSensors.requestTemporaryDisable();
+                // A pulse will temporarily disable sensors that require a touch screen.
+                // Let's make sure that they are re-enabled when the pulse is over.
+                mDozeSensors.updateListening();
                 break;
             case FINISH:
                 mBroadcastReceiver.unregister(mContext);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 51e96d2..e877d44 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -130,6 +130,7 @@
                 break;
             case DOZE:
             case DOZE_AOD_PAUSED:
+                mHost.prepareForGentleWakeUp();
                 unscheduleTimeTick();
                 break;
             case DOZE_REQUEST_PULSE:
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
index 1b3cd88..35c8b74 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
@@ -24,6 +24,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.DozeParameters;
 
 import java.io.PrintWriter;
@@ -38,18 +39,22 @@
 
     private final IWallpaperManager mWallpaperManagerService;
     private final DozeParameters mDozeParameters;
+    private final BiometricUnlockController mBiometricUnlockController;
     private boolean mIsAmbientMode;
 
-    public DozeWallpaperState(Context context) {
+    public DozeWallpaperState(Context context,
+            BiometricUnlockController biometricUnlockController) {
         this(IWallpaperManager.Stub.asInterface(
                 ServiceManager.getService(Context.WALLPAPER_SERVICE)),
+                biometricUnlockController,
                 DozeParameters.getInstance(context));
     }
 
     @VisibleForTesting
     DozeWallpaperState(IWallpaperManager wallpaperManagerService,
-            DozeParameters parameters) {
+            BiometricUnlockController biometricUnlockController, DozeParameters parameters) {
         mWallpaperManagerService = wallpaperManagerService;
+        mBiometricUnlockController = biometricUnlockController;
         mDozeParameters = parameters;
     }
 
@@ -76,7 +81,9 @@
         } else {
             boolean wakingUpFromPulse = oldState == DozeMachine.State.DOZE_PULSING
                     && newState == DozeMachine.State.FINISH;
-            animated = !mDozeParameters.getDisplayNeedsBlanking() || wakingUpFromPulse;
+            boolean fastDisplay = !mDozeParameters.getDisplayNeedsBlanking();
+            animated = (fastDisplay && !mBiometricUnlockController.unlockedByWakeAndUnlock())
+                    || wakingUpFromPulse;
         }
 
         if (isAmbientMode != mIsAmbientMode) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java
index cc1170f..b444fa5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java
@@ -83,6 +83,11 @@
         bindContents();
     }
 
+    @Override
+    public boolean isTransparent() {
+        return true;
+    }
+
     /** Must be called whenever the UI mode changes (i.e. when we enter night mode). */
     void onUiModeChanged() {
         updateBackgroundColors();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 01e2b28..7655056 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -159,15 +159,13 @@
         float drawStart = !ambientState.isOnKeyguard() ? ambientState.getTopPadding()
                 + ambientState.getStackTranslation() + ambientState.getExpandAnimationTopChange()
                 : 0;
-        float previousNotificationEnd = 0;
-        float previousNotificationStart = 0;
+        float clipStart = 0;
         int childCount = algorithmState.visibleChildren.size();
         for (int i = 0; i < childCount; i++) {
             ExpandableView child = algorithmState.visibleChildren.get(i);
             ExpandableViewState state = child.getViewState();
             if (!child.mustStayOnScreen() || state.headsUpIsVisible) {
-                previousNotificationEnd = Math.max(drawStart, previousNotificationEnd);
-                previousNotificationStart = Math.max(drawStart, previousNotificationStart);
+                clipStart = Math.max(drawStart, clipStart);
             }
             float newYTranslation = state.yTranslation;
             float newHeight = state.height;
@@ -175,10 +173,10 @@
             boolean isHeadsUp = (child instanceof ExpandableNotificationRow)
                     && ((ExpandableNotificationRow) child).isPinned();
             if (mClipNotificationScrollToTop
-                    && !state.inShelf && newYTranslation < previousNotificationEnd
-                    && (!isHeadsUp || ambientState.isShadeExpanded())) {
+                    && (!state.inShelf || isHeadsUp)
+                    && newYTranslation < clipStart) {
                 // The previous view is overlapping on top, clip!
-                float overlapAmount = previousNotificationEnd - newYTranslation;
+                float overlapAmount = clipStart - newYTranslation;
                 state.clipTopAmount = (int) overlapAmount;
             } else {
                 state.clipTopAmount = 0;
@@ -187,8 +185,7 @@
             if (!child.isTransparent()) {
                 // Only update the previous values if we are not transparent,
                 // otherwise we would clip to a transparent view.
-                previousNotificationEnd = newNotificationEnd;
-                previousNotificationStart = newYTranslation;
+                clipStart = Math.max(clipStart, isHeadsUp ? newYTranslation : newNotificationEnd);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index bc7174d..94cd2cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -141,6 +141,7 @@
     private BiometricSourceType mPendingAuthenticatedBioSourceType = null;
     private boolean mPendingShowBouncer;
     private boolean mHasScreenTurnedOnSinceAuthenticating;
+    private boolean mFadedAwayAfterWakeAndUnlock;
 
     private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
 
@@ -260,6 +261,7 @@
         boolean unlockAllowed = mKeyguardBypassController.onBiometricAuthenticated(
                 biometricSourceType);
         if (unlockAllowed) {
+            mKeyguardViewMediator.userActivity();
             startWakeAndUnlock(biometricSourceType);
         } else {
             Log.d(TAG, "onBiometricAuthenticated aborted by bypass controller");
@@ -367,6 +369,7 @@
     @Override
     public void onStartedGoingToSleep(int why) {
         resetMode();
+        mFadedAwayAfterWakeAndUnlock = false;
         mPendingAuthenticatedUserId = -1;
         mPendingAuthenticatedBioSourceType = null;
     }
@@ -466,8 +469,11 @@
         }
         if (mStatusBarKeyguardViewManager.isShowing()) {
             if (mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing() && unlockingAllowed) {
-                return bypass && !mKeyguardBypassController.canPlaySubtleWindowAnimations()
-                        ? MODE_UNLOCK_COLLAPSING : MODE_UNLOCK_FADING;
+                if (bypass && mKeyguardBypassController.canPlaySubtleWindowAnimations()) {
+                    return MODE_UNLOCK_FADING;
+                } else {
+                    return MODE_DISMISS_BOUNCER;
+                }
             } else if (unlockingAllowed) {
                 return bypass ? MODE_UNLOCK_FADING : MODE_NONE;
             } else {
@@ -509,6 +515,9 @@
     }
 
     public void finishKeyguardFadingAway() {
+        if (isWakeAndUnlock()) {
+            mFadedAwayAfterWakeAndUnlock = true;
+        }
         resetMode();
     }
 
@@ -559,6 +568,14 @@
     }
 
     /**
+     * Successful authentication with fingerprint, face, or iris that wakes up the device.
+     * This will return {@code true} even after the keyguard fades away.
+     */
+    public boolean unlockedByWakeAndUnlock() {
+        return  isWakeAndUnlock() || mFadedAwayAfterWakeAndUnlock;
+    }
+
+    /**
      * Successful authentication with fingerprint, face, or iris when the screen was either
      * on or off.
      */
@@ -567,6 +584,13 @@
     }
 
     /**
+     * Successful authentication with fingerprint, face, or iris when the lockscreen fades away
+     */
+    public boolean isUnlockFading() {
+        return mMode == MODE_UNLOCK_FADING;
+    }
+
+    /**
      * Translates biometric source type for logging purpose.
      */
     private int toSubtype(BiometricSourceType biometricSourceType) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index cbaf85c..680e522 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -72,8 +72,6 @@
     private NotificationGroupManager mGroupManager;
     private VisualStabilityManager mVisualStabilityManager;
     private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
-    @VisibleForTesting
-    int mAutoDismissNotificationDecayDozing;
     private boolean mReleaseOnExpandFinish;
 
     private int mStatusBarHeight;
@@ -120,8 +118,6 @@
             KeyguardBypassController bypassController) {
         super(context);
         Resources resources = mContext.getResources();
-        mAutoDismissNotificationDecayDozing = resources.getInteger(
-                R.integer.heads_up_notification_decay_dozing);
         mExtensionTime = resources.getInteger(R.integer.ambient_notification_extension_time);
         mAutoHeadsUpNotificationDecay = resources.getInteger(
                 R.integer.auto_heads_up_notification_decay);
@@ -612,9 +608,7 @@
         }
 
         private int getDecayDuration() {
-            if (mStatusBarStateController.isDozing()) {
-                return mAutoDismissNotificationDecayDozing;
-            } else if (isAutoHeadsUp()) {
+            if (isAutoHeadsUp()) {
                 return getRecommendedHeadsUpTimeoutMs(mAutoHeadsUpNotificationDecay);
             } else {
                 return getRecommendedHeadsUpTimeoutMs(mAutoDismissNotificationDecay);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
index c88b22b..0aec2b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
@@ -167,4 +167,8 @@
         pw.print("  qSExpanded: "); pw.println(qSExpanded)
         pw.print("  bouncerShowing: "); pw.println(bouncerShowing)
     }
+
+    companion object {
+        const val BYPASS_PANEL_FADE_DURATION = 67
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index 49afae7..1360a08 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -102,6 +102,7 @@
     private boolean mWakeAndUnlockRunning;
     private boolean mKeyguardShowing;
     private boolean mShowingLaunchAffordance;
+    private boolean mKeyguardJustShown;
     private boolean mUpdatePending;
 
     private final KeyguardMonitor.Callback mKeyguardMonitorCallback =
@@ -115,6 +116,9 @@
                         mBlockUpdates = false;
                         force = true;
                     }
+                    if (!wasShowing && mKeyguardShowing) {
+                        mKeyguardJustShown = true;
+                    }
                     update(force);
                 }
 
@@ -273,8 +277,10 @@
 
         int state = getState();
         int lastState = mLastState;
+        boolean keyguardJustShown = mKeyguardJustShown;
         mIsFaceUnlockState = state == STATE_SCANNING_FACE;
         mLastState = state;
+        mKeyguardJustShown = false;
 
         boolean shouldUpdate = lastState != state || mForceUpdate;
         if (mBlockUpdates && canBlockUpdates()) {
@@ -283,7 +289,7 @@
         if (shouldUpdate) {
             mForceUpdate = false;
             @LockAnimIndex final int lockAnimIndex = getAnimationIndexForTransition(lastState,
-                    state, mPulsing, mDozing);
+                    state, mPulsing, mDozing, keyguardJustShown);
             boolean isAnim = lockAnimIndex != -1;
             int iconRes = isAnim ? getThemedAnimationResId(lockAnimIndex) : getIconForState(state);
 
@@ -412,7 +418,7 @@
     }
 
     private static int getAnimationIndexForTransition(int oldState, int newState, boolean pulsing,
-            boolean dozing) {
+            boolean dozing, boolean keyguardJustShown) {
 
         // Never animate when screen is off
         if (dozing && !pulsing) {
@@ -423,7 +429,7 @@
             return ERROR;
         } else if (oldState != STATE_LOCK_OPEN && newState == STATE_LOCK_OPEN) {
             return UNLOCK;
-        } else if (oldState == STATE_LOCK_OPEN && newState == STATE_LOCKED) {
+        } else if (oldState == STATE_LOCK_OPEN && newState == STATE_LOCKED && !keyguardJustShown) {
             return LOCK;
         } else if (newState == STATE_SCANNING_FACE) {
             return SCANNING;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index 0bbfbef..195870b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -464,7 +464,7 @@
         if (!sbn.isGroup() || sbn.getNotification().isGroupSummary()) {
             return false;
         }
-        if (!mHeadsUpManager.isAlerting(entry.key)) {
+        if (mHeadsUpManager != null && !mHeadsUpManager.isAlerting(entry.key)) {
             return false;
         }
         return (sbn.getNotification().fullScreenIntent != null
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 3f38c04..1aec5e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -487,6 +487,20 @@
     }
 
     /**
+     * Set front scrim to black, cancelling animations, in order to prepare to fade them
+     * away once the display turns on.
+     */
+    public void prepareForGentleWakeUp() {
+        if (mState == ScrimState.AOD && mDozeParameters.getAlwaysOn()) {
+            mCurrentInFrontAlpha = 1f;
+            mAnimateChange = false;
+            updateScrims();
+            mAnimateChange = true;
+            mAnimationDuration = ANIMATION_DURATION_LONG;
+        }
+    }
+
+    /**
      * If the lock screen sensor is active.
      */
     public void setWakeLockScreenSensorActive(boolean active) {
@@ -932,6 +946,12 @@
         }
     }
 
+    public void setUnlockIsFading(boolean unlockFading) {
+        for (ScrimState state : ScrimState.values()) {
+            state.setUnlockIsFading(unlockFading);
+        }
+    }
+
     public void setLaunchingAffordanceWithPreview(boolean launchingAffordanceWithPreview) {
         for (ScrimState state : ScrimState.values()) {
             state.setLaunchingAffordanceWithPreview(launchingAffordanceWithPreview);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index d152ecd..763e0d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -147,7 +147,9 @@
         public void prepare(ScrimState previousState) {
             mCurrentBehindAlpha = 0;
             mCurrentInFrontAlpha = 0;
-            mAnimationDuration = StatusBar.FADE_KEYGUARD_DURATION;
+            mAnimationDuration = mUnlockIsFading
+                    ? KeyguardBypassController.BYPASS_PANEL_FADE_DURATION
+                    : StatusBar.FADE_KEYGUARD_DURATION;
             mAnimateChange = !mLaunchingAffordanceWithPreview;
 
             if (previousState == ScrimState.AOD) {
@@ -198,6 +200,7 @@
     boolean mHasBackdrop;
     boolean mLaunchingAffordanceWithPreview;
     boolean mWakeLockScreenSensorActive;
+    boolean mUnlockIsFading;
 
     ScrimState(int index) {
         mIndex = index;
@@ -285,4 +288,8 @@
     public void setWakeLockScreenSensorActive(boolean active) {
         mWakeLockScreenSensorActive = active;
     }
+
+    public void setUnlockIsFading(boolean unlockIsFading) {
+        mUnlockIsFading = unlockIsFading;
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 40ebe58..f8e6aa3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1229,6 +1229,7 @@
                 mDozeScrimController, keyguardViewMediator,
                 mScrimController, this, UnlockMethodCache.getInstance(mContext),
                 new Handler(), mKeyguardUpdateMonitor, mKeyguardBypassController);
+        putComponent(BiometricUnlockController.class, mBiometricUnlockController);
         mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
                 getBouncerContainer(), mNotificationPanel, mBiometricUnlockController,
                 mStatusBarWindow.findViewById(R.id.lock_icon_container), mStackScroller,
@@ -3839,6 +3840,7 @@
 
     public void notifyBiometricAuthModeChanged() {
         updateDozing();
+        mScrimController.setUnlockIsFading(mBiometricUnlockController.isUnlockFading());
         updateScrimController();
         mStatusBarWindow.onBiometricAuthModeChanged(mBiometricUnlockController.isWakeAndUnlock(),
                 mBiometricUnlockController.isBiometricUnlock());
@@ -3850,7 +3852,8 @@
 
         // We don't want to end up in KEYGUARD state when we're unlocking with
         // fingerprint from doze. We should cross fade directly from black.
-        boolean wakeAndUnlocking = mBiometricUnlockController.isWakeAndUnlock();
+        boolean unlocking = mBiometricUnlockController.isWakeAndUnlock()
+                || mKeyguardMonitor.isKeyguardFadingAway();
 
         // Do not animate the scrim expansion when triggered by the fingerprint sensor.
         mScrimController.setExpansionAffectsAlpha(
@@ -3875,9 +3878,9 @@
         } else if (isPulsing()) {
             mScrimController.transitionTo(ScrimState.PULSING,
                     mDozeScrimController.getScrimCallback());
-        } else if (mDozing && !wakeAndUnlocking) {
+        } else if (mDozing && !unlocking) {
             mScrimController.transitionTo(ScrimState.AOD);
-        } else if (mIsKeyguard && !wakeAndUnlocking) {
+        } else if (mIsKeyguard && !unlocking) {
             mScrimController.transitionTo(ScrimState.KEYGUARD);
         } else if (mBubbleController.isStackExpanded()) {
             mScrimController.transitionTo(ScrimState.BUBBLE_EXPANDED);
@@ -4118,6 +4121,11 @@
             mScrimController.setAodFrontScrimAlpha(scrimOpacity);
         }
 
+        @Override
+        public void prepareForGentleWakeUp() {
+            mScrimController.prepareForGentleWakeUp();
+        }
+
         private void dispatchTap(View view, float x, float y) {
             long now = SystemClock.elapsedRealtime();
             dispatchTouchEvent(view, x, y, now, MotionEvent.ACTION_DOWN);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 65be708..5ce1329 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -85,7 +85,6 @@
     // make everything a bit slower to bridge a gap until the user is unlocked and home screen has
     // dranw its first frame.
     private static final long KEYGUARD_DISMISS_DURATION_LOCKED = 2000;
-    private static final long BYPASS_PANEL_FADE_DURATION = 67;
 
     private static String TAG = "StatusBarKeyguardViewManager";
 
@@ -270,7 +269,7 @@
         boolean keyguardWithoutQs = mStatusBarStateController.getState() == StatusBarState.KEYGUARD
                 && !mNotificationPanelView.isQsExpanded();
         boolean lockVisible = (mBouncer.isShowing() || keyguardWithoutQs)
-                && !mBouncer.isAnimatingAway();
+                && !mBouncer.isAnimatingAway() && !mKeyguardMonitor.isKeyguardFadingAway();
 
         if (mLastLockVisible != lockVisible) {
             mLastLockVisible = lockVisible;
@@ -279,8 +278,14 @@
                         AppearAnimationUtils.DEFAULT_APPEAR_DURATION /* duration */,
                         0 /* delay */);
             } else {
+                final long duration;
+                if (needsBypassFading()) {
+                    duration = KeyguardBypassController.BYPASS_PANEL_FADE_DURATION;
+                } else {
+                    duration = AppearAnimationUtils.DEFAULT_APPEAR_DURATION / 2;
+                }
                 CrossFadeHelper.fadeOut(mLockIconContainer,
-                        AppearAnimationUtils.DEFAULT_APPEAR_DURATION / 2 /* duration */,
+                        duration /* duration */,
                         0 /* delay */, null /* runnable */);
             }
         }
@@ -567,7 +572,7 @@
                 if (needsBypassFading()) {
                     ViewGroupFadeHelper.fadeOutAllChildrenExcept(mNotificationPanelView,
                             mNotificationContainer,
-                            BYPASS_PANEL_FADE_DURATION,
+                            KeyguardBypassController.BYPASS_PANEL_FADE_DURATION,
                                     () -> {
                         mStatusBar.hideKeyguard();
                         onKeyguardFadedAway();
@@ -583,7 +588,7 @@
                     if (needsBypassFading()) {
                         ViewGroupFadeHelper.fadeOutAllChildrenExcept(mNotificationPanelView,
                                 mNotificationContainer,
-                                BYPASS_PANEL_FADE_DURATION,
+                                KeyguardBypassController.BYPASS_PANEL_FADE_DURATION,
                                 () -> {
                                     mStatusBar.hideKeyguard();
                                 });
@@ -602,6 +607,7 @@
                     mBiometricUnlockController.finishKeyguardFadingAway();
                 }
             }
+            updateLockIcon();
             updateStates();
             mStatusBarWindowController.setKeyguardShowing(false);
             mViewMediatorCallback.keyguardGone();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
index f36c56f..a71fcdb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
@@ -107,6 +107,9 @@
         mListeners.remove(listener);
     }
 
+    /**
+     * If there are faces enrolled and user enabled face auth on keyguard.
+     */
     public boolean isUnlockingWithFacePossible() {
         return mIsUnlockingWithFacePossible;
     }
@@ -119,15 +122,16 @@
                 || (Build.IS_DEBUGGABLE && DEBUG_AUTH_WITH_ADB && mDebugUnlocked);
         boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user);
         boolean trusted = mKeyguardUpdateMonitor.getUserHasTrust(user);
-        boolean hasEnrolledFaces = mKeyguardUpdateMonitor.isUnlockWithFacePossible(user);
-        boolean changed = secure != mSecure || canSkipBouncer != mCanSkipBouncer ||
-                trustManaged != mTrustManaged || mIsUnlockingWithFacePossible != hasEnrolledFaces;
+        boolean isUnlockingWithFacePossible = mKeyguardUpdateMonitor.isUnlockWithFacePossible(user);
+        boolean changed = secure != mSecure || canSkipBouncer != mCanSkipBouncer
+                || trustManaged != mTrustManaged
+                || mIsUnlockingWithFacePossible != isUnlockingWithFacePossible;
         if (changed || updateAlways) {
             mSecure = secure;
             mCanSkipBouncer = canSkipBouncer;
             mTrusted = trusted;
             mTrustManaged = trustManaged;
-            mIsUnlockingWithFacePossible = hasEnrolledFaces;
+            mIsUnlockingWithFacePossible = isUnlockingWithFacePossible;
             notifyListeners();
         }
         Trace.endSection();
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index bdc6341..db6177a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -103,7 +103,8 @@
         when(context.getPackageManager()).thenReturn(mPackageManager);
         doAnswer(invocation -> {
             IBiometricEnabledOnKeyguardCallback callback = invocation.getArgument(0);
-            callback.onChanged(BiometricSourceType.FACE, true /* enabled */);
+            callback.onChanged(BiometricSourceType.FACE, true /* enabled */,
+                    KeyguardUpdateMonitor.getCurrentUser());
             return null;
         }).when(mBiometricManager).registerEnabledOnKeyguardCallback(any());
         when(mFaceManager.isHardwareDetected()).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
index 2d6ae26..2ed0970 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
@@ -24,6 +24,7 @@
 import static org.mockito.Mockito.withSettings;
 
 import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.utils.hardware.FakeSensorManager;
 
 import org.mockito.Answers;
 import org.mockito.MockSettings;
@@ -39,6 +40,7 @@
         when(params.getPickupPerformsProxCheck()).thenReturn(true);
         when(params.getPolicy()).thenReturn(mock(AlwaysOnDisplayPolicy.class));
         when(params.doubleTapReportsTouchCoordinates()).thenReturn(false);
+        when(params.getDisplayNeedsBlanking()).thenReturn(false);
 
         doneHolder[0] = true;
         return params;
@@ -52,11 +54,17 @@
         when(config.pickupGestureEnabled(anyInt())).thenReturn(false);
         when(config.pulseOnNotificationEnabled(anyInt())).thenReturn(true);
         when(config.alwaysOnEnabled(anyInt())).thenReturn(false);
+        when(config.enabled(anyInt())).thenReturn(true);
+        when(config.getWakeLockScreenDebounce()).thenReturn(0L);
 
         when(config.doubleTapSensorType()).thenReturn(null);
         when(config.tapSensorType()).thenReturn(null);
         when(config.longPressSensorType()).thenReturn(null);
 
+        when(config.tapGestureEnabled(anyInt())).thenReturn(true);
+        when(config.tapSensorAvailable()).thenReturn(true);
+        when(config.tapSensorType()).thenReturn(FakeSensorManager.TAP_SENSOR_TYPE);
+
         when(config.dozePickupSensorAvailable()).thenReturn(false);
         when(config.wakeScreenGestureAvailable()).thenReturn(false);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index 6979fd8..eb8ef09 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -19,6 +19,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -27,18 +28,17 @@
 import static org.mockito.Mockito.when;
 
 import android.app.AlarmManager;
-import android.app.Instrumentation;
+import android.hardware.Sensor;
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.os.Handler;
 import android.os.Looper;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
 
-import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.dock.DockManagerFake;
+import com.android.systemui.dock.DockManager;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.util.wakelock.WakeLock;
 import com.android.systemui.util.wakelock.WakeLockFake;
@@ -46,14 +46,12 @@
 
 import org.junit.Before;
 import org.junit.BeforeClass;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @SmallTest
-@Ignore("failing")
 @RunWith(AndroidTestingRunner.class)
-@RunWithLooper
+@RunWithLooper(setAsMainLooper = true)
 public class DozeTriggersTest extends SysuiTestCase {
     private DozeTriggers mTriggers;
     private DozeMachine mMachine;
@@ -61,10 +59,10 @@
     private AmbientDisplayConfiguration mConfig;
     private DozeParameters mParameters;
     private FakeSensorManager mSensors;
+    private Sensor mTapSensor;
     private WakeLock mWakeLock;
-    private Instrumentation mInstrumentation;
     private AlarmManager mAlarmManager;
-    private DockManagerFake mDockManagerFake;
+    private DockManager mDockManagerFake;
 
     @BeforeClass
     public static void setupSuite() {
@@ -74,15 +72,15 @@
 
     @Before
     public void setUp() throws Exception {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
         mMachine = mock(DozeMachine.class);
         mAlarmManager = mock(AlarmManager.class);
-        mHost = new DozeHostFake();
+        mHost = spy(new DozeHostFake());
         mConfig = DozeConfigurationUtil.createMockConfig();
         mParameters = DozeConfigurationUtil.createMockParameters();
-        mSensors = new FakeSensorManager(mContext);
+        mSensors = spy(new FakeSensorManager(mContext));
+        mTapSensor = mSensors.getFakeTapSensor().getSensor();
         mWakeLock = new WakeLockFake();
-        mDockManagerFake = spy(new DockManagerFake());
+        mDockManagerFake = mock(DockManager.class);
 
         mTriggers = new DozeTriggers(mContext, mMachine, mHost, mAlarmManager, mConfig, mParameters,
                 mSensors, Handler.createAsync(Looper.myLooper()), mWakeLock, true,
@@ -95,29 +93,45 @@
 
         mTriggers.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
         mTriggers.transitionTo(DozeMachine.State.INITIALIZED, DozeMachine.State.DOZE);
+        clearInvocations(mMachine);
 
         mHost.callback.onNotificationAlerted();
-
         mSensors.getMockProximitySensor().sendProximityResult(false); /* Near */
 
         verify(mMachine, never()).requestState(any());
         verify(mMachine, never()).requestPulse(anyInt());
 
         mHost.callback.onNotificationAlerted();
-
         mSensors.getMockProximitySensor().sendProximityResult(true); /* Far */
 
         verify(mMachine).requestPulse(anyInt());
     }
 
     @Test
+    public void testTransitionTo_disablesAndEnablesTouchSensors() {
+        when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE);
+
+        mTriggers.transitionTo(DozeMachine.State.INITIALIZED, DozeMachine.State.DOZE);
+        verify(mSensors).requestTriggerSensor(any(), eq(mTapSensor));
+
+        clearInvocations(mSensors);
+        mTriggers.transitionTo(DozeMachine.State.DOZE,
+                DozeMachine.State.DOZE_REQUEST_PULSE);
+        mTriggers.transitionTo(DozeMachine.State.DOZE_REQUEST_PULSE,
+                DozeMachine.State.DOZE_PULSING);
+        verify(mSensors).cancelTriggerSensor(any(), eq(mTapSensor));
+
+        clearInvocations(mSensors);
+        mTriggers.transitionTo(DozeMachine.State.DOZE_PULSING, DozeMachine.State.DOZE_PULSE_DONE);
+        verify(mSensors).requestTriggerSensor(any(), eq(mTapSensor));
+    }
+
+    @Test
     public void testDockEventListener_registerAndUnregister() {
         mTriggers.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
-
         verify(mDockManagerFake).addListener(any());
 
         mTriggers.transitionTo(DozeMachine.State.DOZE, DozeMachine.State.FINISH);
-
         verify(mDockManagerFake).removeListener(any());
     }
 
@@ -128,7 +142,6 @@
         mTriggers.onSensor(DozeLog.REASON_SENSOR_DOUBLE_TAP,
                 false /* sensorPerformedProxCheck */, 50 /* screenX */, 50 /* screenY */,
                 null /* rawValues */);
-
         verify(mMachine, never()).wakeUp();
     }
 
@@ -142,7 +155,7 @@
                 false /* sensorPerformedProxCheck */, 50 /* screenX */, 50 /* screenY */,
                 null /* rawValues */);
 
-        verify(mHost).setAodDimmingScrim(eq(255));
+        verify(mHost).setAodDimmingScrim(eq(1f));
         verify(mMachine).wakeUp();
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
index 87ae85f..f07edf3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
@@ -18,6 +18,7 @@
 
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -29,6 +30,7 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.DozeParameters;
 
 import org.junit.Before;
@@ -44,12 +46,14 @@
 
     private DozeWallpaperState mDozeWallpaperState;
     @Mock IWallpaperManager mIWallpaperManager;
+    @Mock BiometricUnlockController mBiometricUnlockController;
     @Mock DozeParameters mDozeParameters;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mDozeWallpaperState = new DozeWallpaperState(mIWallpaperManager, mDozeParameters);
+        mDozeWallpaperState = new DozeWallpaperState(mIWallpaperManager, mBiometricUnlockController,
+                mDozeParameters);
     }
 
     @Test
@@ -102,6 +106,20 @@
     }
 
     @Test
+    public void testDoesNotAnimate_whenWakeAndUnlock() throws RemoteException {
+        // Pre-conditions
+        when(mDozeParameters.getAlwaysOn()).thenReturn(true);
+        when(mBiometricUnlockController.unlockedByWakeAndUnlock()).thenReturn(true);
+
+        mDozeWallpaperState.transitionTo(DozeMachine.State.UNINITIALIZED,
+                DozeMachine.State.DOZE_AOD);
+        clearInvocations(mIWallpaperManager);
+
+        mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_AOD, DozeMachine.State.FINISH);
+        verify(mIWallpaperManager).setInAmbientMode(eq(false), eq(0L));
+    }
+
+    @Test
     public void testTransitionTo_requestPulseIsAmbientMode() throws RemoteException {
         mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE,
                 DozeMachine.State.DOZE_REQUEST_PULSE);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
index 5c1f473..881cc39 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
@@ -64,7 +64,7 @@
     protected static final int TEST_AUTO_DISMISS_TIME = 500;
     // Number of notifications to use in tests requiring multiple notifications
     private static final int TEST_NUM_NOTIFICATIONS = 4;
-    protected static final int TEST_TIMEOUT_TIME = 10000;
+    protected static final int TEST_TIMEOUT_TIME = 15000;
     protected final Runnable TEST_TIMEOUT_RUNNABLE = () -> mTimedOut = true;
 
     private AlertingNotificationManager mAlertingNotificationManager;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
index a99dc7f..7d9920d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyFloat;
@@ -192,6 +194,34 @@
     }
 
     @Test
+    public void onBiometricAuthenticated_whenBypassOnBouncer_dismissBouncer() {
+        reset(mKeyguardBypassController);
+        when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(true);
+        when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
+        when(mKeyguardBypassController.onBiometricAuthenticated(any())).thenReturn(true);
+        when(mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing()).thenReturn(true);
+        mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
+                BiometricSourceType.FACE);
+
+        verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(eq(false));
+        assertThat(mBiometricUnlockController.getMode())
+                .isEqualTo(BiometricUnlockController.MODE_DISMISS_BOUNCER);
+    }
+
+    @Test
+    public void onBiometricAuthenticated_whenBypassOnBouncer_respectsCanPlaySubtleAnim() {
+        when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(true);
+        when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
+        when(mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing()).thenReturn(true);
+        mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
+                BiometricSourceType.FACE);
+
+        verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(eq(false));
+        assertThat(mBiometricUnlockController.getMode())
+                .isEqualTo(BiometricUnlockController.MODE_UNLOCK_FADING);
+    }
+
+    @Test
     public void onBiometricAuthenticated_whenFaceAndPulsing_dontDismissKeyguard() {
         reset(mUpdateMonitor);
         reset(mStatusBarKeyguardViewManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
index f8b9e68..48934da 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
@@ -70,7 +70,6 @@
             setUp(statusBarWindowView, groupManager, bar, vsManager);
             mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
             mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
-            mAutoDismissNotificationDecayDozing = TEST_AUTO_DISMISS_TIME;
         }
     }
 
@@ -134,13 +133,11 @@
 
     @Test
     public void testExtendHeadsUp() {
-        when(mStatusBarStateController.isDozing()).thenReturn(true);
         mHeadsUpManager.showNotification(mEntry);
         Runnable pastNormalTimeRunnable =
                 () -> mLivesPastNormalTime = mHeadsUpManager.isAlerting(mEntry.key);
         mTestHandler.postDelayed(pastNormalTimeRunnable,
-                mHeadsUpManager.mAutoDismissNotificationDecayDozing +
-                        mHeadsUpManager.mExtensionTime / 2);
+                TEST_AUTO_DISMISS_TIME + mHeadsUpManager.mExtensionTime / 2);
         mTestHandler.postDelayed(TEST_TIMEOUT_RUNNABLE, TEST_TIMEOUT_TIME);
 
         mHeadsUpManager.extendHeadsUp();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java b/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java
index a4ae166..29b8ab60 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java
@@ -40,18 +40,23 @@
 import java.util.List;
 import java.util.stream.Collectors;
 
+import javax.annotation.Nullable;
+
 /**
  * Rudimentary fake for SensorManager
  *
- * Currently only supports the proximity sensor.
+ * Currently only supports proximity, light and tap sensors.
  *
  * Note that this class ignores the "Handler" argument, so the test is responsible for calling the
  * listener on the right thread.
  */
 public class FakeSensorManager extends SensorManager {
 
+    public static final String TAP_SENSOR_TYPE = "tapSensorType";
+
     private final MockProximitySensor mMockProximitySensor;
     private final FakeGenericSensor mFakeLightSensor;
+    private final FakeGenericSensor mFakeTapSensor;
     private final FakeGenericSensor[] mSensors;
 
     public FakeSensorManager(Context context) throws Exception {
@@ -59,12 +64,13 @@
                 .getDefaultSensor(Sensor.TYPE_PROXIMITY);
         if (proxSensor == null) {
             // No prox? Let's create a fake one!
-            proxSensor = createSensor(Sensor.TYPE_PROXIMITY);
+            proxSensor = createSensor(Sensor.TYPE_PROXIMITY, null);
         }
 
         mSensors = new FakeGenericSensor[]{
                 mMockProximitySensor = new MockProximitySensor(proxSensor),
-                mFakeLightSensor = new FakeGenericSensor(createSensor(Sensor.TYPE_LIGHT)),
+                mFakeLightSensor = new FakeGenericSensor(createSensor(Sensor.TYPE_LIGHT, null)),
+                mFakeTapSensor = new FakeGenericSensor(createSensor(99, TAP_SENSOR_TYPE))
         };
     }
 
@@ -76,6 +82,10 @@
         return mFakeLightSensor;
     }
 
+    public FakeGenericSensor getFakeTapSensor() {
+        return mFakeTapSensor;
+    }
+
     @Override
     public Sensor getDefaultSensor(int type) {
         Sensor s = super.getDefaultSensor(type);
@@ -160,13 +170,13 @@
 
     @Override
     protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) {
-        return false;
+        return true;
     }
 
     @Override
     protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor,
             boolean disable) {
-        return false;
+        return true;
     }
 
     @Override
@@ -185,12 +195,15 @@
         return false;
     }
 
-    private Sensor createSensor(int type) throws Exception {
+    private Sensor createSensor(int type, @Nullable String stringType) throws Exception {
         Constructor<Sensor> constr = Sensor.class.getDeclaredConstructor();
         constr.setAccessible(true);
         Sensor sensor = constr.newInstance();
 
         setSensorType(sensor, type);
+        if (stringType != null) {
+            setSensorField(sensor, "mStringType", stringType);
+        }
         setSensorField(sensor, "mName", "Mock " + sensor.getStringType() + "/" + type);
         setSensorField(sensor, "mVendor", "Mock Vendor");
         setSensorField(sensor, "mVersion", 1);
diff --git a/proto/src/task_snapshot.proto b/proto/src/task_snapshot.proto
index 381d983..821db86 100644
--- a/proto/src/task_snapshot.proto
+++ b/proto/src/task_snapshot.proto
@@ -33,4 +33,5 @@
      bool is_translucent = 9;
      string top_activity_component = 10;
      float scale = 11;
- }
\ No newline at end of file
+     int64 id = 12;
+ }
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index 1873de5..2db7f0e 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -17,7 +17,6 @@
 package com.android.server.accessibility;
 
 import static android.accessibilityservice.AccessibilityServiceInfo.DEFAULT;
-import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS;
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS;
@@ -37,6 +36,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
 import android.graphics.Region;
+import android.hardware.display.DisplayManager;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -49,6 +49,7 @@
 import android.os.SystemClock;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.view.Display;
 import android.view.KeyEvent;
 import android.view.MagnificationSpec;
 import android.view.View;
@@ -91,6 +92,7 @@
     private final WindowManagerInternal mWindowManagerService;
     private final GlobalActionPerformer mGlobalActionPerformer;
     private final AccessibilityWindowManager mA11yWindowManager;
+    private final DisplayManager mDisplayManager;
     private final PowerManager mPowerManager;
 
     // Handler for scheduling method invocations on the main thread.
@@ -149,7 +151,7 @@
     // types as message types allowing us to remove messages per event type.
     public Handler mEventDispatchHandler;
 
-    final IBinder mOverlayWindowToken = new Binder();
+    final SparseArray<IBinder> mOverlayWindowTokens = new SparseArray();
 
 
     public interface SystemSupport {
@@ -222,6 +224,7 @@
         mSystemSupport = systemSupport;
         mInvocationHandler = new InvocationHandler(mainHandler.getLooper());
         mA11yWindowManager = a11yWindowManager;
+        mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mEventDispatchHandler = new Handler(mainHandler.getLooper()) {
             @Override
@@ -928,24 +931,73 @@
     }
 
     public void onAdded() {
+        final Display[] displays = mDisplayManager.getDisplays();
+        for (int i = 0; i < displays.length; i++) {
+            final int displayId = displays[i].getDisplayId();
+            onDisplayAdded(displayId);
+        }
+    }
+
+    /**
+     * Called whenever a logical display has been added to the system. Add a window token for adding
+     * an accessibility overlay.
+     *
+     * @param displayId The id of the logical display that was added.
+     */
+    public void onDisplayAdded(int displayId) {
         final long identity = Binder.clearCallingIdentity();
         try {
-            mWindowManagerService.addWindowToken(mOverlayWindowToken,
-                    TYPE_ACCESSIBILITY_OVERLAY, DEFAULT_DISPLAY);
+            final IBinder overlayWindowToken = new Binder();
+            mWindowManagerService.addWindowToken(overlayWindowToken, TYPE_ACCESSIBILITY_OVERLAY,
+                    displayId);
+            synchronized (mLock) {
+                mOverlayWindowTokens.put(displayId, overlayWindowToken);
+            }
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
     public void onRemoved() {
+        final Display[] displays = mDisplayManager.getDisplays();
+        for (int i = 0; i < displays.length; i++) {
+            final int displayId = displays[i].getDisplayId();
+            onDisplayRemoved(displayId);
+        }
+    }
+
+    /**
+     * Called whenever a logical display has been removed from the system. Remove a window token for
+     * removing an accessibility overlay.
+     *
+     * @param displayId The id of the logical display that was added.
+     */
+    public void onDisplayRemoved(int displayId) {
         final long identity = Binder.clearCallingIdentity();
         try {
-            mWindowManagerService.removeWindowToken(mOverlayWindowToken, true, DEFAULT_DISPLAY);
+            mWindowManagerService.removeWindowToken(mOverlayWindowTokens.get(displayId), true,
+                    displayId);
+            synchronized (mLock) {
+                mOverlayWindowTokens.remove(displayId);
+            }
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
+    /**
+     * Gets overlay window token by the display Id.
+     *
+     * @param displayId The id of the logical display that was added.
+     * @return window token.
+     */
+    @Override
+    public IBinder getOverlayWindowToken(int displayId) {
+        synchronized (mLock) {
+            return mOverlayWindowTokens.get(displayId);
+        }
+    }
+
     public void resetLocked() {
         mSystemSupport.getKeyEventDispatcher().flush(this);
         try {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 47f137c..d108469 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -2550,6 +2550,13 @@
                     mInputFilter.onDisplayChanged();
                 }
                 UserState userState = getCurrentUserStateLocked();
+                if (displayId != Display.DEFAULT_DISPLAY) {
+                    final List<AccessibilityServiceConnection> services = userState.mBoundServices;
+                    for (int i = 0; i < services.size(); i++) {
+                        AccessibilityServiceConnection boundClient = services.get(i);
+                        boundClient.onDisplayAdded(displayId);
+                    }
+                }
                 updateMagnificationLocked(userState);
             }
         }
@@ -2566,6 +2573,14 @@
                 if (mInputFilter != null) {
                     mInputFilter.onDisplayChanged();
                 }
+                UserState userState = getCurrentUserStateLocked();
+                if (displayId != Display.DEFAULT_DISPLAY) {
+                    final List<AccessibilityServiceConnection> services = userState.mBoundServices;
+                    for (int i = 0; i < services.size(); i++) {
+                        AccessibilityServiceConnection boundClient = services.get(i);
+                        boundClient.onDisplayRemoved(displayId);
+                    }
+                }
             }
             if (mMagnificationController != null) {
                 mMagnificationController.onDisplayRemoved(displayId);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
index 547f7d3..02306c0 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
@@ -31,6 +31,7 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Slog;
+import android.view.Display;
 
 import com.android.server.accessibility.AccessibilityManagerService.UserState;
 import com.android.server.wm.WindowManagerInternal;
@@ -196,7 +197,7 @@
             return;
         }
         try {
-            serviceInterface.init(this, mId, mOverlayWindowToken);
+            serviceInterface.init(this, mId, mOverlayWindowTokens.get(Display.DEFAULT_DISPLAY));
         } catch (RemoteException re) {
             Slog.w(LOG_TAG, "Error while setting connection for service: "
                     + serviceInterface, re);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
index 8415272..1dea2f2 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
@@ -23,7 +23,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Binder;
 import android.os.Handler;
@@ -277,7 +276,7 @@
         } else if (!oldWindow.activityToken.equals(newWindow.activityToken)) {
             return true;
         }
-        if (!oldWindow.boundsInScreen.equals(newWindow.boundsInScreen)) {
+        if (!oldWindow.regionInScreen.equals(newWindow.regionInScreen)) {
             return true;
         }
         if (oldWindow.childTokens != null && newWindow.childTokens != null
@@ -755,20 +754,20 @@
         boolean windowInteractiveRegionChanged = false;
 
         final int windowCount = mWindows.size();
-        final Rect currentWindowBounds = new Rect();
+        final Region currentWindowRegions = new Region();
         for (int i = windowCount - 1; i >= 0; i--) {
             AccessibilityWindowInfo currentWindow = mWindows.get(i);
             if (windowInteractiveRegion == null) {
                 if (currentWindow.getId() == windowId) {
-                    currentWindow.getBoundsInScreen(currentWindowBounds);
-                    outRegion.set(currentWindowBounds);
+                    currentWindow.getRegionInScreen(currentWindowRegions);
+                    outRegion.set(currentWindowRegions);
                     windowInteractiveRegion = outRegion;
                     continue;
                 }
             } else if (currentWindow.getType()
                     != AccessibilityWindowInfo.TYPE_ACCESSIBILITY_OVERLAY) {
-                currentWindow.getBoundsInScreen(currentWindowBounds);
-                if (windowInteractiveRegion.op(currentWindowBounds, Region.Op.DIFFERENCE)) {
+                currentWindow.getRegionInScreen(currentWindowRegions);
+                if (windowInteractiveRegion.op(currentWindowRegions, Region.Op.DIFFERENCE)) {
                     windowInteractiveRegionChanged = true;
                 }
             }
@@ -1115,7 +1114,7 @@
         reportedWindow.setType(getTypeForWindowManagerWindowType(window.type));
         reportedWindow.setLayer(window.layer);
         reportedWindow.setFocused(window.focused);
-        reportedWindow.setBoundsInScreen(window.boundsInScreen);
+        reportedWindow.setRegionInScreen(window.regionInScreen);
         reportedWindow.setTitle(window.title);
         reportedWindow.setAnchorId(window.accessibilityIdOfAnchor);
         reportedWindow.setPictureInPicture(window.inPictureInPicture);
diff --git a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
index 285bd09..2698b72 100644
--- a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
@@ -27,6 +27,7 @@
 import android.os.IBinder.DeathRecipient;
 import android.os.RemoteException;
 import android.util.Slog;
+import android.view.Display;
 import android.view.accessibility.AccessibilityEvent;
 
 import com.android.internal.util.DumpUtils;
@@ -246,7 +247,8 @@
                     // another thread.
                     if (serviceInterface != null) {
                         service.linkToDeath(this, 0);
-                        serviceInterface.init(this, mId, mOverlayWindowToken);
+                        serviceInterface.init(this, mId,
+                                mOverlayWindowTokens.get(Display.DEFAULT_DISPLAY));
                     }
                 } catch (RemoteException re) {
                     Slog.w(LOG_TAG, "Error initialized connection", re);
diff --git a/services/art-profile b/services/art-profile
index a9d5982..cbc4627 100644
--- a/services/art-profile
+++ b/services/art-profile
@@ -16071,7 +16071,7 @@
 PLcom/android/server/wm/DisplayPolicy;->offsetInputMethodWindowLw(Lcom/android/server/wm/WindowState;Lcom/android/server/wm/DisplayFrames;)V
 HSPLcom/android/server/wm/DisplayPolicy;->onConfigurationChanged()V
 PLcom/android/server/wm/DisplayPolicy;->onPowerKeyDown(Z)V
-HSPLcom/android/server/wm/DisplayPolicy;->prepareAddWindowLw(Lcom/android/server/wm/WindowState;Landroid/view/WindowManager$LayoutParams;)I
+HSPLcom/android/server/wm/DisplayPolicy;->validateAddingWindowLw(Landroid/view/WindowManager$LayoutParams;)I
 HSPLcom/android/server/wm/DisplayPolicy;->removeWindowLw(Lcom/android/server/wm/WindowState;)V
 HSPLcom/android/server/wm/DisplayPolicy;->requestTransientBars(Lcom/android/server/wm/WindowState;)V
 HSPLcom/android/server/wm/DisplayPolicy;->resetSystemUiVisibilityLw()V
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index aada967..1e1e07d 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -769,6 +769,19 @@
     }
 
     /**
+     * Updates the last fill response when a dataset is shown.
+     */
+    void logDatasetShown(int sessionId, @Nullable Bundle clientState) {
+        synchronized (mLock) {
+            if (isValidEventLocked("logDatasetShown", sessionId)) {
+                mEventHistory.addEvent(
+                        new Event(Event.TYPE_DATASETS_SHOWN, null, clientState, null, null, null,
+                                null, null, null, null, null));
+            }
+        }
+    }
+
+    /**
      * Updates the last fill response when an autofill context is committed.
      */
     @GuardedBy("mLock")
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 988db6a..46c2a85 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -2497,6 +2497,8 @@
                 mService.getServicePackageName(), mComponentName,
                 serviceLabel, serviceIcon, this, id, mCompatMode);
 
+        mService.logDatasetShown(id, mClientState);
+
         synchronized (mLock) {
             if (mUiShownTime == 0) {
                 // Log first time UI is shown.
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 8df25b5..d5a7c81 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -194,6 +194,11 @@
         }
     }
 
+    boolean isAbleToServeUser(int userId) {
+        return getServiceUsers().get(UserHandle.USER_SYSTEM) != null
+                && getServiceUsers().get(userId) != null;
+    }
+
     /**
      *  Returns a lst of users currently unlocked that have a
      *  {@link UserBackupManagerService} registered.
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index 53bbac4..f4b6645 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -202,11 +202,10 @@
         }
     }
 
-    // A user is ready for a backup if it's unlocked and is not suppressed by a device
-    // admin (device owner or profile owner).
+    // This method should not perform any I/O (e.g. do not call isBackupActivatedForUser),
+    // it's used in multiple places where I/O waits would cause system lock-ups.
     private boolean isUserReadyForBackup(int userId) {
-        return mService != null && mService.getServiceUsers().get(userId) != null
-                && isBackupActivatedForUser(userId);
+        return mService != null && mService.isAbleToServeUser(userId);
     }
 
     /**
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
index 18ee7a4..18c38dc 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
@@ -128,7 +128,7 @@
 
     private static final String TAG = "PFTBT";
 
-    private UserBackupManagerService backupManagerService;
+    private UserBackupManagerService mUserBackupManagerService;
     private final Object mCancelLock = new Object();
 
     ArrayList<PackageInfo> mPackages;
@@ -159,7 +159,7 @@
             @Nullable IBackupManagerMonitor monitor, @Nullable OnTaskFinishedListener listener,
             boolean userInitiated) {
         super(observer);
-        this.backupManagerService = backupManagerService;
+        this.mUserBackupManagerService = backupManagerService;
         mTransportClient = transportClient;
         mUpdateSchedule = updateSchedule;
         mLatch = latch;
@@ -252,16 +252,16 @@
     }
 
     private void registerTask() {
-        synchronized (backupManagerService.getCurrentOpLock()) {
+        synchronized (mUserBackupManagerService.getCurrentOpLock()) {
             Slog.d(TAG, "backupmanager pftbt token=" + Integer.toHexString(mCurrentOpToken));
-            backupManagerService.getCurrentOperations().put(
+            mUserBackupManagerService.getCurrentOperations().put(
                     mCurrentOpToken,
                     new Operation(OP_PENDING, this, OP_TYPE_BACKUP));
         }
     }
 
     public void unregisterTask() {
-        backupManagerService.removeOperation(mCurrentOpToken);
+        mUserBackupManagerService.removeOperation(mCurrentOpToken);
     }
 
     @Override
@@ -288,7 +288,7 @@
 
             mCancelAll = true;
             if (mIsDoingBackup) {
-                backupManagerService.handleCancel(mBackupRunnerOpToken, cancelAll);
+                mUserBackupManagerService.handleCancel(mBackupRunnerOpToken, cancelAll);
                 try {
                     // If we're running a backup we should be connected to a transport
                     IBackupTransport transport =
@@ -320,16 +320,17 @@
         int backupRunStatus = BackupManager.SUCCESS;
 
         try {
-            if (!backupManagerService.isEnabled() || !backupManagerService.isSetupComplete()) {
+            if (!mUserBackupManagerService.isEnabled()
+                    || !mUserBackupManagerService.isSetupComplete()) {
                 // Backups are globally disabled, so don't proceed.
                 if (DEBUG) {
-                    Slog.i(TAG, "full backup requested but enabled=" + backupManagerService
+                    Slog.i(TAG, "full backup requested but enabled=" + mUserBackupManagerService
                             .isEnabled()
-                            + " setupComplete=" + backupManagerService.isSetupComplete()
+                            + " setupComplete=" + mUserBackupManagerService.isSetupComplete()
                             + "; ignoring");
                 }
                 int monitoringEvent;
-                if (backupManagerService.isSetupComplete()) {
+                if (mUserBackupManagerService.isSetupComplete()) {
                     monitoringEvent = BackupManagerMonitor.LOG_EVENT_ID_BACKUP_DISABLED;
                 } else {
                     monitoringEvent = BackupManagerMonitor.LOG_EVENT_ID_DEVICE_NOT_PROVISIONED;
@@ -532,7 +533,8 @@
                 // Roll this package to the end of the backup queue if we're
                 // in a queue-driven mode (regardless of success/failure)
                 if (mUpdateSchedule) {
-                    backupManagerService.enqueueFullBackup(packageName, System.currentTimeMillis());
+                    mUserBackupManagerService.enqueueFullBackup(
+                            packageName, System.currentTimeMillis());
                 }
 
                 if (backupPackageStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
@@ -549,7 +551,8 @@
                     // from the preflight pass.  If we got as far as preflight, we now need
                     // to tear down the target process.
                     if (mBackupRunner != null) {
-                        backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+                        mUserBackupManagerService.tearDownAgentAndKill(
+                                currentPackage.applicationInfo);
                     }
                     // ... and continue looping.
                 } else if (backupPackageStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
@@ -561,7 +564,7 @@
                         EventLog.writeEvent(EventLogTags.FULL_BACKUP_QUOTA_EXCEEDED,
                                 packageName);
                     }
-                    backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+                    mUserBackupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
                     // Do nothing, clean up, and continue looping.
                 } else if (backupPackageStatus == BackupTransport.AGENT_ERROR) {
                     BackupObserverUtils
@@ -569,7 +572,7 @@
                                     BackupManager.ERROR_AGENT_FAILURE);
                     Slog.w(TAG, "Application failure for package: " + packageName);
                     EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName);
-                    backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+                    mUserBackupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
                     // Do nothing, clean up, and continue looping.
                 } else if (backupPackageStatus == BackupManager.ERROR_BACKUP_CANCELLED) {
                     BackupObserverUtils
@@ -578,7 +581,7 @@
                     Slog.w(TAG, "Backup cancelled. package=" + packageName +
                             ", cancelAll=" + mCancelAll);
                     EventLog.writeEvent(EventLogTags.FULL_BACKUP_CANCELLED, packageName);
-                    backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+                    mUserBackupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
                     // Do nothing, clean up, and continue looping.
                 } else if (backupPackageStatus != BackupTransport.TRANSPORT_OK) {
                     BackupObserverUtils
@@ -588,7 +591,7 @@
                     EventLog.writeEvent(EventLogTags.FULL_BACKUP_TRANSPORT_FAILURE);
                     // Abort entire backup pass.
                     backupRunStatus = BackupManager.ERROR_TRANSPORT_ABORTED;
-                    backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+                    mUserBackupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
                     return;
                 } else {
                     // Success!
@@ -596,14 +599,14 @@
                             .sendBackupOnPackageResult(mBackupObserver, packageName,
                                     BackupManager.SUCCESS);
                     EventLog.writeEvent(EventLogTags.FULL_BACKUP_SUCCESS, packageName);
-                    backupManagerService.logBackupComplete(packageName);
+                    mUserBackupManagerService.logBackupComplete(packageName);
                 }
                 cleanUpPipes(transportPipes);
                 cleanUpPipes(enginePipes);
                 if (currentPackage.applicationInfo != null) {
                     Slog.i(TAG, "Unbinding agent in " + packageName);
                     try {
-                        backupManagerService.getActivityManager().unbindBackupAgent(
+                        mUserBackupManagerService.getActivityManager().unbindBackupAgent(
                                 currentPackage.applicationInfo);
                     } catch (RemoteException e) { /* can't happen; activity manager is local */ }
                 }
@@ -639,8 +642,8 @@
                 mJob.finishBackupPass(mUserId);
             }
 
-            synchronized (backupManagerService.getQueueLock()) {
-                backupManagerService.setRunningFullBackupTask(null);
+            synchronized (mUserBackupManagerService.getQueueLock()) {
+                mUserBackupManagerService.setRunningFullBackupTask(null);
             }
 
             mListener.onFinished("PFTBT.run()");
@@ -650,11 +653,11 @@
             // Now that we're actually done with schedule-driven work, reschedule
             // the next pass based on the new queue state.
             if (mUpdateSchedule) {
-                backupManagerService.scheduleNextFullBackupJob(backoff);
+                mUserBackupManagerService.scheduleNextFullBackupJob(backoff);
             }
 
             Slog.i(TAG, "Full data backup pass finished.");
-            backupManagerService.getWakelock().release();
+            mUserBackupManagerService.getWakelock().release();
         }
     }
 
@@ -709,13 +712,13 @@
             long fullBackupAgentTimeoutMillis =
                     mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
             try {
-                backupManagerService.prepareOperationTimeout(
+                mUserBackupManagerService.prepareOperationTimeout(
                         mCurrentOpToken, fullBackupAgentTimeoutMillis, this, OP_TYPE_BACKUP_WAIT);
                 if (MORE_DEBUG) {
                     Slog.d(TAG, "Preflighting full payload of " + pkg.packageName);
                 }
                 agent.doMeasureFullBackup(mQuota, mCurrentOpToken,
-                        backupManagerService.getBackupManagerBinder(), mTransportFlags);
+                        mUserBackupManagerService.getBackupManagerBinder(), mTransportFlags);
 
                 // Now wait to get our result back.  If this backstop timeout is reached without
                 // the latch being thrown, flow will continue as though a result or "normal"
@@ -765,7 +768,7 @@
             }
             mResult.set(result);
             mLatch.countDown();
-            backupManagerService.removeOperation(mCurrentOpToken);
+            mUserBackupManagerService.removeOperation(mCurrentOpToken);
         }
 
         @Override
@@ -775,7 +778,7 @@
             }
             mResult.set(BackupTransport.AGENT_ERROR);
             mLatch.countDown();
-            backupManagerService.removeOperation(mCurrentOpToken);
+            mUserBackupManagerService.removeOperation(mCurrentOpToken);
         }
 
         @Override
@@ -812,7 +815,7 @@
             mOutput = ParcelFileDescriptor.dup(output.getFileDescriptor());
             mTarget = target;
             mCurrentOpToken = currentOpToken;
-            mEphemeralToken = backupManagerService.generateRandomIntegerToken();
+            mEphemeralToken = mUserBackupManagerService.generateRandomIntegerToken();
             mPreflight = new SinglePackageBackupPreflight(
                     transportClient, quota, mEphemeralToken, transportFlags);
             mPreflightLatch = new CountDownLatch(1);
@@ -825,23 +828,32 @@
         }
 
         void registerTask() {
-            synchronized (backupManagerService.getCurrentOpLock()) {
-                backupManagerService.getCurrentOperations().put(
+            synchronized (mUserBackupManagerService.getCurrentOpLock()) {
+                mUserBackupManagerService.getCurrentOperations().put(
                         mCurrentOpToken, new Operation(OP_PENDING, this, OP_TYPE_BACKUP_WAIT));
             }
         }
 
         void unregisterTask() {
-            synchronized (backupManagerService.getCurrentOpLock()) {
-                backupManagerService.getCurrentOperations().remove(mCurrentOpToken);
+            synchronized (mUserBackupManagerService.getCurrentOpLock()) {
+                mUserBackupManagerService.getCurrentOperations().remove(mCurrentOpToken);
             }
         }
 
         @Override
         public void run() {
             FileOutputStream out = new FileOutputStream(mOutput.getFileDescriptor());
-            mEngine = new FullBackupEngine(backupManagerService, out, mPreflight, mTarget, false,
-                    this, mQuota, mCurrentOpToken, mTransportFlags);
+            mEngine =
+                    new FullBackupEngine(
+                            mUserBackupManagerService,
+                            out,
+                            mPreflight,
+                            mTarget,
+                            false,
+                            this,
+                            mQuota,
+                            mCurrentOpToken,
+                            mTransportFlags);
             try {
                 try {
                     if (!mIsCancelled) {
@@ -928,13 +940,13 @@
                     mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, null);
             mIsCancelled = true;
             // Cancel tasks spun off by this task.
-            backupManagerService.handleCancel(mEphemeralToken, cancelAll);
-            backupManagerService.tearDownAgentAndKill(mTarget.applicationInfo);
+            mUserBackupManagerService.handleCancel(mEphemeralToken, cancelAll);
+            mUserBackupManagerService.tearDownAgentAndKill(mTarget.applicationInfo);
             // Free up everyone waiting on this task and its children.
             mPreflightLatch.countDown();
             mBackupLatch.countDown();
             // We are done with this operation.
-            backupManagerService.removeOperation(mCurrentOpToken);
+            mUserBackupManagerService.removeOperation(mCurrentOpToken);
         }
     }
 }
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 930cf9e..5089ee0 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -42,7 +42,6 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.PackageManagerInternal;
 import android.content.pm.ResolveInfo;
 import android.content.pm.Signature;
 import android.content.res.Resources;
@@ -121,6 +120,7 @@
 import com.android.server.location.MockProvider;
 import com.android.server.location.PassiveProvider;
 import com.android.server.location.RemoteListenerHelper;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import java.io.ByteArrayOutputStream;
 import java.io.FileDescriptor;
@@ -282,12 +282,12 @@
 
         // Let the package manager query which are the default location
         // providers as they get certain permissions granted by default.
-        PackageManagerInternal packageManagerInternal = LocalServices.getService(
-                PackageManagerInternal.class);
-        packageManagerInternal.setLocationPackagesProvider(
+        PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService(
+                PermissionManagerServiceInternal.class);
+        permissionManagerInternal.setLocationPackagesProvider(
                 userId -> mContext.getResources().getStringArray(
                         com.android.internal.R.array.config_locationProviderPackageNames));
-        packageManagerInternal.setLocationExtraPackagesProvider(
+        permissionManagerInternal.setLocationExtraPackagesProvider(
                 userId -> mContext.getResources().getStringArray(
                       com.android.internal.R.array.config_locationExtraPackageNames));
 
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 80d7ac9..df5005e 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -26,7 +26,6 @@
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
 import android.database.ContentObserver;
 import android.location.LocationManager;
 import android.net.INetworkRecommendationProvider;
@@ -54,15 +53,14 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
-import android.util.IntArray;
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.TransferPipe;
-import com.android.internal.telephony.SmsApplication;
 import com.android.internal.util.DumpUtils;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -294,7 +292,7 @@
                     String useOpenWifiPackage = Global.getString(mContext.getContentResolver(),
                             Global.USE_OPEN_WIFI_PACKAGE);
                     if (!TextUtils.isEmpty(useOpenWifiPackage)) {
-                        LocalServices.getService(PackageManagerInternal.class)
+                        LocalServices.getService(PermissionManagerServiceInternal.class)
                                 .grantDefaultPermissionsToDefaultUseOpenWifiApp(useOpenWifiPackage,
                                         userId);
                     }
@@ -306,17 +304,14 @@
                 false /*notifyForDescendants*/,
                 mUseOpenWifiPackageObserver);
         // Set a callback for the package manager to query the use open wifi app.
-        LocalServices.getService(PackageManagerInternal.class).setUseOpenWifiAppPackagesProvider(
-                new PackageManagerInternal.PackagesProvider() {
-                    @Override
-                    public String[] getPackages(int userId) {
-                        String useOpenWifiPackage = Global.getString(mContext.getContentResolver(),
-                                Global.USE_OPEN_WIFI_PACKAGE);
-                        if (!TextUtils.isEmpty(useOpenWifiPackage)) {
-                            return new String[]{useOpenWifiPackage};
-                        }
-                        return null;
+        LocalServices.getService(PermissionManagerServiceInternal.class)
+                .setUseOpenWifiAppPackagesProvider((userId) -> {
+                    String useOpenWifiPackage = Global.getString(mContext.getContentResolver(),
+                            Global.USE_OPEN_WIFI_PACKAGE);
+                    if (!TextUtils.isEmpty(useOpenWifiPackage)) {
+                        return new String[]{useOpenWifiPackage};
                     }
+                    return null;
                 });
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index adb0909..ff8c3e9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -347,6 +347,7 @@
 import com.android.server.Watchdog;
 import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto;
 import com.android.server.appop.AppOpsService;
+import com.android.server.compat.CompatConfig;
 import com.android.server.contentcapture.ContentCaptureManagerInternal;
 import com.android.server.firewall.IntentFirewall;
 import com.android.server.job.JobSchedulerInternal;
@@ -392,7 +393,9 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -5027,6 +5030,7 @@
             bindApplicationTimeMillis = SystemClock.elapsedRealtime();
             mAtmInternal.preBindApplication(app.getWindowProcessController());
             final ActiveInstrumentation instr2 = app.getActiveInstrumentation();
+            long[] disabledCompatChanges = CompatConfig.get().getDisabledChanges(app.info);
             if (app.isolatedEntryPoint != null) {
                 // This is an isolated process which should just call an entry point instead of
                 // being bound to an application.
@@ -5042,7 +5046,8 @@
                         new Configuration(app.getWindowProcessController().getConfiguration()),
                         app.compat, getCommonServicesLocked(app.isolated),
                         mCoreSettingsObserver.getCoreSettingsLocked(),
-                        buildSerial, autofillOptions, contentCaptureOptions);
+                        buildSerial, autofillOptions, contentCaptureOptions,
+                        disabledCompatChanges);
             } else {
                 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                         null, null, null, testMode,
@@ -5051,7 +5056,8 @@
                         new Configuration(app.getWindowProcessController().getConfiguration()),
                         app.compat, getCommonServicesLocked(app.isolated),
                         mCoreSettingsObserver.getCoreSettingsLocked(),
-                        buildSerial, autofillOptions, contentCaptureOptions);
+                        buildSerial, autofillOptions, contentCaptureOptions,
+                        disabledCompatChanges);
             }
             if (profilerInfo != null) {
                 profilerInfo.closeFd();
@@ -7706,6 +7712,34 @@
         return null;
     }
 
+    int checkContentProviderUriPermission(Uri uri, int userId, int callingUid, int modeFlags) {
+        final String name = uri.getAuthority();
+        final long ident = Binder.clearCallingIdentity();
+        ContentProviderHolder holder = null;
+        try {
+            holder = getContentProviderExternalUnchecked(name, null, callingUid,
+                    "*checkContentProviderUriPermission*", userId);
+            if (holder != null) {
+                return holder.provider.checkUriPermission(null, uri, callingUid, modeFlags);
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "Content provider dead retrieving " + uri, e);
+            return PackageManager.PERMISSION_DENIED;
+        } catch (Exception e) {
+            Log.w(TAG, "Exception while determining type of " + uri, e);
+            return PackageManager.PERMISSION_DENIED;
+        } finally {
+            try {
+                if (holder != null) {
+                    removeContentProviderExternalUnchecked(name, null, userId);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+        return PackageManager.PERMISSION_DENIED;
+    }
+
     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
         if (UserHandle.getUserId(callingUid) == userId) {
             return true;
@@ -17826,6 +17860,35 @@
         }
 
         @Override
+        public int checkContentProviderUriPermission(Uri uri, int userId,
+                int callingUid, int modeFlags) {
+            // We can find ourselves needing to check Uri permissions while
+            // already holding the WM lock, which means reaching back here for
+            // the AM lock would cause an inversion. The WM team has requested
+            // that we use the strategy below instead of shifting where Uri
+            // grants are calculated.
+
+            // Since we could also arrive here while holding the AM lock, we
+            // can't always delegate the call through the handler, and we need
+            // to delicately dance between the deadlocks.
+            if (Thread.currentThread().holdsLock(ActivityManagerService.this)) {
+                return ActivityManagerService.this.checkContentProviderUriPermission(uri,
+                        userId, callingUid, modeFlags);
+            } else {
+                final CompletableFuture<Integer> res = new CompletableFuture<>();
+                mHandler.post(() -> {
+                    res.complete(ActivityManagerService.this.checkContentProviderUriPermission(uri,
+                            userId, callingUid, modeFlags));
+                });
+                try {
+                    return res.get();
+                } catch (InterruptedException | ExecutionException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+
+        @Override
         public void onWakefulnessChanged(int wakefulness) {
             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index f7512f9..33070dc 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -89,6 +89,7 @@
 import com.android.internal.util.HexDump;
 import com.android.internal.util.MemInfoReader;
 import com.android.internal.util.Preconditions;
+import com.android.server.compat.CompatConfig;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -290,6 +291,8 @@
                     return runNoHomeScreen(pw);
                 case "wait-for-broadcast-idle":
                     return runWaitForBroadcastIdle(pw);
+                case "compat":
+                    return runCompat(pw);
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -2874,6 +2877,50 @@
         return 0;
     }
 
+    private int runCompat(PrintWriter pw) {
+        final CompatConfig config = CompatConfig.get();
+        String toggleValue = getNextArgRequired();
+        long changeId;
+        String changeIdString = getNextArgRequired();
+        try {
+            changeId = Long.parseLong(changeIdString);
+        } catch (NumberFormatException e) {
+            changeId = config.lookupChangeId(changeIdString);
+        }
+        if (changeId == -1) {
+            pw.println("Unknown or invalid change: '" + changeIdString + "'.");
+        }
+        String packageName = getNextArgRequired();
+        switch(toggleValue) {
+            case "enable":
+                if (!config.addOverride(changeId, packageName, true)) {
+                    pw.println("Warning! Change " + changeId + " is not known yet. Enabling it"
+                            + " could have no effect.");
+                }
+                pw.println("Enabled change " + changeId + " for " + packageName + ".");
+                return 0;
+            case "disable":
+                if (!config.addOverride(changeId, packageName, false)) {
+                    pw.println("Warning! Change " + changeId + " is not known yet. Disabling it"
+                            + " could have no effect.");
+                }
+                pw.println("Disabled change " + changeId + " for " + packageName + ".");
+                return 0;
+            case "reset":
+                if (config.removeOverride(changeId, packageName)) {
+                    pw.println("Reset change " + changeId + " for " + packageName
+                            + " to default value.");
+                } else {
+                    pw.println("No override exists for changeId " + changeId + ".");
+                }
+                return 0;
+            default:
+                pw.println("Invalid toggle value: '" + toggleValue + "'.");
+        }
+        return -1;
+    }
+
+
     private Resources getResources(PrintWriter pw) throws RemoteException {
         // system resources does not contain all the device configuration, construct it manually.
         Configuration config = mInterface.getConfiguration();
@@ -3181,6 +3228,8 @@
             pw.println("      without restarting any processes.");
             pw.println("  write");
             pw.println("      Write all pending state to storage.");
+            pw.println("  compat enable|disable|reset <CHANGE_ID|CHANGE_NAME> <PACKAGE_NAME>");
+            pw.println("      Toggles a change either by id or by name for <PACKAGE_NAME>.");
             pw.println();
             Intent.printIntentArgsHelp(pw, "");
         }
diff --git a/services/core/java/com/android/server/am/EventLogTags.logtags b/services/core/java/com/android/server/am/EventLogTags.logtags
index 421b755..cf0de06 100644
--- a/services/core/java/com/android/server/am/EventLogTags.logtags
+++ b/services/core/java/com/android/server/am/EventLogTags.logtags
@@ -146,4 +146,7 @@
 30065 am_on_top_resumed_lost_called (Token|1|5),(Component Name|3),(Reason|3)
 
 # An activity been add into stopping list
-30066 am_add_to_stopping (User|1|5),(Token|1|5),(Component Name|3),(Reason|3)
\ No newline at end of file
+30066 am_add_to_stopping (User|1|5),(Token|1|5),(Component Name|3),(Reason|3)
+
+# Keyguard status changed
++30067 am_set_keyguard_shown (keyguardShowing|1),(aodShowing|1),(keyguardGoingAway|1),(Reason|3)
\ No newline at end of file
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index ffbc6b3..5465309 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -1526,6 +1526,9 @@
             if ("1".equals(SystemProperties.get("debug.assert"))) {
                 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
             }
+            if ("1".equals(SystemProperties.get("debug.ignoreappsignalhandler"))) {
+                runtimeFlags |= Zygote.DEBUG_IGNORE_APP_SIGNAL_HANDLER;
+            }
             if (mService.mNativeDebuggingApp != null
                     && mService.mNativeDebuggingApp.equals(app.processName)) {
                 // Enable all debug flags required by the native debugger.
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 4d09c3b..cb6cf74 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -125,6 +125,8 @@
     /*package*/ void onAudioServerDied() {
         // Restore forced usage for communications and record
         synchronized (mDeviceStateLock) {
+            AudioSystem.setParameters(
+                    "BT_SCO=" + (mForcedUseForComm == AudioSystem.FORCE_BT_SCO ? "on" : "off"));
             onSetForceUse(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, "onAudioServerDied");
             onSetForceUse(AudioSystem.FOR_RECORD, mForcedUseForComm, "onAudioServerDied");
         }
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index df6f73b..bd3cd54 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -521,8 +521,8 @@
             List<EnabledOnKeyguardCallback> callbacks = mEnabledOnKeyguardCallbacks;
             for (int i = 0; i < callbacks.size(); i++) {
                 callbacks.get(i).notify(BiometricSourceType.FACE,
-                        mFaceEnabledOnKeyguard.getOrDefault(userId,
-                                DEFAULT_KEYGUARD_ENABLED));
+                        mFaceEnabledOnKeyguard.getOrDefault(userId, DEFAULT_KEYGUARD_ENABLED),
+                        userId);
             }
         }
     }
@@ -540,9 +540,9 @@
             }
         }
 
-        void notify(BiometricSourceType sourceType, boolean enabled) {
+        void notify(BiometricSourceType sourceType, boolean enabled, int userId) {
             try {
-                mCallback.onChanged(sourceType, enabled);
+                mCallback.onChanged(sourceType, enabled, userId);
             } catch (DeadObjectException e) {
                 Slog.w(TAG, "Death while invoking notify", e);
                 mEnabledOnKeyguardCallbacks.remove(this);
@@ -796,7 +796,8 @@
             mEnabledOnKeyguardCallbacks.add(new EnabledOnKeyguardCallback(callback));
             try {
                 callback.onChanged(BiometricSourceType.FACE,
-                        mSettingObserver.getFaceEnabledOnKeyguard());
+                        mSettingObserver.getFaceEnabledOnKeyguard(),
+                        UserHandle.getCallingUserId());
             } catch (RemoteException e) {
                 Slog.w(TAG, "Remote exception", e);
             }
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
index f08423e..20eb618 100644
--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -665,8 +665,12 @@
         mMetricsLogger.count(getConstants().tagHalDied(), 1);
         mHALDeathCount++;
         mCurrentUserId = UserHandle.USER_NULL;
-        handleError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
-                0 /*vendorCode */);
+
+        // All client lifecycle must be managed on the handler.
+        mHandler.post(() -> {
+            handleError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
+                    0 /*vendorCode */);
+        });
 
         StatsLog.write(StatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED, statsModality(),
                 BiometricsProtoEnums.ISSUE_HAL_DEATH);
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index fea5d83..bcf1d80 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -128,20 +128,24 @@
      * <p>Note, package overrides are not persistent and will be lost on system or runtime restart.
      *
      * @param changeId The ID of the change to be overridden. Note, this call will succeed even if
-     *                 this change is not known; it will only have any affect if any code in the
+     *                 this change is not known; it will only have any effect if any code in the
      *                 platform is gated on the ID given.
      * @param packageName The app package name to override the change for.
      * @param enabled If the change should be enabled or disabled.
+     * @return {@code true} if the change existed before adding the override.
      */
-    public void addOverride(long changeId, String packageName, boolean enabled) {
+    public boolean addOverride(long changeId, String packageName, boolean enabled) {
+        boolean alreadyKnown = true;
         synchronized (mChanges) {
             CompatChange c = mChanges.get(changeId);
             if (c == null) {
+                alreadyKnown = false;
                 c = new CompatChange(changeId);
                 addChange(c);
             }
             c.addPackageOverride(packageName, enabled);
         }
+        return alreadyKnown;
     }
 
     /**
@@ -151,14 +155,18 @@
      *
      * @param changeId The ID of the change that was overridden.
      * @param packageName The app package name that was overridden.
+     * @return {@code true} if an override existed;
      */
-    public void removeOverride(long changeId, String packageName) {
+    public boolean removeOverride(long changeId, String packageName) {
+        boolean overrideExists = false;
         synchronized (mChanges) {
             CompatChange c = mChanges.get(changeId);
             if (c != null) {
+                overrideExists = true;
                 c.removePackageOverride(packageName);
             }
         }
+        return overrideExists;
     }
 
 }
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 7824a0a..3e1817b 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -40,7 +40,6 @@
 import android.content.SyncRequest;
 import android.content.SyncStatusInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
 import android.content.pm.ProviderInfo;
 import android.database.IContentObserver;
 import android.database.sqlite.SQLiteException;
@@ -71,6 +70,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -280,15 +280,11 @@
 
         // Let the package manager query for the sync adapters for a given authority
         // as we grant default permissions to sync adapters for specific authorities.
-        PackageManagerInternal packageManagerInternal = LocalServices.getService(
-                PackageManagerInternal.class);
-        packageManagerInternal.setSyncAdapterPackagesprovider(
-                new PackageManagerInternal.SyncAdapterPackagesProvider() {
-                    @Override
-                    public String[] getPackages(String authority, int userId) {
-                        return getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
-                    }
-                });
+        final PermissionManagerServiceInternal permissionManagerInternal =
+                LocalServices.getService(PermissionManagerServiceInternal.class);
+        permissionManagerInternal.setSyncAdapterPackagesProvider((authority, userId) -> {
+            return getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
+        });
 
         final IntentFilter packageFilter = new IntentFilter();
         packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 99341d1..4f33ebb0 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -303,6 +303,8 @@
     private final Spline mMinimumBrightnessSpline;
     private final ColorSpace mWideColorSpace;
 
+    private SensorManager mSensorManager;
+
     public DisplayManagerService(Context context) {
         this(context, new Injector());
     }
@@ -430,7 +432,7 @@
         }
 
         mDisplayModeDirector.setListener(new AllowedDisplayModeObserver());
-        mDisplayModeDirector.start();
+        mDisplayModeDirector.start(mSensorManager);
 
         mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
     }
@@ -2358,6 +2360,7 @@
                 };
                 mDisplayPowerController = new DisplayPowerController(
                         mContext, callbacks, handler, sensorManager, blanker);
+                mSensorManager = sensorManager;
             }
 
             mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION);
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index 14bd2d8..78a48da 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -18,26 +18,41 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.hardware.display.DisplayManager;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.UserHandle;
+import android.os.PowerManager;
+import android.os.SystemClock;
 import android.provider.Settings;
+import android.text.TextUtils;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.DisplayInfo;
 
 import com.android.internal.R;
+import com.android.server.display.whitebalance.DisplayWhiteBalanceFactory;
+import com.android.server.display.whitebalance.AmbientFilter;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -74,7 +89,7 @@
     private final AppRequestObserver mAppRequestObserver;
     private final SettingsObserver mSettingsObserver;
     private final DisplayObserver mDisplayObserver;
-
+    private final BrightnessObserver mBrightnessObserver;
 
     private Listener mListener;
 
@@ -87,6 +102,8 @@
         mAppRequestObserver = new AppRequestObserver();
         mSettingsObserver = new SettingsObserver(context, handler);
         mDisplayObserver = new DisplayObserver(context, handler);
+        mBrightnessObserver = new BrightnessObserver(context, handler);
+
     }
 
     /**
@@ -96,15 +113,17 @@
      * This has to be deferred because the object may be constructed before the rest of the system
      * is ready.
      */
-    public void start() {
+    public void start(SensorManager sensorManager) {
         mSettingsObserver.observe();
         mDisplayObserver.observe();
         mSettingsObserver.observe();
+        mBrightnessObserver.observe(sensorManager);
         synchronized (mLock) {
             // We may have a listener already registered before the call to start, so go ahead and
             // notify them to pick up our newly initialized state.
             notifyAllowedModesChangedLocked();
         }
+
     }
 
     /**
@@ -315,6 +334,7 @@
             }
             mSettingsObserver.dumpLocked(pw);
             mAppRequestObserver.dumpLocked(pw);
+            mBrightnessObserver.dumpLocked(pw);
         }
     }
 
@@ -486,20 +506,15 @@
                 Settings.System.getUriFor(Settings.System.PEAK_REFRESH_RATE);
         private final Uri mLowPowerModeSetting =
                 Settings.Global.getUriFor(Settings.Global.LOW_POWER_MODE);
-        private final Uri mBrightnessSetting =
-                Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);
 
         private final Context mContext;
         private final float mDefaultPeakRefreshRate;
-        private final int mBrightnessThreshold;
 
         SettingsObserver(@NonNull Context context, @NonNull Handler handler) {
             super(handler);
             mContext = context;
             mDefaultPeakRefreshRate = (float) context.getResources().getInteger(
                     R.integer.config_defaultPeakRefreshRate);
-            mBrightnessThreshold = context.getResources().getInteger(
-                    R.integer.config_brightnessThresholdOfPeakRefreshRate);
         }
 
         public void observe() {
@@ -508,14 +523,9 @@
                     UserHandle.USER_SYSTEM);
             cr.registerContentObserver(mLowPowerModeSetting, false /*notifyDescendants*/, this,
                     UserHandle.USER_SYSTEM);
-            if (mBrightnessThreshold >= 0) {
-                cr.registerContentObserver(mBrightnessSetting, false /*notifyDescendants*/, this,
-                    UserHandle.USER_SYSTEM);
-            }
             synchronized (mLock) {
                 updateRefreshRateSettingLocked();
                 updateLowPowerModeSettingLocked();
-                updateBrightnessSettingLocked();
             }
         }
 
@@ -526,8 +536,6 @@
                     updateRefreshRateSettingLocked();
                 } else if (mLowPowerModeSetting.equals(uri)) {
                     updateLowPowerModeSettingLocked();
-                } else if (mBrightnessThreshold >=0 && mBrightnessSetting.equals(uri)) {
-                    updateBrightnessSettingLocked();
                 }
             }
         }
@@ -542,6 +550,7 @@
                 vote = null;
             }
             updateVoteLocked(Vote.PRIORITY_LOW_POWER_MODE, vote);
+            mBrightnessObserver.onLowPowerModeEnabled(inLowPowerMode);
         }
 
         private void updateRefreshRateSettingLocked() {
@@ -549,23 +558,7 @@
                     Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate);
             Vote vote = Vote.forRefreshRates(0f, peakRefreshRate);
             updateVoteLocked(Vote.PRIORITY_USER_SETTING_REFRESH_RATE, vote);
-        }
-
-        private void updateBrightnessSettingLocked() {
-            int brightness = Settings.System.getInt(mContext.getContentResolver(),
-                    Settings.System.SCREEN_BRIGHTNESS, -1);
-
-            if (brightness < 0) {
-                return;
-            }
-
-            final Vote vote;
-            if (brightness <= mBrightnessThreshold) {
-                vote = Vote.forRefreshRates(0f, 60f);
-            } else {
-                vote = null;
-            }
-            updateVoteLocked(Vote.PRIORITY_LOW_BRIGHTNESS, vote);
+            mBrightnessObserver.onPeakRefreshRateEnabled(peakRefreshRate > 60f);
         }
 
         public void dumpLocked(PrintWriter pw) {
@@ -715,4 +708,240 @@
             }
         }
     }
+
+    /**
+     * This class manages brightness threshold for switching between 60 hz and higher refresh rate.
+     * See more information at the definition of
+     * {@link R.array#config_brightnessThresholdsOfPeakRefreshRate} and
+     * {@link R.array#config_ambientThresholdsOfPeakRefreshRate}.
+     */
+    private class BrightnessObserver extends ContentObserver {
+        private final Uri mDisplayBrightnessSetting =
+                Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);
+
+        private final static int LIGHT_SENSOR_RATE_MS = 250;
+        private final int[] mDisplayBrightnessThresholds;
+        private final int[] mAmbientBrightnessThresholds;
+        // valid threshold if any item from the array >= 0
+        private boolean mShouldObserveDisplayChange;
+        private boolean mShouldObserveAmbientChange;
+
+        private SensorManager mSensorManager;
+        private Sensor mLightSensor;
+        // Take it as low brightness before valid sensor data comes
+        private float mAmbientLux = -1.0f;
+        private AmbientFilter mAmbientFilter;
+
+        private final Context mContext;
+        private ScreenStateReceiver mScreenStateReceiver;
+
+        // Enable light sensor only when screen is on, peak refresh rate enabled and low power mode
+        // off. After initialization, these states will be updated from the same handler thread.
+        private boolean mScreenOn = false;
+        private boolean mPeakRefreshRateEnabled = false;
+        private boolean mLowPowerModeEnabled = false;
+
+        BrightnessObserver(Context context, Handler handler) {
+            super(handler);
+            mContext = context;
+            mDisplayBrightnessThresholds = context.getResources().getIntArray(
+                    R.array.config_brightnessThresholdsOfPeakRefreshRate);
+            mAmbientBrightnessThresholds = context.getResources().getIntArray(
+                    R.array.config_ambientThresholdsOfPeakRefreshRate);
+            if (mDisplayBrightnessThresholds.length != mAmbientBrightnessThresholds.length) {
+                throw new RuntimeException("display brightness threshold array and ambient "
+                        + "brightness threshold array have different length");
+            }
+
+            mShouldObserveDisplayChange = checkShouldObserve(mDisplayBrightnessThresholds);
+            mShouldObserveAmbientChange = checkShouldObserve(mAmbientBrightnessThresholds);
+        }
+
+        public void observe(SensorManager sensorManager) {
+            if (mShouldObserveDisplayChange) {
+                final ContentResolver cr = mContext.getContentResolver();
+                cr.registerContentObserver(mDisplayBrightnessSetting,
+                        false /*notifyDescendants*/, this, UserHandle.USER_SYSTEM);
+            }
+
+            if (mShouldObserveAmbientChange) {
+                Resources resources = mContext.getResources();
+                String lightSensorType = resources.getString(
+                        com.android.internal.R.string.config_displayLightSensorType);
+
+                Sensor lightSensor = null;
+                if (!TextUtils.isEmpty(lightSensorType)) {
+                    List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
+                    for (int i = 0; i < sensors.size(); i++) {
+                        Sensor sensor = sensors.get(i);
+                        if (lightSensorType.equals(sensor.getStringType())) {
+                            lightSensor = sensor;
+                            break;
+                        }
+                    }
+                }
+
+                if (lightSensor == null) {
+                    lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
+                }
+
+                if (lightSensor != null) {
+                    final Resources res = mContext.getResources();
+
+                    mAmbientFilter = DisplayWhiteBalanceFactory.createBrightnessFilter(res);
+                    mSensorManager = sensorManager;
+                    mLightSensor = lightSensor;
+
+                    // Intent.ACTION_SCREEN_ON is not sticky. Check current screen status.
+                    if (mContext.getSystemService(PowerManager.class).isInteractive()) {
+                        onScreenOn(true);
+                    }
+                    mScreenStateReceiver = new ScreenStateReceiver(mContext);
+                }
+            }
+
+            if (mShouldObserveDisplayChange || mShouldObserveAmbientChange) {
+                synchronized (mLock) {
+                    onBrightnessChangedLocked();
+                }
+            }
+        }
+
+        public void onPeakRefreshRateEnabled(boolean b) {
+            if (mShouldObserveAmbientChange && mPeakRefreshRateEnabled != b) {
+                mPeakRefreshRateEnabled = b;
+                updateSensorStatus();
+            }
+        }
+
+        public void onLowPowerModeEnabled(boolean b) {
+            if (mShouldObserveAmbientChange && mLowPowerModeEnabled != b) {
+                mLowPowerModeEnabled = b;
+                updateSensorStatus();
+            }
+        }
+
+        public void dumpLocked(PrintWriter pw) {
+            pw.println("  BrightnessObserver");
+
+            for (int d: mDisplayBrightnessThresholds) {
+                pw.println("    mDisplayBrightnessThreshold: " + d);
+            }
+
+            for (int d: mAmbientBrightnessThresholds) {
+                pw.println("    mAmbientBrightnessThreshold: " + d);
+            }
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri, int userId) {
+            synchronized (mLock) {
+                onBrightnessChangedLocked();
+            }
+        }
+
+        /**
+         * Checks to see if at least one value is positive, in which case it is necessary to listen
+         * to value changes.
+         */
+        private boolean checkShouldObserve(int[] a) {
+            for (int d: a) {
+                if (d >= 0) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        private void onBrightnessChangedLocked() {
+            int brightness = Settings.System.getInt(mContext.getContentResolver(),
+                    Settings.System.SCREEN_BRIGHTNESS, -1);
+
+            Vote vote = null;
+            for (int i = 0; i < mDisplayBrightnessThresholds.length; i++) {
+                int disp = mDisplayBrightnessThresholds[i];
+                int ambi = mAmbientBrightnessThresholds[i];
+
+                if (disp >= 0 && ambi >= 0) {
+                    if (brightness <= disp && mAmbientLux <= ambi) {
+                        vote = Vote.forRefreshRates(0f, 60f);
+                    }
+                } else if (disp >= 0) {
+                    if (brightness <= disp) {
+                        vote = Vote.forRefreshRates(0f, 60f);
+                    }
+                } else if (ambi >= 0) {
+                    if (mAmbientLux <= ambi) {
+                        vote = Vote.forRefreshRates(0f, 60f);
+                    }
+                }
+
+                if (vote != null) {
+                    break;
+                }
+            }
+
+            if (DEBUG) {
+                Slog.d(TAG, "Display brightness " + brightness + ", ambient lux " +  mAmbientLux +
+                        (vote != null ? " 60hz only" : " no refresh rate limit"));
+            }
+            updateVoteLocked(Vote.PRIORITY_LOW_BRIGHTNESS, vote);
+        }
+
+        private void onScreenOn(boolean on) {
+            // Not check mShouldObserveAmbientChange because Screen status receiver is registered
+            // only when it is true.
+            if (mScreenOn != on) {
+                mScreenOn = on;
+                updateSensorStatus();
+            }
+        }
+
+        private void updateSensorStatus() {
+            if (mSensorManager == null || mLightSensorListener == null) {
+                return;
+            }
+
+            if (mScreenOn && !mLowPowerModeEnabled && mPeakRefreshRateEnabled) {
+                mSensorManager.registerListener(mLightSensorListener,
+                        mLightSensor, LIGHT_SENSOR_RATE_MS * 1000, mHandler);
+            } else {
+                mSensorManager.unregisterListener(mLightSensorListener);
+            }
+        }
+
+        private final SensorEventListener mLightSensorListener = new SensorEventListener() {
+            @Override
+            public void onSensorChanged(SensorEvent event) {
+                long now = SystemClock.uptimeMillis();
+                mAmbientFilter.addValue(now, event.values[0]);
+                mAmbientLux = mAmbientFilter.getEstimate(now);
+
+                synchronized (mLock) {
+                    onBrightnessChangedLocked();
+                }
+            }
+
+            @Override
+            public void onAccuracyChanged(Sensor sensor, int accuracy) {
+                // Not used.
+            }
+        };
+
+        private final class ScreenStateReceiver extends BroadcastReceiver {
+            public ScreenStateReceiver(Context context) {
+                IntentFilter filter = new IntentFilter();
+                filter.addAction(Intent.ACTION_SCREEN_OFF);
+                filter.addAction(Intent.ACTION_SCREEN_ON);
+                filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+                context.registerReceiver(this, filter, null, mHandler);
+            }
+
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                onScreenOn(Intent.ACTION_SCREEN_ON.equals(intent.getAction()));
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java
index 2e5aafe..7fb5b19 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -63,6 +63,8 @@
 import android.provider.Settings.System;
 import android.util.MathUtils;
 import android.util.Slog;
+import android.util.SparseIntArray;
+import android.view.Display;
 import android.view.SurfaceControl;
 import android.view.accessibility.AccessibilityManager;
 import android.view.animation.AnimationUtils;
@@ -171,6 +173,11 @@
 
     private NightDisplayAutoMode mNightDisplayAutoMode;
 
+    /**
+     * Map of color modes -> display composition colorspace
+     */
+    private SparseIntArray mColorModeCompositionColorSpaces = null;
+
     public ColorDisplayService(Context context) {
         super(context);
         mHandler = new TintHandler(DisplayThread.get().getLooper());
@@ -267,6 +274,30 @@
         return Secure.getIntForUser(cr, Secure.USER_SETUP_COMPLETE, 0, userHandle) == 1;
     }
 
+    private void setUpDisplayCompositionColorSpaces(Resources res) {
+        mColorModeCompositionColorSpaces = null;
+
+        final int[] colorModes = res.getIntArray(R.array.config_displayCompositionColorModes);
+        if (colorModes == null) {
+            return;
+        }
+
+        final int[] compSpaces = res.getIntArray(R.array.config_displayCompositionColorSpaces);
+        if (compSpaces == null) {
+            return;
+        }
+
+        if (colorModes.length != compSpaces.length) {
+            Slog.e(TAG, "Number of composition color spaces doesn't match specified color modes");
+            return;
+        }
+
+        mColorModeCompositionColorSpaces = new SparseIntArray(colorModes.length);
+        for (int i = 0; i < colorModes.length; i++) {
+            mColorModeCompositionColorSpaces.put(colorModes[i], compSpaces[i]);
+        }
+    }
+
     private void setUp() {
         Slog.d(TAG, "setUp: currentUser=" + mCurrentUser);
 
@@ -359,6 +390,8 @@
         onAccessibilityInversionChanged();
         onAccessibilityDaltonizerChanged();
 
+        setUpDisplayCompositionColorSpaces(getContext().getResources());
+
         // Set the color mode, if valid, and immediately apply the updated tint matrix based on the
         // existing activated state. This ensures consistency of tint across the color mode change.
         onDisplayColorModeChanged(getColorModeInternal());
@@ -450,6 +483,14 @@
         }
     }
 
+    private int getCompositionColorSpace(int mode) {
+        if (mColorModeCompositionColorSpaces == null) {
+            return Display.COLOR_MODE_INVALID;
+        }
+
+        return mColorModeCompositionColorSpaces.get(mode, Display.COLOR_MODE_INVALID);
+    }
+
     private void onDisplayColorModeChanged(int mode) {
         if (mode == NOT_SET) {
             return;
@@ -470,7 +511,8 @@
         // DisplayTransformManager.needsLinearColorMatrix(), therefore it is dependent
         // on the state of DisplayTransformManager.
         final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
-        dtm.setColorMode(mode, mNightDisplayTintController.getMatrix());
+        dtm.setColorMode(mode, mNightDisplayTintController.getMatrix(),
+                getCompositionColorSpace(mode));
 
         if (mDisplayWhiteBalanceTintController.isAvailable(getContext())) {
             updateDisplayWhiteBalanceStatus();
diff --git a/services/core/java/com/android/server/display/color/DisplayTransformManager.java b/services/core/java/com/android/server/display/color/DisplayTransformManager.java
index 5ff45a9..d5706a5 100644
--- a/services/core/java/com/android/server/display/color/DisplayTransformManager.java
+++ b/services/core/java/com/android/server/display/color/DisplayTransformManager.java
@@ -26,6 +26,7 @@
 import android.os.SystemProperties;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.view.Display;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -77,6 +78,8 @@
     @VisibleForTesting
     static final String PERSISTENT_PROPERTY_SATURATION = "persist.sys.sf.color_saturation";
     @VisibleForTesting
+    static final String PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE = "persist.sys.sf.color_mode";
+    @VisibleForTesting
     static final String PERSISTENT_PROPERTY_DISPLAY_COLOR = "persist.sys.sf.native_mode";
 
     private static final float COLOR_SATURATION_NATURAL = 1.0f;
@@ -251,23 +254,24 @@
     /**
      * Sets color mode and updates night display transform values.
      */
-    public boolean setColorMode(int colorMode, float[] nightDisplayMatrix) {
+    public boolean setColorMode(int colorMode, float[] nightDisplayMatrix,
+            int compositionColorMode) {
         if (colorMode == ColorDisplayManager.COLOR_MODE_NATURAL) {
             applySaturation(COLOR_SATURATION_NATURAL);
-            setDisplayColor(DISPLAY_COLOR_MANAGED);
+            setDisplayColor(DISPLAY_COLOR_MANAGED, compositionColorMode);
         } else if (colorMode == ColorDisplayManager.COLOR_MODE_BOOSTED) {
             applySaturation(COLOR_SATURATION_BOOSTED);
-            setDisplayColor(DISPLAY_COLOR_MANAGED);
+            setDisplayColor(DISPLAY_COLOR_MANAGED, compositionColorMode);
         } else if (colorMode == ColorDisplayManager.COLOR_MODE_SATURATED) {
             applySaturation(COLOR_SATURATION_NATURAL);
-            setDisplayColor(DISPLAY_COLOR_UNMANAGED);
+            setDisplayColor(DISPLAY_COLOR_UNMANAGED, compositionColorMode);
         } else if (colorMode == ColorDisplayManager.COLOR_MODE_AUTOMATIC) {
             applySaturation(COLOR_SATURATION_NATURAL);
-            setDisplayColor(DISPLAY_COLOR_ENHANCED);
+            setDisplayColor(DISPLAY_COLOR_ENHANCED, compositionColorMode);
         } else if (colorMode >= ColorDisplayManager.VENDOR_COLOR_MODE_RANGE_MIN
                 && colorMode <= ColorDisplayManager.VENDOR_COLOR_MODE_RANGE_MAX) {
             applySaturation(COLOR_SATURATION_NATURAL);
-            setDisplayColor(colorMode);
+            setDisplayColor(colorMode, compositionColorMode);
         }
 
         setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, nightDisplayMatrix);
@@ -323,13 +327,21 @@
     /**
      * Toggles native mode on/off in SurfaceFlinger.
      */
-    private void setDisplayColor(int color) {
+    private void setDisplayColor(int color, int compositionColorMode) {
         SystemProperties.set(PERSISTENT_PROPERTY_DISPLAY_COLOR, Integer.toString(color));
+        if (compositionColorMode != Display.COLOR_MODE_INVALID) {
+            SystemProperties.set(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE,
+                Integer.toString(compositionColorMode));
+        }
+
         final IBinder flinger = ServiceManager.getService(SURFACE_FLINGER);
         if (flinger != null) {
             final Parcel data = Parcel.obtain();
             data.writeInterfaceToken("android.ui.ISurfaceComposer");
             data.writeInt(color);
+            if (compositionColorMode != Display.COLOR_MODE_INVALID) {
+                data.writeInt(compositionColorMode);
+            }
             try {
                 flinger.transact(SURFACE_FLINGER_TRANSACTION_DISPLAY_COLOR, data, null, 0);
             } catch (RemoteException ex) {
diff --git a/services/core/java/com/android/server/display/whitebalance/AmbientFilter.java b/services/core/java/com/android/server/display/whitebalance/AmbientFilter.java
index 123cd73..3580897 100644
--- a/services/core/java/com/android/server/display/whitebalance/AmbientFilter.java
+++ b/services/core/java/com/android/server/display/whitebalance/AmbientFilter.java
@@ -36,7 +36,7 @@
  * - {@link WeightedMovingAverageAmbientFilter}
  *   A weighted average prioritising recent changes.
  */
-abstract class AmbientFilter {
+abstract public class AmbientFilter {
 
     protected static final boolean DEBUG = false; // Enable for verbose logs.
 
@@ -156,8 +156,7 @@
     /**
      * A weighted average prioritising recent changes.
      */
-    @VisibleForTesting
-    public static class WeightedMovingAverageAmbientFilter extends AmbientFilter {
+    static class WeightedMovingAverageAmbientFilter extends AmbientFilter {
 
         // How long the latest ambient value change is predicted to last.
         private static final int PREDICTION_TIME = 100; // Milliseconds
diff --git a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java
index 4df7d6b..bf0a1d1 100644
--- a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java
+++ b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java
@@ -115,8 +115,7 @@
      * Creates a BrightnessFilter which functions as a weighted moving average buffer for recent
      * brightness values.
      */
-    @VisibleForTesting
-    static AmbientFilter createBrightnessFilter(Resources resources) {
+    public static AmbientFilter createBrightnessFilter(Resources resources) {
         final int horizon = resources.getInteger(
                 com.android.internal.R.integer.config_displayWhiteBalanceBrightnessFilterHorizon);
         final float intercept = getFloat(resources,
@@ -129,7 +128,6 @@
                 + "expected config_displayWhiteBalanceBrightnessFilterIntercept");
     }
 
-
     /**
      * Creates an ambient color sensor instance to redirect sensor data to callbacks.
      */
diff --git a/services/core/java/com/android/server/job/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java
index ababad9..4c11947 100644
--- a/services/core/java/com/android/server/job/controllers/TimeController.java
+++ b/services/core/java/com/android/server/job/controllers/TimeController.java
@@ -18,20 +18,13 @@
 
 import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
 
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.AlarmManager;
 import android.app.AlarmManager.OnAlarmListener;
-import android.content.ContentResolver;
 import android.content.Context;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
 import android.os.Process;
 import android.os.UserHandle;
 import android.os.WorkSource;
-import android.provider.Settings;
-import android.util.KeyValueListParser;
 import android.util.Log;
 import android.util.Slog;
 import android.util.TimeUtils;
@@ -39,7 +32,6 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.job.ConstantsProto;
 import com.android.server.job.JobSchedulerService;
 import com.android.server.job.StateControllerProto;
 
@@ -63,9 +55,6 @@
     /** Delay alarm tag for logging purposes */
     private final String DELAY_TAG = "*job.delay*";
 
-    private final Handler mHandler;
-    private final TcConstants mTcConstants;
-
     private long mNextJobExpiredElapsedMillis;
     private long mNextDelayExpiredElapsedMillis;
 
@@ -81,14 +70,6 @@
         mNextJobExpiredElapsedMillis = Long.MAX_VALUE;
         mNextDelayExpiredElapsedMillis = Long.MAX_VALUE;
         mChainedAttributionEnabled = mService.isChainedAttributionEnabled();
-
-        mHandler = new Handler(mContext.getMainLooper());
-        mTcConstants = new TcConstants(mHandler);
-    }
-
-    @Override
-    public void onSystemServicesReady() {
-        mTcConstants.start(mContext.getContentResolver());
     }
 
     /**
@@ -133,20 +114,16 @@
 
             job.setTrackingController(JobStatus.TRACKING_TIME);
             WorkSource ws = deriveWorkSource(job.getSourceUid(), job.getSourcePackageName());
-            final long deadlineExpiredElapsed =
-                    job.hasDeadlineConstraint() ? job.getLatestRunTimeElapsed() : Long.MAX_VALUE;
-            final long delayExpiredElapsed =
-                    job.hasTimingDelayConstraint() ? job.getEarliestRunTime() : Long.MAX_VALUE;
-            if (mTcConstants.SKIP_NOT_READY_JOBS) {
-                if (wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_TIMING_DELAY)) {
-                    maybeUpdateDelayAlarmLocked(delayExpiredElapsed, ws);
-                }
-                if (wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_DEADLINE)) {
-                    maybeUpdateDeadlineAlarmLocked(deadlineExpiredElapsed, ws);
-                }
-            } else {
-                maybeUpdateDelayAlarmLocked(delayExpiredElapsed, ws);
-                maybeUpdateDeadlineAlarmLocked(deadlineExpiredElapsed, ws);
+
+            // Only update alarms if the job would be ready with the relevant timing constraint
+            // satisfied.
+            if (job.hasTimingDelayConstraint()
+                    && wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_TIMING_DELAY)) {
+                maybeUpdateDelayAlarmLocked(job.getEarliestRunTime(), ws);
+            }
+            if (job.hasDeadlineConstraint()
+                    && wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_DEADLINE)) {
+                maybeUpdateDeadlineAlarmLocked(job.getLatestRunTimeElapsed(), ws);
             }
         }
     }
@@ -168,10 +145,6 @@
 
     @Override
     public void evaluateStateLocked(JobStatus job) {
-        if (!mTcConstants.SKIP_NOT_READY_JOBS) {
-            return;
-        }
-
         final long nowElapsedMillis = sElapsedRealtimeClock.millis();
 
         // Check deadline constraint first because if it's satisfied, we avoid a little bit of
@@ -261,9 +234,7 @@
                     }
                     it.remove();
                 } else {  // Sorted by expiry time, so take the next one and stop.
-                    if (mTcConstants.SKIP_NOT_READY_JOBS
-                            && !wouldBeReadyWithConstraintLocked(
-                            job, JobStatus.CONSTRAINT_DEADLINE)) {
+                    if (!wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_DEADLINE)) {
                         if (DEBUG) {
                             Slog.i(TAG,
                                     "Skipping " + job + " because deadline won't make it ready.");
@@ -321,9 +292,7 @@
                         ready = true;
                     }
                 } else {
-                    if (mTcConstants.SKIP_NOT_READY_JOBS
-                            && !wouldBeReadyWithConstraintLocked(
-                            job, JobStatus.CONSTRAINT_TIMING_DELAY)) {
+                    if (!wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_TIMING_DELAY)) {
                         if (DEBUG) {
                             Slog.i(TAG,
                                     "Skipping " + job + " because delay won't make it ready.");
@@ -458,81 +427,6 @@
         checkExpiredDelaysAndResetAlarm();
     }
 
-    @VisibleForTesting
-    class TcConstants extends ContentObserver {
-        private ContentResolver mResolver;
-        private final KeyValueListParser mParser = new KeyValueListParser(',');
-
-        private static final String KEY_SKIP_NOT_READY_JOBS = "skip_not_ready_jobs";
-
-        private static final boolean DEFAULT_SKIP_NOT_READY_JOBS = true;
-
-        /**
-         * Whether or not TimeController should skip setting wakeup alarms for jobs that aren't
-         * ready now.
-         */
-        public boolean SKIP_NOT_READY_JOBS = DEFAULT_SKIP_NOT_READY_JOBS;
-
-        /**
-         * Creates a content observer.
-         *
-         * @param handler The handler to run {@link #onChange} on, or null if none.
-         */
-        TcConstants(Handler handler) {
-            super(handler);
-        }
-
-        private void start(ContentResolver resolver) {
-            mResolver = resolver;
-            mResolver.registerContentObserver(Settings.Global.getUriFor(
-                    Settings.Global.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS), false, this);
-            onChange(true, null);
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            final String constants = Settings.Global.getString(
-                    mResolver, Settings.Global.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS);
-
-            try {
-                mParser.setString(constants);
-            } catch (Exception e) {
-                // Failed to parse the settings string, log this and move on with defaults.
-                Slog.e(TAG, "Bad jobscheduler time controller settings", e);
-            }
-
-            final boolean oldVal = SKIP_NOT_READY_JOBS;
-            SKIP_NOT_READY_JOBS = mParser.getBoolean(
-                    KEY_SKIP_NOT_READY_JOBS, DEFAULT_SKIP_NOT_READY_JOBS);
-
-            if (oldVal != SKIP_NOT_READY_JOBS) {
-                synchronized (mLock) {
-                    recheckAlarmsLocked();
-                }
-            }
-        }
-
-        private void dump(IndentingPrintWriter pw) {
-            pw.println();
-            pw.println("TimeController:");
-            pw.increaseIndent();
-            pw.printPair(KEY_SKIP_NOT_READY_JOBS, SKIP_NOT_READY_JOBS).println();
-            pw.decreaseIndent();
-        }
-
-        private void dump(ProtoOutputStream proto) {
-            final long tcToken = proto.start(ConstantsProto.TIME_CONTROLLER);
-            proto.write(ConstantsProto.TimeController.SKIP_NOT_READY_JOBS, SKIP_NOT_READY_JOBS);
-            proto.end(tcToken);
-        }
-    }
-
-    @VisibleForTesting
-    @NonNull
-    TcConstants getTcConstants() {
-        return mTcConstants;
-    }
-
     @Override
     public void dumpControllerStateLocked(IndentingPrintWriter pw,
             Predicate<JobStatus> predicate) {
@@ -607,14 +501,4 @@
         proto.end(mToken);
         proto.end(token);
     }
-
-    @Override
-    public void dumpConstants(IndentingPrintWriter pw) {
-        mTcConstants.dump(pw);
-    }
-
-    @Override
-    public void dumpConstants(ProtoOutputStream proto) {
-        mTcConstants.dump(proto);
-    }
 }
diff --git a/services/core/java/com/android/server/locksettings/PasswordSlotManager.java b/services/core/java/com/android/server/locksettings/PasswordSlotManager.java
index 5cbd237..4ef63c0 100644
--- a/services/core/java/com/android/server/locksettings/PasswordSlotManager.java
+++ b/services/core/java/com/android/server/locksettings/PasswordSlotManager.java
@@ -122,7 +122,7 @@
      */
     public void markSlotDeleted(int slot) throws RuntimeException {
         ensureSlotMapLoaded();
-        if (mSlotMap.containsKey(slot) && mSlotMap.get(slot) != getMode()) {
+        if (mSlotMap.containsKey(slot) && !mSlotMap.get(slot).equals(getMode())) {
             throw new RuntimeException("password slot " + slot + " cannot be deleted");
         }
         mSlotMap.remove(slot);
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 01936c9..12137fe 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -32,16 +32,15 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
-import android.os.Message;
 import android.os.RemoteException;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
-import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.function.pooled.PooledLambda;
 
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
@@ -204,13 +203,15 @@
 
                 UserRecord oldUser = mUserRecords.get(oldUserId);
                 if (oldUser != null) {
-                    oldUser.mHandler.sendEmptyMessage(MediaRouterService.UserHandler.MSG_STOP);
+                    oldUser.mHandler.sendMessage(
+                            obtainMessage(UserHandler::stop, oldUser.mHandler));
                     disposeUserIfNeededLocked(oldUser); // since no longer current user
                 }
 
                 UserRecord newUser = mUserRecords.get(userId);
                 if (newUser != null) {
-                    newUser.mHandler.sendEmptyMessage(MediaRouterService.UserHandler.MSG_START);
+                    newUser.mHandler.sendMessage(
+                            obtainMessage(UserHandler::start, newUser.mHandler));
                 }
             }
         }
@@ -296,8 +297,9 @@
         if (clientRecord != null) {
             clientRecord.mControlCategories = categories;
 
-            clientRecord.mUserRecord.mHandler.obtainMessage(
-                    UserHandler.MSG_UPDATE_CLIENT_USAGE, clientRecord).sendToTarget();
+            clientRecord.mUserRecord.mHandler.sendMessage(
+                    obtainMessage(UserHandler::updateClientUsage,
+                            clientRecord.mUserRecord.mHandler, clientRecord));
         }
     }
 
@@ -307,9 +309,9 @@
         ClientRecord clientRecord = mAllClientRecords.get(binder);
 
         if (clientRecord != null) {
-            Pair<MediaRoute2Info, Intent> obj = new Pair<>(route, request);
-            clientRecord.mUserRecord.mHandler.obtainMessage(
-                    UserHandler.MSG_SEND_CONTROL_REQUEST, obj).sendToTarget();
+            clientRecord.mUserRecord.mHandler.sendMessage(
+                    obtainMessage(UserHandler::sendControlRequest,
+                            clientRecord.mUserRecord.mHandler, route, request));
         }
     }
 
@@ -346,8 +348,9 @@
             final int count = userRecord.mClientRecords.size();
             for (int i = 0; i < count; i++) {
                 ClientRecord clientRecord = userRecord.mClientRecords.get(i);
-                clientRecord.mUserRecord.mHandler.obtainMessage(
-                        UserHandler.MSG_UPDATE_CLIENT_USAGE, clientRecord).sendToTarget();
+                clientRecord.mUserRecord.mHandler.sendMessage(
+                        obtainMessage(UserHandler::updateClientUsage,
+                            clientRecord.mUserRecord.mHandler, clientRecord));
             }
         }
     }
@@ -381,7 +384,8 @@
             Slog.d(TAG, userRecord + ": Initialized");
         }
         if (userRecord.mUserId == mCurrentUserId) {
-            userRecord.mHandler.sendEmptyMessage(UserHandler.MSG_START);
+            userRecord.mHandler.sendMessage(
+                    obtainMessage(UserHandler::start, userRecord.mHandler));
         }
     }
 
@@ -497,13 +501,6 @@
             MediaRoute2ProviderWatcher.Callback,
             MediaRoute2ProviderProxy.Callback {
 
-        //TODO: Use PooledLambda instead.
-        static final int MSG_START = 1;
-        static final int MSG_STOP = 2;
-
-        static final int MSG_UPDATE_CLIENT_USAGE = 11;
-        static final int MSG_SEND_CONTROL_REQUEST = 12;
-
         private final WeakReference<MediaRouter2ServiceImpl> mServiceRef;
         private final UserRecord mUserRecord;
         private final MediaRoute2ProviderWatcher mWatcher;
@@ -524,28 +521,6 @@
                     this, mUserRecord.mUserId);
         }
 
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_START: {
-                    start();
-                    break;
-                }
-                case MSG_STOP: {
-                    stop();
-                    break;
-                }
-                case MSG_UPDATE_CLIENT_USAGE: {
-                    updateClientUsage((ClientRecord) msg.obj);
-                    break;
-                }
-                case MSG_SEND_CONTROL_REQUEST: {
-                    Pair<MediaRoute2Info, Intent> obj = (Pair<MediaRoute2Info, Intent>) msg.obj;
-                    sendControlRequest(obj.first, obj.second);
-                }
-            }
-        }
-
         private void start() {
             if (!mRunning) {
                 mRunning = true;
@@ -613,7 +588,7 @@
         private void scheduleUpdateManagerState() {
             if (!mManagerStateUpdateScheduled) {
                 mManagerStateUpdateScheduled = true;
-                post(this::updateManagerState);
+                sendMessage(PooledLambda.obtainMessage(UserHandler::updateManagerState, this));
             }
         }
 
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index d3346cd..5530b51 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -403,8 +403,10 @@
     private IConnectivityManager mConnManager;
     private PowerManagerInternal mPowerManagerInternal;
     private IDeviceIdleController mDeviceIdleController;
+
+    /** Current cached value of the current Battery Saver mode's setting for restrict background. */
     @GuardedBy("mUidRulesFirstLock")
-    private PowerSaveState mRestrictBackgroundPowerState;
+    private boolean mRestrictBackgroundLowPowerMode;
 
     // Store the status of restrict background before turning on battery saver.
     // Used to restore mRestrictBackground when battery saver is turned off.
@@ -771,11 +773,9 @@
 
                     // Update the restrictBackground if battery saver is turned on
                     mRestrictBackgroundBeforeBsm = mLoadedRestrictBackground;
-                    mRestrictBackgroundPowerState = mPowerManagerInternal
-                            .getLowPowerState(ServiceType.DATA_SAVER);
-                    final boolean localRestrictBackground =
-                            mRestrictBackgroundPowerState.batterySaverEnabled;
-                    if (localRestrictBackground && !mLoadedRestrictBackground) {
+                    mRestrictBackgroundLowPowerMode = mPowerManagerInternal
+                            .getLowPowerState(ServiceType.DATA_SAVER).batterySaverEnabled;
+                    if (mRestrictBackgroundLowPowerMode && !mLoadedRestrictBackground) {
                         mLoadedRestrictBackground = true;
                     }
                     mPowerManagerInternal.registerLowPowerModeObserver(
@@ -2900,7 +2900,7 @@
             sendRestrictBackgroundChangedMsg();
             mLogger.restrictBackgroundChanged(oldRestrictBackground, mRestrictBackground);
 
-            if (mRestrictBackgroundPowerState.globalBatterySaverEnabled) {
+            if (mRestrictBackgroundLowPowerMode) {
                 mRestrictBackgroundChangedInBsm = true;
             }
             synchronized (mNetworkPoliciesSecondLock) {
@@ -4907,17 +4907,21 @@
     @GuardedBy("mUidRulesFirstLock")
     @VisibleForTesting
     void updateRestrictBackgroundByLowPowerModeUL(final PowerSaveState result) {
-        mRestrictBackgroundPowerState = result;
+        if (mRestrictBackgroundLowPowerMode == result.batterySaverEnabled) {
+            // Nothing changed. Nothing to do.
+            return;
+        }
+        mRestrictBackgroundLowPowerMode = result.batterySaverEnabled;
 
-        boolean restrictBackground = result.batterySaverEnabled;
+        boolean restrictBackground = mRestrictBackgroundLowPowerMode;
         boolean shouldInvokeRestrictBackground;
-        // store the temporary mRestrictBackgroundChangedInBsm and update it at last
+        // store the temporary mRestrictBackgroundChangedInBsm and update it at the end.
         boolean localRestrictBgChangedInBsm = mRestrictBackgroundChangedInBsm;
 
-        if (result.globalBatterySaverEnabled) {
+        if (mRestrictBackgroundLowPowerMode) {
             // Try to turn on restrictBackground if (1) it is off and (2) batter saver need to
             // turn it on.
-            shouldInvokeRestrictBackground = !mRestrictBackground && result.batterySaverEnabled;
+            shouldInvokeRestrictBackground = !mRestrictBackground;
             mRestrictBackgroundBeforeBsm = mRestrictBackground;
             localRestrictBgChangedInBsm = false;
         } else {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 07fd322..d30895e 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -401,7 +401,7 @@
 
     // for enabling and disabling notification pulse behavior
     boolean mScreenOn = true;
-    protected boolean mInCall = false;
+    protected boolean mInCallStateOffHook = false;
     boolean mNotificationPulseEnabled;
 
     private Uri mInCallNotificationUri;
@@ -1299,7 +1299,7 @@
                 mScreenOn = false;
                 updateNotificationPulse();
             } else if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
-                mInCall = TelephonyManager.EXTRA_STATE_OFFHOOK
+                mInCallStateOffHook = TelephonyManager.EXTRA_STATE_OFFHOOK
                         .equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE));
                 updateNotificationPulse();
             } else if (action.equals(Intent.ACTION_USER_STOPPED)) {
@@ -5824,7 +5824,7 @@
                     }
                     if (DBG) Slog.v(TAG, "Interrupting!");
                     if (hasValidSound) {
-                        if (mInCall) {
+                        if (isInCall()) {
                             playInCallNotification();
                             beep = true;
                         } else {
@@ -5838,7 +5838,7 @@
                     final boolean ringerModeSilent =
                             mAudioManager.getRingerModeInternal()
                                     == AudioManager.RINGER_MODE_SILENT;
-                    if (!mInCall && hasValidVibrate && !ringerModeSilent) {
+                    if (!isInCall() && hasValidVibrate && !ringerModeSilent) {
                         buzz = playVibration(record, vibration, hasValidSound);
                         if(buzz) {
                             mVibrateNotificationKey = key;
@@ -5926,7 +5926,7 @@
             return false;
         }
         // not if in call or the screen's on
-        if (mInCall || mScreenOn) {
+        if (isInCall() || mScreenOn) {
             return false;
         }
 
@@ -7027,7 +7027,7 @@
         }
 
         // Don't flash while we are in a call or screen is on
-        if (ledNotification == null || mInCall || mScreenOn) {
+        if (ledNotification == null || isInCall() || mScreenOn) {
             mNotificationLight.turnOff();
         } else {
             NotificationRecord.Light light = ledNotification.getLight();
@@ -7495,6 +7495,18 @@
         }
     }
 
+    private boolean isInCall() {
+        if (mInCallStateOffHook) {
+            return true;
+        }
+        int audioMode = mAudioManager.getMode();
+        if (audioMode == AudioManager.MODE_IN_CALL
+                || audioMode == AudioManager.MODE_IN_COMMUNICATION) {
+            return true;
+        }
+        return false;
+    }
+
     public class NotificationAssistants extends ManagedServices {
         static final String TAG_ENABLED_NOTIFICATION_ASSISTANTS = "enabled_assistants";
 
diff --git a/services/core/java/com/android/server/om/IdmapDaemon.java b/services/core/java/com/android/server/om/IdmapDaemon.java
new file mode 100644
index 0000000..55fbcb4
--- /dev/null
+++ b/services/core/java/com/android/server/om/IdmapDaemon.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.om;
+
+import static android.content.Context.IDMAP_SERVICE;
+
+import static com.android.server.om.OverlayManagerService.DEBUG;
+import static com.android.server.om.OverlayManagerService.TAG;
+
+import android.os.IBinder;
+import android.os.IIdmap2;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.util.Slog;
+
+import com.android.server.IoThread;
+
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * To prevent idmap2d from continuously running, the idmap daemon will terminate after 10
+ * seconds without a transaction.
+ **/
+class IdmapDaemon {
+    // The amount of time in milliseconds to wait after a transaction to the idmap service is made
+    // before stopping the service.
+    private static final int SERVICE_TIMEOUT_MS = 10000;
+
+    // The amount of time in milliseconds to wait when attempting to connect to idmap service.
+    private static final int SERVICE_CONNECT_TIMEOUT_MS = 5000;
+
+    private static final Object IDMAP_TOKEN = new Object();
+    private static final String IDMAP_DAEMON = "idmap2d";
+
+    private static IdmapDaemon sInstance;
+    private volatile IIdmap2 mService;
+    private final AtomicInteger mOpenedCount = new AtomicInteger();
+
+    /**
+     * An {@link AutoCloseable} connection to the idmap service. When the connection is closed or
+     * finalized, the idmap service will be stopped after a period of time unless another connection
+     * to the service is open.
+     **/
+    private class Connection implements AutoCloseable {
+        private boolean mOpened = true;
+
+        private Connection() {
+            synchronized (IDMAP_TOKEN) {
+                mOpenedCount.incrementAndGet();
+            }
+        }
+
+        @Override
+        public void close() {
+            synchronized (IDMAP_TOKEN) {
+                if (!mOpened) {
+                    return;
+                }
+
+                mOpened = false;
+                if (mOpenedCount.decrementAndGet() != 0) {
+                    // Only post the callback to stop the service if the service does not have an
+                    // open connection.
+                    return;
+                }
+
+                IoThread.getHandler().postDelayed(() -> {
+                    synchronized (IDMAP_TOKEN) {
+                        // Only stop the service if the service does not have an open connection.
+                        if (mService == null || mOpenedCount.get() != 0) {
+                            return;
+                        }
+
+                        stopIdmapService();
+                        mService = null;
+                    }
+                }, IDMAP_TOKEN, SERVICE_TIMEOUT_MS);
+            }
+        }
+    }
+
+    static IdmapDaemon getInstance() {
+        if (sInstance == null) {
+            sInstance = new IdmapDaemon();
+        }
+        return sInstance;
+    }
+
+    String createIdmap(String targetPath, String overlayPath, int policies, boolean enforce,
+            int userId) throws Exception {
+        try (Connection connection = connect()) {
+            return mService.createIdmap(targetPath, overlayPath, policies, enforce, userId);
+        }
+    }
+
+    boolean removeIdmap(String overlayPath, int userId) throws Exception {
+        try (Connection connection = connect()) {
+            return mService.removeIdmap(overlayPath, userId);
+        }
+    }
+
+    boolean verifyIdmap(String overlayPath, int policies, boolean enforce, int userId)
+            throws Exception {
+        try (Connection connection = connect()) {
+            return mService.verifyIdmap(overlayPath, policies, enforce, userId);
+        }
+    }
+
+    String getIdmapPath(String overlayPath, int userId) throws Exception {
+        try (Connection connection = connect()) {
+            return mService.getIdmapPath(overlayPath, userId);
+        }
+    }
+
+    static void startIdmapService() {
+        SystemProperties.set("ctl.start", IDMAP_DAEMON);
+    }
+
+    static void stopIdmapService() {
+        SystemProperties.set("ctl.stop", IDMAP_DAEMON);
+    }
+
+    private Connection connect() throws Exception {
+        synchronized (IDMAP_TOKEN) {
+            IoThread.getHandler().removeCallbacksAndMessages(IDMAP_TOKEN);
+            if (mService != null) {
+                // Not enough time has passed to stop the idmap service. Reuse the existing
+                // interface.
+                return new Connection();
+            }
+
+            // Start the idmap service if it is not currently running.
+            startIdmapService();
+
+            // Block until the service is found.
+            FutureTask<IBinder> bindIdmap = new FutureTask<>(() -> {
+                IBinder binder = null;
+                while (binder == null) {
+                    try {
+                        binder = ServiceManager.getService(IDMAP_SERVICE);
+                        Thread.sleep(100);
+                    } catch (Exception e) {
+                        Slog.e(TAG, "service '" + IDMAP_SERVICE + "' not retrieved; "
+                                + e.getMessage());
+                    }
+                }
+                return binder;
+            });
+
+            IBinder binder;
+            try {
+                IoThread.getHandler().postAtFrontOfQueue(bindIdmap);
+                binder = bindIdmap.get(SERVICE_CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+            } catch (Exception rethrow) {
+                Slog.e(TAG, "service '" + IDMAP_SERVICE + "' not found;");
+                throw rethrow;
+            }
+
+            try {
+                binder.linkToDeath(() -> {
+                    Slog.w(TAG, "service '" + IDMAP_SERVICE + "' died");
+                }, 0);
+            } catch (RemoteException rethrow) {
+                Slog.e(TAG, "service '" + IDMAP_SERVICE + "' failed to be bound");
+                throw rethrow;
+            }
+
+            mService = IIdmap2.Stub.asInterface(binder);
+            if (DEBUG) {
+                Slog.d(TAG, "service '" + IDMAP_SERVICE + "' connected");
+            }
+
+            return new Connection();
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java
index b604aa8..288ef0e 100644
--- a/services/core/java/com/android/server/om/IdmapManager.java
+++ b/services/core/java/com/android/server/om/IdmapManager.java
@@ -16,9 +16,6 @@
 
 package com.android.server.om;
 
-import static android.content.Context.IDMAP_SERVICE;
-import static android.text.format.DateUtils.SECOND_IN_MILLIS;
-
 import static com.android.server.om.OverlayManagerService.DEBUG;
 import static com.android.server.om.OverlayManagerService.TAG;
 
@@ -27,15 +24,11 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.os.Build.VERSION_CODES;
-import android.os.IBinder;
 import android.os.IIdmap2;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.util.Slog;
 
-import com.android.internal.os.BackgroundThread;
 import com.android.server.om.OverlayManagerServiceImpl.PackageManagerHelper;
 import com.android.server.pm.Installer;
 
@@ -51,11 +44,6 @@
  */
 class IdmapManager {
     private static final boolean FEATURE_FLAG_IDMAP2 = true;
-
-    private final Installer mInstaller;
-    private final PackageManagerHelper mPackageManager;
-    private IIdmap2 mIdmap2Service;
-
     private static final boolean VENDOR_IS_Q_OR_LATER;
     static {
         final String value = SystemProperties.get("ro.vndk.version", "29");
@@ -70,12 +58,14 @@
         VENDOR_IS_Q_OR_LATER = isQOrLater;
     }
 
+    private final Installer mInstaller;
+    private final PackageManagerHelper mPackageManager;
+    private final IdmapDaemon mIdmapDaemon;
+
     IdmapManager(final Installer installer, final PackageManagerHelper packageManager) {
         mInstaller = installer;
         mPackageManager = packageManager;
-        if (FEATURE_FLAG_IDMAP2) {
-            connectToIdmap2d();
-        }
+        mIdmapDaemon = IdmapDaemon.getInstance();
     }
 
     boolean createIdmap(@NonNull final PackageInfo targetPackage,
@@ -91,11 +81,11 @@
             if (FEATURE_FLAG_IDMAP2) {
                 int policies = calculateFulfilledPolicies(targetPackage, overlayPackage, userId);
                 boolean enforce = enforceOverlayable(overlayPackage);
-                if (mIdmap2Service.verifyIdmap(overlayPath, policies, enforce, userId)) {
+                if (mIdmapDaemon.verifyIdmap(overlayPath, policies, enforce, userId)) {
                     return true;
                 }
-                return mIdmap2Service.createIdmap(targetPath, overlayPath, policies, enforce,
-                    userId) != null;
+                return mIdmapDaemon.createIdmap(targetPath, overlayPath, policies,
+                        enforce, userId) != null;
             } else {
                 mInstaller.idmap(targetPath, overlayPath, sharedGid);
                 return true;
@@ -113,7 +103,7 @@
         }
         try {
             if (FEATURE_FLAG_IDMAP2) {
-                return mIdmap2Service.removeIdmap(oi.baseCodePath, userId);
+                return mIdmapDaemon.removeIdmap(oi.baseCodePath, userId);
             } else {
                 mInstaller.removeIdmap(oi.baseCodePath);
                 return true;
@@ -137,7 +127,7 @@
             final int userId) {
         if (FEATURE_FLAG_IDMAP2) {
             try {
-                return mIdmap2Service.getIdmapPath(overlayPackagePath, userId);
+                return mIdmapDaemon.getIdmapPath(overlayPackagePath, userId);
             } catch (Exception e) {
                 Slog.w(TAG, "failed to get idmap path for " + overlayPackagePath + ": "
                         + e.getMessage());
@@ -151,35 +141,6 @@
         }
     }
 
-    private void connectToIdmap2d() {
-        IBinder binder = ServiceManager.getService(IDMAP_SERVICE);
-        if (binder != null) {
-            try {
-                binder.linkToDeath(new IBinder.DeathRecipient() {
-                    @Override
-                    public void binderDied() {
-                        Slog.w(TAG, "service '" + IDMAP_SERVICE + "' died; reconnecting...");
-                        connectToIdmap2d();
-                    }
-
-                }, 0);
-            } catch (RemoteException e) {
-                binder = null;
-            }
-        }
-        if (binder != null) {
-            mIdmap2Service = IIdmap2.Stub.asInterface(binder);
-            if (DEBUG) {
-                Slog.d(TAG, "service '" + IDMAP_SERVICE + "' connected");
-            }
-        } else {
-            Slog.w(TAG, "service '" + IDMAP_SERVICE + "' not found; trying again...");
-            BackgroundThread.getHandler().postDelayed(() -> {
-                connectToIdmap2d();
-            }, SECOND_IN_MILLIS);
-        }
-    }
-
     /**
      * Checks if overlayable and policies should be enforced on the specified overlay for backwards
      * compatibility with pre-Q overlays.
@@ -237,14 +198,9 @@
             return fulfilledPolicies | IIdmap2.POLICY_OEM_PARTITION;
         }
 
-        // Check partitions for which there exists no policy so overlays on these partitions will
-        // not fulfill the system policy.
-        if (ai.isProductServices()) {
-            return fulfilledPolicies;
-        }
-
+        // System_ext partition (/system_ext) is considered as system
         // Check this last since every partition except for data is scanned as system in the PMS.
-        if (ai.isSystemApp()) {
+        if (ai.isSystemApp() || ai.isSystemExt()) {
             return fulfilledPolicies | IIdmap2.POLICY_SYSTEM_PARTITION;
         }
 
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index da69986..ce95181 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -262,6 +262,7 @@
 
             initIfNeeded();
             onSwitchUser(UserHandle.USER_SYSTEM);
+            IdmapDaemon.stopIdmapService();
 
             publishBinderService(Context.OVERLAY_SERVICE, mService);
             publishLocalService(OverlayManagerService.class, this);
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 9094e1b..e5a2e77 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -376,12 +376,12 @@
                 continue;
             }
 
-            // If the path is in /system, /vendor, /product or /product_services, ignore. It will
+            // If the path is in /system, /vendor, /product or /system_ext, ignore. It will
             // have been ota-dexopted into /data/ota and moved into the dalvik-cache already.
             if (pkg.codePath.startsWith("/system")
                     || pkg.codePath.startsWith("/vendor")
                     || pkg.codePath.startsWith("/product")
-                    || pkg.codePath.startsWith("/product_services")) {
+                    || pkg.codePath.startsWith("/system_ext")) {
                 continue;
             }
 
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 6f9a918..4eddb930 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -23,6 +23,7 @@
 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SPLIT;
+import static android.content.pm.PackageParser.APEX_FILE_EXTENSION;
 import static android.content.pm.PackageParser.APK_FILE_EXTENSION;
 import static android.system.OsConstants.O_CREAT;
 import static android.system.OsConstants.O_RDONLY;
@@ -1484,7 +1485,29 @@
                     "Too many files for apex install");
         }
 
-        mResolvedBaseFile = addedFiles[0];
+        try {
+            resolveStageDirLocked();
+        } catch (IOException e) {
+            throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR,
+                    "Failed to resolve stage location", e);
+        }
+
+        File addedFile = addedFiles[0]; // there is only one file
+
+        // Ensure file name has proper suffix
+        final String sourceName = addedFile.getName();
+        final String targetName = sourceName.endsWith(APEX_FILE_EXTENSION)
+                ? sourceName
+                : sourceName + APEX_FILE_EXTENSION;
+        if (!FileUtils.isValidExtFilename(targetName)) {
+            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
+                    "Invalid filename: " + targetName);
+        }
+
+        final File targetFile = new File(mResolvedStageDir, targetName);
+        resolveAndStageFile(addedFile, targetFile);
+
+        mResolvedBaseFile = targetFile;
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 8660d19..c72b38a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -311,7 +311,6 @@
 import com.android.server.pm.dex.PackageDexUsage;
 import com.android.server.pm.dex.ViewCompiler;
 import com.android.server.pm.permission.BasePermission;
-import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
 import com.android.server.pm.permission.PermissionManagerService;
 import com.android.server.pm.permission.PermissionManagerServiceInternal;
 import com.android.server.pm.permission.PermissionsState;
@@ -472,7 +471,7 @@
     static final int SCAN_AS_OEM = 1 << 19;
     static final int SCAN_AS_VENDOR = 1 << 20;
     static final int SCAN_AS_PRODUCT = 1 << 21;
-    static final int SCAN_AS_PRODUCT_SERVICES = 1 << 22;
+    static final int SCAN_AS_SYSTEM_EXT = 1 << 22;
     static final int SCAN_AS_ODM = 1 << 23;
 
     @IntDef(flag = true, prefix = { "SCAN_" }, value = {
@@ -584,7 +583,7 @@
 
     private static final String PRODUCT_OVERLAY_DIR = "/product/overlay";
 
-    private static final String PRODUCT_SERVICES_OVERLAY_DIR = "/product_services/overlay";
+    private static final String SYSTEM_EXT_OVERLAY_DIR = "/system_ext/overlay";
 
     private static final String ODM_OVERLAY_DIR = "/odm/overlay";
 
@@ -948,8 +947,6 @@
     final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
             = new SparseArray<>();
 
-    // TODO remove this and go through mPermissonManager directly
-    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
     // Internal interface for permission manager
     private final PermissionManagerServiceInternal mPermissionManager;
     // Public interface for permission manager
@@ -992,15 +989,6 @@
         void receiveVerificationResponse(int verificationId);
     }
 
-    @GuardedBy("mPackages")
-    private PackageManagerInternal.DefaultBrowserProvider mDefaultBrowserProvider;
-
-    @GuardedBy("mPackages")
-    private PackageManagerInternal.DefaultDialerProvider mDefaultDialerProvider;
-
-    @GuardedBy("mPackages")
-    private PackageManagerInternal.DefaultHomeProvider mDefaultHomeProvider;
-
     private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
         private Context mContext;
         private ComponentName mIntentFilterVerifierComponent;
@@ -1966,7 +1954,7 @@
                             final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
                             if (pkgSetting.getInstallReason(userId)
                                     != PackageManager.INSTALL_REASON_DEVICE_RESTORE) {
-                                setDefaultBrowserAsyncLPw(null, userId);
+                                mPermissionManager.setDefaultBrowser(null, true, true, userId);
                             }
                         }
                     }
@@ -2348,7 +2336,6 @@
                     mPackages /*externalLock*/);
             mPermissionManagerService =
                     (IPermissionManager) ServiceManager.getService("permissionmgr");
-            mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
             mSettings = new Settings(Environment.getDataDirectory(),
                     mPermissionManager.getPermissionSettings(), mPackages);
         }
@@ -2540,7 +2527,7 @@
                 scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
             }
 
-            // Collect vendor/product/product_services overlay packages. (Do this before scanning
+            // Collect vendor/product/system_ext overlay packages. (Do this before scanning
             // any apps.)
             // For security and version matching reason, only consider overlay packages if they
             // reside in the right directory.
@@ -2558,12 +2545,12 @@
                     | SCAN_AS_SYSTEM
                     | SCAN_AS_PRODUCT,
                     0);
-            scanDirTracedLI(new File(PRODUCT_SERVICES_OVERLAY_DIR),
+            scanDirTracedLI(new File(SYSTEM_EXT_OVERLAY_DIR),
                     mDefParseFlags
                     | PackageParser.PARSE_IS_SYSTEM_DIR,
                     scanFlags
                     | SCAN_AS_SYSTEM
-                    | SCAN_AS_PRODUCT_SERVICES,
+                    | SCAN_AS_SYSTEM_EXT,
                     0);
             scanDirTracedLI(new File(ODM_OVERLAY_DIR),
                     mDefParseFlags
@@ -2721,37 +2708,37 @@
                     | SCAN_AS_PRODUCT,
                     0);
 
-            // Collected privileged /product_services packages.
-            File privilegedProductServicesAppDir =
-                    new File(Environment.getProductServicesDirectory(), "priv-app");
+            // Collected privileged /system_ext packages.
+            File privilegedSystemExtAppDir =
+                    new File(Environment.getSystemExtDirectory(), "priv-app");
             try {
-                privilegedProductServicesAppDir =
-                        privilegedProductServicesAppDir.getCanonicalFile();
+                privilegedSystemExtAppDir =
+                        privilegedSystemExtAppDir.getCanonicalFile();
             } catch (IOException e) {
                 // failed to look up canonical path, continue with original one
             }
-            scanDirTracedLI(privilegedProductServicesAppDir,
+            scanDirTracedLI(privilegedSystemExtAppDir,
                     mDefParseFlags
                     | PackageParser.PARSE_IS_SYSTEM_DIR,
                     scanFlags
                     | SCAN_AS_SYSTEM
-                    | SCAN_AS_PRODUCT_SERVICES
+                    | SCAN_AS_SYSTEM_EXT
                     | SCAN_AS_PRIVILEGED,
                     0);
 
-            // Collect ordinary /product_services packages.
-            File productServicesAppDir = new File(Environment.getProductServicesDirectory(), "app");
+            // Collect ordinary /system_ext packages.
+            File systemExtAppDir = new File(Environment.getSystemExtDirectory(), "app");
             try {
-                productServicesAppDir = productServicesAppDir.getCanonicalFile();
+                systemExtAppDir = systemExtAppDir.getCanonicalFile();
             } catch (IOException e) {
                 // failed to look up canonical path, continue with original one
             }
-            scanDirTracedLI(productServicesAppDir,
+            scanDirTracedLI(systemExtAppDir,
                     mDefParseFlags
                     | PackageParser.PARSE_IS_SYSTEM_DIR,
                     scanFlags
                     | SCAN_AS_SYSTEM
-                    | SCAN_AS_PRODUCT_SERVICES,
+                    | SCAN_AS_SYSTEM_EXT,
                     0);
 
             // Prune any system packages that no longer exist.
@@ -2981,23 +2968,23 @@
                                     scanFlags
                                     | SCAN_AS_SYSTEM
                                     | SCAN_AS_PRODUCT;
-                        } else if (FileUtils.contains(privilegedProductServicesAppDir, scanFile)) {
+                        } else if (FileUtils.contains(privilegedSystemExtAppDir, scanFile)) {
                             reparseFlags =
                                     mDefParseFlags |
                                     PackageParser.PARSE_IS_SYSTEM_DIR;
                             rescanFlags =
                                     scanFlags
                                     | SCAN_AS_SYSTEM
-                                    | SCAN_AS_PRODUCT_SERVICES
+                                    | SCAN_AS_SYSTEM_EXT
                                     | SCAN_AS_PRIVILEGED;
-                        } else if (FileUtils.contains(productServicesAppDir, scanFile)) {
+                        } else if (FileUtils.contains(systemExtAppDir, scanFile)) {
                             reparseFlags =
                                     mDefParseFlags |
                                     PackageParser.PARSE_IS_SYSTEM_DIR;
                             rescanFlags =
                                     scanFlags
                                     | SCAN_AS_SYSTEM
-                                    | SCAN_AS_PRODUCT_SERVICES;
+                                    | SCAN_AS_SYSTEM_EXT;
                         } else {
                             Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
                             continue;
@@ -5499,40 +5486,6 @@
     }
 
     @Override
-    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
-        if (UserHandle.getCallingUserId() != userId) {
-            mContext.enforceCallingPermission(
-                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
-                    "isPermissionRevokedByPolicy for user " + userId);
-        }
-
-        if (checkPermission(permission, packageName, userId)
-                == PackageManager.PERMISSION_GRANTED) {
-            return false;
-        }
-
-        final int callingUid = Binder.getCallingUid();
-        if (getInstantAppPackageName(callingUid) != null) {
-            if (!isCallerSameApp(packageName, callingUid)) {
-                return false;
-            }
-        } else {
-            if (isInstantApp(packageName, userId)) {
-                return false;
-            }
-        }
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            final int flags = mPermissionManager
-                    .getPermissionFlags(permission, packageName, Binder.getCallingUid(), userId);
-            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    @Override
     public String getPermissionControllerPackageName() {
         synchronized (mPackages) {
             return mRequiredPermissionControllerPackage;
@@ -5588,46 +5541,6 @@
     }
 
     @Override
-    public boolean shouldShowRequestPermissionRationale(String permName,
-            String packageName, int userId) {
-        if (UserHandle.getCallingUserId() != userId) {
-            mContext.enforceCallingPermission(
-                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
-                    "canShowRequestPermissionRationale for user " + userId);
-        }
-
-        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
-        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
-            return false;
-        }
-
-        if (checkPermission(permName, packageName, userId)
-                == PackageManager.PERMISSION_GRANTED) {
-            return false;
-        }
-
-        final int flags;
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            flags = mPermissionManager
-                    .getPermissionFlags(permName, packageName, Binder.getCallingUid(), userId);
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-
-        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
-                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
-                | PackageManager.FLAG_PERMISSION_USER_FIXED;
-
-        if ((flags & fixedFlags) != 0) {
-            return false;
-        }
-
-        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
-    }
-
-    @Override
     public boolean isProtectedBroadcast(String actionName) {
         // allow instant applications
         synchronized (mProtectedBroadcasts) {
@@ -7286,7 +7199,8 @@
                 } else {
                     // Browser/generic handling case.  If there's a default browser, go straight
                     // to that (but only if there is no other higher-priority match).
-                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
+                    final String defaultBrowserPackageName =
+                            mPermissionManager.getDefaultBrowser(userId);
                     int maxMatchPrio = 0;
                     ResolveInfo defaultBrowserMatch = null;
                     final int numCandidates = matchAllList.size();
@@ -10340,7 +10254,7 @@
      * <li>{@link #SCAN_AS_OEM}</li>
      * <li>{@link #SCAN_AS_VENDOR}</li>
      * <li>{@link #SCAN_AS_PRODUCT}</li>
-     * <li>{@link #SCAN_AS_PRODUCT_SERVICES}</li>
+     * <li>{@link #SCAN_AS_SYSTEM_EXT}</li>
      * <li>{@link #SCAN_AS_INSTANT_APP}</li>
      * <li>{@link #SCAN_AS_VIRTUAL_PRELOAD}</li>
      * <li>{@link #SCAN_AS_ODM}</li>
@@ -10377,8 +10291,8 @@
                 scanFlags |= SCAN_AS_PRODUCT;
             }
             if ((systemPkgSetting.pkgPrivateFlags
-                    & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0) {
-                scanFlags |= SCAN_AS_PRODUCT_SERVICES;
+                    & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0) {
+                scanFlags |= SCAN_AS_SYSTEM_EXT;
             }
             if ((systemPkgSetting.pkgPrivateFlags
                     & ApplicationInfo.PRIVATE_FLAG_ODM) != 0) {
@@ -11156,8 +11070,8 @@
             pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT;
         }
 
-        if ((scanFlags & SCAN_AS_PRODUCT_SERVICES) != 0) {
-            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES;
+        if ((scanFlags & SCAN_AS_SYSTEM_EXT) != 0) {
+            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT;
         }
 
         if ((scanFlags & SCAN_AS_ODM) != 0) {
@@ -12121,8 +12035,8 @@
             codeRoot = Environment.getOdmDirectory();
         } else if (FileUtils.contains(Environment.getProductDirectory(), codePath)) {
             codeRoot = Environment.getProductDirectory();
-        } else if (FileUtils.contains(Environment.getProductServicesDirectory(), codePath)) {
-            codeRoot = Environment.getProductServicesDirectory();
+        } else if (FileUtils.contains(Environment.getSystemExtDirectory(), codePath)) {
+            codeRoot = Environment.getSystemExtDirectory();
         } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
             codeRoot = Environment.getOdmDirectory();
         } else {
@@ -12826,7 +12740,9 @@
 
     @Override
     public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) {
-        enforceSystemOrPhoneCaller("setSystemAppHiddenUntilInstalled");
+        final int callingUid = Binder.getCallingUid();
+        PackageManagerServiceUtils
+                .enforceSystemOrPhoneCaller("setSystemAppHiddenUntilInstalled", callingUid);
         synchronized (mPackages) {
             final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
             if (pkgSetting == null || !pkgSetting.isSystem()) {
@@ -12849,7 +12765,9 @@
 
     @Override
     public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
-        enforceSystemOrPhoneCaller("setSystemAppInstallState");
+        final int callingUid = Binder.getCallingUid();
+        PackageManagerServiceUtils
+                .enforceSystemOrPhoneCaller("setSystemAppInstallState", callingUid);
         synchronized (mPackages) {
             final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
             // The target app should always be in system
@@ -13421,7 +13339,7 @@
         final long callingId = Binder.clearCallingIdentity();
         try {
             final String activeLauncherPackageName = getActiveLauncherPackageName(userId);
-            final String dialerPackageName = getDefaultDialerPackageName(userId);
+            final String dialerPackageName = mPermissionManager.getDefaultDialer(userId);
             for (int i = 0; i < packageNames.length; i++) {
                 canSuspend[i] = false;
                 final String packageName = packageNames[i];
@@ -13503,19 +13421,6 @@
         return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
     }
 
-    @Nullable
-    private String getDefaultDialerPackageName(@UserIdInt int userId) {
-        PackageManagerInternal.DefaultDialerProvider provider;
-        synchronized (mPackages) {
-            provider = mDefaultDialerProvider;
-        }
-        if (provider == null) {
-            Slog.e(TAG, "mDefaultDialerProvider is null");
-            return null;
-        }
-        return provider.getDefaultDialer(userId);
-    }
-
     @Override
     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
         mContext.enforceCallingOrSelfPermission(
@@ -13874,75 +13779,6 @@
         }
     }
 
-    @Override
-    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
-        if (UserHandle.getCallingUserId() != userId) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
-        }
-        if (userId == UserHandle.USER_ALL) {
-            return false;
-        }
-        PackageManagerInternal.DefaultBrowserProvider provider;
-        synchronized (mPackages) {
-            provider = mDefaultBrowserProvider;
-        }
-        if (provider == null) {
-            Slog.e(TAG, "mDefaultBrowserProvider is null");
-            return false;
-        }
-        boolean successful = provider.setDefaultBrowser(packageName, userId);
-        if (!successful) {
-            return false;
-        }
-        if (packageName != null) {
-            synchronized (mPackages) {
-                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(packageName,
-                        userId);
-            }
-        }
-        return true;
-    }
-
-    private void setDefaultBrowserAsyncLPw(@Nullable String packageName, @UserIdInt int userId) {
-        if (userId == UserHandle.USER_ALL) {
-            return;
-        }
-        if (mDefaultBrowserProvider == null) {
-            Slog.e(TAG, "mDefaultBrowserProvider is null");
-            return;
-        }
-        mDefaultBrowserProvider.setDefaultBrowserAsync(packageName, userId);
-        if (packageName != null) {
-            synchronized (mPackages) {
-                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(packageName,
-                        userId);
-            }
-        }
-    }
-
-    @Override
-    public String getDefaultBrowserPackageName(int userId) {
-        if (UserHandle.getCallingUserId() != userId) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
-        }
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
-            return null;
-        }
-        PackageManagerInternal.DefaultBrowserProvider provider;
-        synchronized (mPackages) {
-            provider = mDefaultBrowserProvider;
-        }
-        if (provider == null) {
-            Slog.e(TAG, "mDefaultBrowserProvider is null");
-            return null;
-        }
-        return provider.getDefaultBrowser(userId);
-    }
-
     /**
      * Get the "allow unknown sources" setting.
      *
@@ -16082,13 +15918,13 @@
                                 && compareSignatures(sharedUserSignatures,
                                         pkg.mSigningDetails.signatures)
                                         != PackageManager.SIGNATURE_MATCH) {
-                            if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 28) {
+                            if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 29) {
                                 // Mismatched signatures is an error and silently skipping system
                                 // packages will likely break the device in unforeseen ways.
-                                // However,
-                                // we allow the device to boot anyway because, prior to P,
-                                // vendors were
-                                // not expecting the platform to crash in this situation.
+                                // However, we allow the device to boot anyway because, prior to Q,
+                                // vendors were not expecting the platform to crash in this
+                                // situation.
+                                // This WILL be a hard failure on any new API levels after Q.
                                 throw new ReconcileFailure(
                                         INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
                                         "Signature mismatch for shared user: "
@@ -17678,9 +17514,9 @@
         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
     }
 
-    private static boolean isProductServicesApp(PackageParser.Package pkg) {
+    private static boolean isSystemExtApp(PackageParser.Package pkg) {
         return (pkg.applicationInfo.privateFlags
-                & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0;
+                & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0;
     }
 
     private static boolean isOdmApp(PackageParser.Package pkg) {
@@ -18445,13 +18281,13 @@
             final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
             final File privilegedOdmAppDir = new File(Environment.getOdmDirectory(), "priv-app");
             final File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
-            final File privilegedProductServicesAppDir =
-                    new File(Environment.getProductServicesDirectory(), "priv-app");
+            final File privilegedSystemExtAppDir =
+                    new File(Environment.getSystemExtDirectory(), "priv-app");
             return path.startsWith(privilegedAppDir.getCanonicalPath() + "/")
                     || path.startsWith(privilegedVendorAppDir.getCanonicalPath() + "/")
                     || path.startsWith(privilegedOdmAppDir.getCanonicalPath() + "/")
                     || path.startsWith(privilegedProductAppDir.getCanonicalPath() + "/")
-                    || path.startsWith(privilegedProductServicesAppDir.getCanonicalPath() + "/");
+                    || path.startsWith(privilegedSystemExtAppDir.getCanonicalPath() + "/");
         } catch (IOException e) {
             Slog.e(TAG, "Unable to access code path " + path);
         }
@@ -18486,10 +18322,10 @@
         return false;
     }
 
-    static boolean locationIsProductServices(String path) {
+    static boolean locationIsSystemExt(String path) {
         try {
             return path.startsWith(
-              Environment.getProductServicesDirectory().getCanonicalPath() + "/");
+              Environment.getSystemExtDirectory().getCanonicalPath() + "/");
         } catch (IOException e) {
             Slog.e(TAG, "Unable to access code path " + path);
         }
@@ -18622,8 +18458,8 @@
         if (locationIsProduct(codePathString)) {
             scanFlags |= SCAN_AS_PRODUCT;
         }
-        if (locationIsProductServices(codePathString)) {
-            scanFlags |= SCAN_AS_PRODUCT_SERVICES;
+        if (locationIsSystemExt(codePathString)) {
+            scanFlags |= SCAN_AS_SYSTEM_EXT;
         }
         if (locationIsOdm(codePathString)) {
             scanFlags |= SCAN_AS_ODM;
@@ -19688,10 +19524,10 @@
     }
 
     private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
-        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
+        final String defaultBrowserPackageName = mPermissionManager.getDefaultBrowser(userId);
         if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
             if (packageName.equals(defaultBrowserPackageName)) {
-                setDefaultBrowserPackageName(null, userId);
+                mPermissionManager.setDefaultBrowser(null, true, true, userId);
             }
         }
     }
@@ -19719,7 +19555,7 @@
             // significant refactoring to keep all default apps in the package
             // manager (cleaner but more work) or have the services provide
             // callbacks to the package manager to request a default app reset.
-            setDefaultBrowserPackageName(null, userId);
+            mPermissionManager.setDefaultBrowser(null, true, true, userId);
             resetNetworkPolicies(userId);
             synchronized (mPackages) {
                 scheduleWritePackageRestrictionsLocked(userId);
@@ -19972,17 +19808,14 @@
             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
             restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
                     (parser1, userId1) -> {
-                        String defaultBrowser;
+                        final String defaultBrowser;
                         synchronized (mPackages) {
                             mSettings.readDefaultAppsLPw(parser1, userId1);
                             defaultBrowser = mSettings.removeDefaultBrowserPackageNameLPw(userId1);
                         }
                         if (defaultBrowser != null) {
-                            PackageManagerInternal.DefaultBrowserProvider provider;
-                            synchronized (mPackages) {
-                                provider = mDefaultBrowserProvider;
-                            }
-                            provider.setDefaultBrowser(defaultBrowser, userId1);
+                            mPermissionManager
+                                    .setDefaultBrowser(defaultBrowser, false, false, userId1);
                         }
                     });
         } catch (Exception e) {
@@ -20219,15 +20052,7 @@
         }
         allHomeCandidates.addAll(resolveInfos);
 
-        PackageManagerInternal.DefaultHomeProvider provider;
-        synchronized (mPackages) {
-            provider = mDefaultHomeProvider;
-        }
-        if (provider == null) {
-            Slog.e(TAG, "mDefaultHomeProvider is null");
-            return null;
-        }
-        String packageName = provider.getDefaultHome(userId);
+        final String packageName = mPermissionManager.getDefaultHome(userId);
         if (packageName == null) {
             return null;
         }
@@ -20280,15 +20105,7 @@
         final String packageName = preferredResolveInfo != null
                 && preferredResolveInfo.activityInfo != null
                 ? preferredResolveInfo.activityInfo.packageName : null;
-        final PackageManagerInternal.DefaultHomeProvider provider;
-        synchronized (mPackages) {
-            provider = mDefaultHomeProvider;
-        }
-        if (provider == null) {
-            Slog.e(TAG, "Default home provider has not been set");
-            return false;
-        }
-        final String currentPackageName = provider.getDefaultHome(userId);
+        final String currentPackageName = mPermissionManager.getDefaultHome(userId);
         if (TextUtils.equals(currentPackageName, packageName)) {
             return false;
         }
@@ -20298,7 +20115,7 @@
             // PermissionController manages default home directly.
             return false;
         }
-        provider.setDefaultHomeAsync(packageName, userId, (successful) -> {
+        mPermissionManager.setDefaultHome(currentPackageName, userId, (successful) -> {
             if (successful) {
                 postPreferredActivityChangedBroadcast(userId);
             }
@@ -20854,7 +20671,8 @@
         // Disable any carrier apps. We do this very early in boot to prevent the apps from being
         // disabled after already being started.
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
-                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
+                mPermissionManagerService, mContext.getContentResolver(),
+                UserHandle.USER_SYSTEM);
 
         disableSkuSpecificApps();
 
@@ -20868,8 +20686,6 @@
             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
         }
 
-        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
-
         synchronized (mPackages) {
             // Verify that all of the preferred activity components actually
             // exist.  It is possible for applications to be updated and at
@@ -20899,27 +20715,9 @@
                             mSettings.mPreferredActivities.keyAt(i));
                 }
             }
-
-            for (int userId : UserManagerService.getInstance().getUserIds()) {
-                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
-                    grantPermissionsUserIds = ArrayUtils.appendInt(
-                            grantPermissionsUserIds, userId);
-                }
-            }
         }
 
         sUserManager.systemReady();
-        // If we upgraded grant all default permissions before kicking off.
-        for (int userId : grantPermissionsUserIds) {
-            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
-        }
-
-        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
-            // If we did not grant default permissions, we preload from this the
-            // default permission exceptions lazily to ensure we don't hit the
-            // disk on a new user creation.
-            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
-        }
 
         // Now that we've scanned all packages, and granted any default
         // permissions, ensure permissions are updated. Beware of dragons if you
@@ -22943,11 +22741,7 @@
     }
 
     void onNewUserCreated(final int userId) {
-        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
-        synchronized(mPackages) {
-            // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
-            mPermissionManager.updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, true);
-        }
+        mPermissionManager.onNewUserCreated(userId);
     }
 
     @Override
@@ -22962,44 +22756,6 @@
     }
 
     @Override
-    public void setPermissionEnforced(String permission, boolean enforced) {
-        // TODO: Now that we no longer change GID for storage, this should to away.
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
-                "setPermissionEnforced");
-        if (READ_EXTERNAL_STORAGE.equals(permission)) {
-            synchronized (mPackages) {
-                if (mSettings.mReadExternalStorageEnforced == null
-                        || mSettings.mReadExternalStorageEnforced != enforced) {
-                    mSettings.mReadExternalStorageEnforced =
-                            enforced ? Boolean.TRUE : Boolean.FALSE;
-                    mSettings.writeLPr();
-                }
-            }
-            // kill any non-foreground processes so we restart them and
-            // grant/revoke the GID.
-            final IActivityManager am = ActivityManager.getService();
-            if (am != null) {
-                final long token = Binder.clearCallingIdentity();
-                try {
-                    am.killProcessesBelowForeground("setPermissionEnforcement");
-                } catch (RemoteException e) {
-                } finally {
-                    Binder.restoreCallingIdentity(token);
-                }
-            }
-        } else {
-            throw new IllegalArgumentException("No selective enforcement for " + permission);
-        }
-    }
-
-    @Override
-    @Deprecated
-    public boolean isPermissionEnforced(String permission) {
-        // allow instant applications
-        return true;
-    }
-
-    @Override
     public boolean isStorageLow() {
         // allow instant applications
         final long token = Binder.clearCallingIdentity();
@@ -23463,8 +23219,20 @@
         @Override
         public boolean filterAppAccess(PackageParser.Package pkg, int callingUid, int userId) {
             synchronized (mPackages) {
-                return PackageManagerService.this.filterAppAccessLPr(
-                        (PackageSetting) pkg.mExtras, callingUid, userId);
+                return PackageManagerService.this
+                        .filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid, userId);
+            }
+        }
+
+        @Override
+        public boolean filterAppAccess(String packageName, int callingUid, int userId) {
+            synchronized (mPackages) {
+                final PackageParser.Package pkg = mPackages.get(packageName);
+                if (pkg == null) {
+                    return false;
+                }
+                return PackageManagerService.this
+                        .filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid, userId);
             }
         }
 
@@ -23531,7 +23299,7 @@
         public String getKnownPackageName(int knownPackage, int userId) {
             switch(knownPackage) {
                 case PackageManagerInternal.PACKAGE_BROWSER:
-                    return getDefaultBrowserPackageName(userId);
+                    return mPermissionManager.getDefaultBrowser(userId);
                 case PackageManagerInternal.PACKAGE_INSTALLER:
                     return mRequiredInstallerPackage;
                 case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
@@ -23565,37 +23333,6 @@
         }
 
         @Override
-        public void setLocationPackagesProvider(PackagesProvider provider) {
-            mDefaultPermissionPolicy.setLocationPackagesProvider(provider);
-        }
-
-        @Override
-        public void setLocationExtraPackagesProvider(PackagesProvider provider) {
-            mDefaultPermissionPolicy.setLocationExtraPackagesProvider(provider);
-        }
-
-        @Override
-        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
-            mDefaultPermissionPolicy.setVoiceInteractionPackagesProvider(provider);
-        }
-
-        @Override
-        public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
-            mDefaultPermissionPolicy.setUseOpenWifiAppPackagesProvider(provider);
-        }
-
-        @Override
-        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
-            mDefaultPermissionPolicy.setSyncAdapterPackagesProvider(provider);
-        }
-
-        @Override
-        public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
-            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultUseOpenWifiApp(
-                    packageName, userId);
-        }
-
-        @Override
         public void setKeepUninstalledPackages(final List<String> packageList) {
             Preconditions.checkNotNull(packageList);
             List<String> removedFromList = null;
@@ -24108,27 +23845,6 @@
         }
 
         @Override
-        public void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider) {
-            synchronized (mPackages) {
-                mDefaultBrowserProvider = provider;
-            }
-        }
-
-        @Override
-        public void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider) {
-            synchronized (mPackages) {
-                mDefaultDialerProvider = provider;
-            }
-        }
-
-        @Override
-        public void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider) {
-            synchronized (mPackages) {
-                mDefaultHomeProvider = provider;
-            }
-        }
-
-        @Override
         public boolean isApexPackage(String packageName) {
             return PackageManagerService.this.mApexManager.isApexPackage(packageName);
         }
@@ -24174,13 +23890,6 @@
         }
 
         @Override
-        public boolean wereDefaultPermissionsGrantedSinceBoot(int userId) {
-            synchronized (mPackages) {
-                return mDefaultPermissionPolicy.wereDefaultPermissionsGrantedSinceBoot(userId);
-            }
-        }
-
-        @Override
         public void setRuntimePermissionsFingerPrint(@NonNull String fingerPrint,
                 @UserIdInt int userId) {
             synchronized (mPackages) {
@@ -24266,6 +23975,25 @@
                         && UserHandle.isSameApp(installerPackageSetting.appId, callingUid);
             }
         }
+
+        @Override
+        public boolean areDefaultRuntimePermissionsGranted(int userId) {
+            synchronized (mPackages) {
+                return mSettings.areDefaultRuntimePermissionsGrantedLPr(userId);
+            }
+        }
+
+        @Override
+        public void setReadExternalStorageEnforced(boolean enforced) {
+            synchronized (mPackages) {
+                if (mSettings.mReadExternalStorageEnforced != null
+                        && mSettings.mReadExternalStorageEnforced == enforced) {
+                    return;
+                }
+                mSettings.mReadExternalStorageEnforced = enforced ? Boolean.TRUE : Boolean.FALSE;
+                mSettings.writeLPr();
+            }
+        }
     }
 
     @GuardedBy("mPackages")
@@ -24334,83 +24062,6 @@
         }
     }
 
-    @Override
-    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
-        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
-        synchronized (mPackages) {
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierApps(
-                        packageNames, userId);
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-
-    @Override
-    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
-        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
-        synchronized (mPackages) {
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServices(
-                        packageNames, userId);
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-
-    @Override
-    public void grantDefaultPermissionsToEnabledTelephonyDataServices(
-            String[] packageNames, int userId) {
-        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledTelephonyDataServices");
-        synchronized (mPackages) {
-            Binder.withCleanCallingIdentity( () -> mDefaultPermissionPolicy.
-                    grantDefaultPermissionsToEnabledTelephonyDataServices(
-                            packageNames, userId));
-        }
-    }
-
-    @Override
-    public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
-            String[] packageNames, int userId) {
-        enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromDisabledTelephonyDataServices");
-        synchronized (mPackages) {
-            Binder.withCleanCallingIdentity( () -> mDefaultPermissionPolicy.
-                    revokeDefaultPermissionsFromDisabledTelephonyDataServices(
-                            packageNames, userId));
-        }
-    }
-
-    @Override
-    public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
-        enforceSystemOrPhoneCaller("grantDefaultPermissionsToActiveLuiApp");
-        synchronized (mPackages) {
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                mDefaultPermissionPolicy.grantDefaultPermissionsToActiveLuiApp(
-                        packageName, userId);
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-
-    @Override
-    public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
-        enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromLuiApps");
-        synchronized (mPackages) {
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                mDefaultPermissionPolicy.revokeDefaultPermissionsFromLuiApps(packageNames, userId);
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-
     void forEachPackage(Consumer<PackageParser.Package> actionLocked) {
         synchronized (mPackages) {
             int numPackages = mPackages.size();
@@ -24435,14 +24086,6 @@
         }
     }
 
-    private static void enforceSystemOrPhoneCaller(String tag) {
-        int callingUid = Binder.getCallingUid();
-        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
-            throw new SecurityException(
-                    "Cannot call " + tag + " from UID " + callingUid);
-        }
-    }
-
     boolean isHistoricalPackageUsageAvailable() {
         return mPackageUsage.isHistoricalPackageUsageAvailable();
     }
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index f56e1ef..4c7db9a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -390,6 +390,17 @@
     }
 
     /**
+     * Enforces that the caller must be either the system process or the phone process.
+     * If not, throws a {@link SecurityException}.
+     */
+    public static void enforceSystemOrPhoneCaller(String methodName, int callingUid) {
+        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
+            throw new SecurityException(
+                    "Cannot call " + methodName + " from UID " + callingUid);
+        }
+    }
+
+    /**
      * Derive the value of the {@code cpuAbiOverride} based on the provided
      * value and an optional stored value from the package settings.
      */
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 53c1c1f..85bc9f3 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -2020,7 +2020,7 @@
             getErrPrintWriter().println("Error: no enforcement specified");
             return 1;
         }
-        mInterface.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw));
+        mPermissionManager.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw));
         return 0;
     }
 
@@ -2042,10 +2042,10 @@
         }
     }
 
-    private boolean isProductServicesApp(String pkg) {
+    private boolean isSystemExtApp(String pkg) {
         try {
             final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
-            return info != null && info.applicationInfo.isProductServices();
+            return info != null && info.applicationInfo.isSystemExt();
         } catch (RemoteException e) {
             return false;
         }
@@ -2063,9 +2063,9 @@
             privAppPermissions = SystemConfig.getInstance().getVendorPrivAppPermissions(pkg);
         } else if (isProductApp(pkg)) {
             privAppPermissions = SystemConfig.getInstance().getProductPrivAppPermissions(pkg);
-        } else if (isProductServicesApp(pkg)) {
+        } else if (isSystemExtApp(pkg)) {
             privAppPermissions = SystemConfig.getInstance()
-                    .getProductServicesPrivAppPermissions(pkg);
+                    .getSystemExtPrivAppPermissions(pkg);
         } else {
             privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg);
         }
@@ -2087,9 +2087,9 @@
             privAppPermissions = SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg);
         } else if (isProductApp(pkg)) {
             privAppPermissions = SystemConfig.getInstance().getProductPrivAppDenyPermissions(pkg);
-        } else if (isProductServicesApp(pkg)) {
+        } else if (isSystemExtApp(pkg)) {
             privAppPermissions = SystemConfig.getInstance()
-                    .getProductServicesPrivAppDenyPermissions(pkg);
+                    .getSystemExtPrivAppDenyPermissions(pkg);
         } else {
             privAppPermissions = SystemConfig.getInstance().getPrivAppDenyPermissions(pkg);
         }
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index e859893..4ea8a30 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -148,8 +148,8 @@
         return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
     }
 
-    public boolean isProductServices() {
-        return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0;
+    public boolean isSystemExt() {
+        return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0;
     }
 
     public boolean isOdm() {
diff --git a/services/core/java/com/android/server/pm/SettingBase.java b/services/core/java/com/android/server/pm/SettingBase.java
index a24818f..ec9746d 100644
--- a/services/core/java/com/android/server/pm/SettingBase.java
+++ b/services/core/java/com/android/server/pm/SettingBase.java
@@ -63,7 +63,7 @@
                 | ApplicationInfo.PRIVATE_FLAG_OEM
                 | ApplicationInfo.PRIVATE_FLAG_VENDOR
                 | ApplicationInfo.PRIVATE_FLAG_PRODUCT
-                | ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES
+                | ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT
                 | ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER
                 | ApplicationInfo.PRIVATE_FLAG_ODM);
     }
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 11a8f4b..3bc2236 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -774,7 +774,7 @@
                 | ApplicationInfo.PRIVATE_FLAG_OEM
                 | ApplicationInfo.PRIVATE_FLAG_VENDOR
                 | ApplicationInfo.PRIVATE_FLAG_PRODUCT
-                | ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES
+                | ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT
                 | ApplicationInfo.PRIVATE_FLAG_ODM);
         pkgSetting.pkgFlags |= pkgFlags & ApplicationInfo.FLAG_SYSTEM;
         pkgSetting.pkgPrivateFlags |=
@@ -786,7 +786,7 @@
         pkgSetting.pkgPrivateFlags |=
                 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT;
         pkgSetting.pkgPrivateFlags |=
-                pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES;
+                pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT;
         pkgSetting.pkgPrivateFlags |=
                 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_ODM;
         pkgSetting.primaryCpuAbiString = primaryCpuAbi;
@@ -4413,7 +4413,7 @@
             ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY, "STATIC_SHARED_LIBRARY",
             ApplicationInfo.PRIVATE_FLAG_VENDOR, "VENDOR",
             ApplicationInfo.PRIVATE_FLAG_PRODUCT, "PRODUCT",
-            ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES, "PRODUCT_SERVICES",
+            ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT, "SYSTEM_EXT",
             ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD, "VIRTUAL_PRELOAD",
             ApplicationInfo.PRIVATE_FLAG_ODM, "ODM",
     };
diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING
index e375fa4..b829f0b 100644
--- a/services/core/java/com/android/server/pm/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/TEST_MAPPING
@@ -8,7 +8,9 @@
     },
     {
       "name": "CtsCompilationTestCases"
-    },
+    }
+  ],
+  "postsubmit": [
     {
       "name": "CtsPermissionTestCases",
       "options": [
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index db01d77..fe0b3a3 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -34,8 +34,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.PackageManagerInternal;
-import android.content.pm.PackageManagerInternal.PackagesProvider;
-import android.content.pm.PackageManagerInternal.SyncAdapterPackagesProvider;
 import android.content.pm.PermissionInfo;
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
@@ -69,6 +67,8 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.XmlUtils;
 import com.android.server.LocalServices;
+import com.android.server.pm.permission.PermissionManagerServiceInternal.PackagesProvider;
+import com.android.server.pm.permission.PermissionManagerServiceInternal.SyncAdapterPackagesProvider;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -1388,8 +1388,7 @@
         if (dir.isDirectory() && dir.canRead()) {
             Collections.addAll(ret, dir.listFiles());
         }
-        dir = new File(Environment.getProductServicesDirectory(),
-                "etc/default-permissions");
+        dir = new File(Environment.getSystemExtDirectory(), "etc/default-permissions");
         if (dir.isDirectory() && dir.canRead()) {
             Collections.addAll(ret, dir.listFiles());
         }
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 9d0b427..673ab6c 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -33,6 +33,7 @@
 import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE;
 import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL;
+import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
 import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED;
 import static android.permission.PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED;
@@ -118,6 +119,9 @@
 import com.android.server.pm.PackageSetting;
 import com.android.server.pm.SharedUserSetting;
 import com.android.server.pm.UserManagerService;
+import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultBrowserProvider;
+import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultDialerProvider;
+import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultHomeProvider;
 import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
 import com.android.server.pm.permission.PermissionsState.PermissionState;
 import com.android.server.policy.SoftRestrictedPermissionPolicy;
@@ -250,6 +254,15 @@
     @GuardedBy("mLock")
     private final OnPermissionChangeListeners mOnPermissionChangeListeners;
 
+    @GuardedBy("mLock")
+    private DefaultBrowserProvider mDefaultBrowserProvider;
+
+    @GuardedBy("mLock")
+    private DefaultDialerProvider mDefaultDialerProvider;
+
+    @GuardedBy("mLock")
+    private DefaultHomeProvider mDefaultHomeProvider;
+
     // TODO: Take a look at the methods defined in the callback.
     // The callback was initially created to support the split between permission
     // manager and the package manager. However, it's started to be used for other
@@ -1609,6 +1622,226 @@
         mPackageManagerInt.writePermissionSettings(asyncUpdatedUsers.toArray(), true);
     }
 
+    @Override
+    public String getDefaultBrowser(int userId) {
+        final int callingUid = Binder.getCallingUid();
+        if (UserHandle.getUserId(callingUid) != userId) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+        }
+        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
+            return null;
+        }
+        synchronized (mLock) {
+            return mDefaultBrowserProvider == null
+                    ? null : mDefaultBrowserProvider.getDefaultBrowser(userId);
+        }
+    }
+
+    @Override
+    public boolean setDefaultBrowser(String packageName, int userId) {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
+        if (UserHandle.getCallingUserId() != userId) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+        }
+        return setDefaultBrowserInternal(packageName, false, true, userId);
+    }
+
+    private boolean setDefaultBrowserInternal(String packageName, boolean async,
+            boolean doGrant, int userId) {
+        synchronized (mLock) {
+            if (userId == UserHandle.USER_ALL) {
+                return false;
+            }
+            if (mDefaultBrowserProvider == null) {
+                return false;
+            }
+            if (async) {
+                mDefaultBrowserProvider.setDefaultBrowserAsync(packageName, userId);
+            } else {
+                if (!mDefaultBrowserProvider.setDefaultBrowser(packageName, userId)) {
+                    return false;
+                }
+            }
+            if (doGrant && packageName != null) {
+                mDefaultPermissionGrantPolicy
+                        .grantDefaultPermissionsToDefaultBrowser(packageName, userId);
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        PackageManagerServiceUtils
+                .enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps", callingUid);
+        synchronized (mLock) {
+            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                    .grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId));
+        }
+    }
+
+    @Override
+    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
+                "grantDefaultPermissionsToEnabledImsServices", callingUid);
+        synchronized (mLock) {
+            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                    .grantDefaultPermissionsToEnabledImsServices(packageNames, userId));
+        }
+    }
+
+    @Override
+    public void grantDefaultPermissionsToEnabledTelephonyDataServices(
+            String[] packageNames, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
+                "grantDefaultPermissionsToEnabledTelephonyDataServices", callingUid);
+        synchronized (mLock) {
+            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                    .grantDefaultPermissionsToEnabledTelephonyDataServices(
+                            packageNames, userId));
+        }
+    }
+
+    @Override
+    public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
+            String[] packageNames, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
+                "revokeDefaultPermissionsFromDisabledTelephonyDataServices", callingUid);
+        synchronized (mLock) {
+            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                    .revokeDefaultPermissionsFromDisabledTelephonyDataServices(
+                            packageNames, userId));
+        }
+    }
+
+    @Override
+    public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        PackageManagerServiceUtils
+                .enforceSystemOrPhoneCaller("grantDefaultPermissionsToActiveLuiApp", callingUid);
+        synchronized (mLock) {
+            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                    .grantDefaultPermissionsToActiveLuiApp(packageName, userId));
+        }
+    }
+
+    @Override
+    public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        PackageManagerServiceUtils
+                .enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromLuiApps", callingUid);
+        synchronized (mLock) {
+            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                    .revokeDefaultPermissionsFromLuiApps(packageNames, userId));
+        }
+    }
+
+    @Override
+    public void setPermissionEnforced(String permName, boolean enforced) {
+        // TODO: Now that we no longer change GID for storage, this should to away.
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
+                "setPermissionEnforced");
+        if (READ_EXTERNAL_STORAGE.equals(permName)) {
+            mPackageManagerInt.setReadExternalStorageEnforced(enforced);
+            // kill any non-foreground processes so we restart them and
+            // grant/revoke the GID.
+            final IActivityManager am = ActivityManager.getService();
+            if (am != null) {
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    am.killProcessesBelowForeground("setPermissionEnforcement");
+                } catch (RemoteException e) {
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+            }
+        } else {
+            throw new IllegalArgumentException("No selective enforcement for " + permName);
+        }
+    }
+
+    /** @deprecated */
+    @Override
+    @Deprecated
+    public boolean isPermissionEnforced(String permName) {
+        // allow instant applications
+        return true;
+    }
+
+    @Override
+    public boolean shouldShowRequestPermissionRationale(String permName,
+            String packageName, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        if (UserHandle.getCallingUserId() != userId) {
+            mContext.enforceCallingPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+                    "canShowRequestPermissionRationale for user " + userId);
+        }
+
+        final int uid =
+                mPackageManagerInt.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
+        if (UserHandle.getAppId(callingUid) != UserHandle.getAppId(uid)) {
+            return false;
+        }
+
+        if (checkPermission(permName, packageName, userId)
+                == PackageManager.PERMISSION_GRANTED) {
+            return false;
+        }
+
+        final int flags;
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            flags = getPermissionFlagsInternal(permName, packageName, callingUid, userId);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+
+        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
+                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
+                | PackageManager.FLAG_PERMISSION_USER_FIXED;
+
+        if ((flags & fixedFlags) != 0) {
+            return false;
+        }
+
+        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
+    }
+
+    @Override
+    public boolean isPermissionRevokedByPolicy(String permName, String packageName, int userId) {
+        if (UserHandle.getCallingUserId() != userId) {
+            mContext.enforceCallingPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+                    "isPermissionRevokedByPolicy for user " + userId);
+        }
+
+        if (checkPermission(permName, packageName, userId) == PackageManager.PERMISSION_GRANTED) {
+            return false;
+        }
+
+        final int callingUid = Binder.getCallingUid();
+        if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId)) {
+            return false;
+        }
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            final int flags = getPermissionFlagsInternal(permName, packageName, callingUid, userId);
+            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
     /**
      * Get the state of the runtime permissions as xml file.
      *
@@ -2746,9 +2979,9 @@
         } else if (pkg.isProduct()) {
             wlPermissions =
                     SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName);
-        } else if (pkg.isProductServices()) {
+        } else if (pkg.isSystemExt()) {
             wlPermissions =
-                    SystemConfig.getInstance().getProductServicesPrivAppPermissions(
+                    SystemConfig.getInstance().getSystemExtPrivAppPermissions(
                             pkg.packageName);
         } else {
             wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
@@ -2782,9 +3015,9 @@
                     } else if (pkg.isProduct()) {
                         deniedPermissions = SystemConfig.getInstance()
                                 .getProductPrivAppDenyPermissions(pkg.packageName);
-                    } else if (pkg.isProductServices()) {
+                    } else if (pkg.isSystemExt()) {
                         deniedPermissions = SystemConfig.getInstance()
-                                .getProductServicesPrivAppDenyPermissions(pkg.packageName);
+                                .getSystemExtPrivAppDenyPermissions(pkg.packageName);
                     } else {
                         deniedPermissions = SystemConfig.getInstance()
                                 .getPrivAppDenyPermissions(pkg.packageName);
@@ -2793,13 +3026,15 @@
                             deniedPermissions == null || !deniedPermissions.contains(perm);
                     if (permissionViolation) {
                         Slog.w(TAG, "Privileged permission " + perm + " for package "
-                                + pkg.packageName + " - not in privapp-permissions whitelist");
+                                + pkg.packageName + " (" + pkg.codePath
+                                + ") not in privapp-permissions whitelist");
 
                         if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
                             if (mPrivappPermissionsViolations == null) {
                                 mPrivappPermissionsViolations = new ArraySet<>();
                             }
-                            mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
+                            mPrivappPermissionsViolations.add(
+                                    pkg.packageName + " (" + pkg.codePath + "): " + perm);
                         }
                     } else {
                         return false;
@@ -3714,6 +3949,24 @@
         }
 
         mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
+
+        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
+        for (int userId : UserManagerService.getInstance().getUserIds()) {
+            if (!mPackageManagerInt.areDefaultRuntimePermissionsGranted(userId)) {
+                grantPermissionsUserIds = ArrayUtils.appendInt(
+                        grantPermissionsUserIds, userId);
+            }
+        }
+        // If we upgraded grant all default permissions before kicking off.
+        for (int userId : grantPermissionsUserIds) {
+            mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
+        }
+        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
+            // If we did not grant default permissions, we preload from this the
+            // default permission exceptions lazily to ensure we don't hit the
+            // disk on a new user creation.
+            mDefaultPermissionGrantPolicy.scheduleReadDefaultPermissionExceptions();
+        }
     }
 
     private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
@@ -3847,20 +4100,6 @@
                     .getAppOpPermissionPackagesInternal(permName, callingUid);
         }
         @Override
-        public int getPermissionFlags(String permName, String packageName, int callingUid,
-                int userId) {
-            return PermissionManagerService.this
-                    .getPermissionFlagsInternal(permName, packageName, callingUid, userId);
-        }
-        @Override
-        public void updatePermissionFlags(String permName, String packageName, int flagMask,
-                int flagValues, int callingUid, int userId, boolean overridePolicy,
-                PermissionCallback callback) {
-            PermissionManagerService.this.updatePermissionFlagsInternal(
-                    permName, packageName, flagMask, flagValues, callingUid, userId,
-                    overridePolicy, callback);
-        }
-        @Override
         public void enforceCrossUserPermission(int callingUid, int userId,
                 boolean requireFullPermission, boolean checkShell, String message) {
             PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
@@ -3882,10 +4121,6 @@
             return mSettings;
         }
         @Override
-        public DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
-            return mDefaultPermissionGrantPolicy;
-        }
-        @Override
         public BasePermission getPermissionTEMP(String permName) {
             synchronized (PermissionManagerService.this.mLock) {
                 return mSettings.getPermissionLocked(permName);
@@ -3956,9 +4191,166 @@
                 mCheckPermissionDelegate = delegate;
             }
         }
+
         @Override
-        public void notifyPermissionsChangedTEMP(int uid) {
-            mOnPermissionChangeListeners.onPermissionsChanged(uid);
+        public void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider) {
+            synchronized (mLock) {
+                mDefaultBrowserProvider = provider;
+            }
+        }
+
+        @Override
+        public void setDefaultBrowser(String packageName, boolean async, boolean doGrant,
+                int userId) {
+            setDefaultBrowserInternal(packageName, async, doGrant, userId);
+        }
+
+        @Override
+        public void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider) {
+            synchronized (mLock) {
+                mDefaultDialerProvider = provider;
+            }
+        }
+
+        @Override
+        public void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider) {
+            synchronized (mLock) {
+                mDefaultHomeProvider = provider;
+            }
+        }
+
+        @Override
+        public void setDefaultHome(String packageName, int userId, Consumer<Boolean> callback) {
+            synchronized (mLock) {
+                if (userId == UserHandle.USER_ALL) {
+                    return;
+                }
+                if (mDefaultHomeProvider == null) {
+                    return;
+                }
+                mDefaultHomeProvider.setDefaultHomeAsync(packageName, userId, callback);
+            }
+        }
+
+        @Override
+        public void setDialerAppPackagesProvider(PackagesProvider provider) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy.setDialerAppPackagesProvider(provider);
+            }
+        }
+
+        @Override
+        public void setLocationExtraPackagesProvider(PackagesProvider provider) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy.setLocationExtraPackagesProvider(provider);
+            }
+        }
+
+        @Override
+        public void setLocationPackagesProvider(PackagesProvider provider) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy.setLocationPackagesProvider(provider);
+            }
+        }
+
+        @Override
+        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy.setSimCallManagerPackagesProvider(provider);
+            }
+        }
+
+        @Override
+        public void setSmsAppPackagesProvider(PackagesProvider provider) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy.setSmsAppPackagesProvider(provider);
+            }
+        }
+
+        @Override
+        public void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy.setSyncAdapterPackagesProvider(provider);
+            }
+        }
+
+        @Override
+        public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy.setUseOpenWifiAppPackagesProvider(provider);
+            }
+        }
+
+        @Override
+        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy.setVoiceInteractionPackagesProvider(provider);
+            }
+        }
+
+        @Override
+        public String getDefaultBrowser(int userId) {
+            synchronized (mLock) {
+                return mDefaultBrowserProvider == null
+                        ? null : mDefaultBrowserProvider.getDefaultBrowser(userId);
+            }
+        }
+
+        @Override
+        public String getDefaultDialer(int userId) {
+            synchronized (mLock) {
+                return mDefaultDialerProvider == null
+                        ? null : mDefaultDialerProvider.getDefaultDialer(userId);
+            }
+        }
+
+        @Override
+        public String getDefaultHome(int userId) {
+            synchronized (mLock) {
+                return mDefaultHomeProvider == null
+                        ? null : mDefaultHomeProvider.getDefaultHome(userId);
+            }
+        }
+
+        @Override
+        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy
+                        .grantDefaultPermissionsToDefaultSimCallManager(packageName, userId);
+            }
+        }
+
+        @Override
+        public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy
+                        .grantDefaultPermissionsToDefaultUseOpenWifiApp(packageName, userId);
+            }
+        }
+
+        @Override
+        public void grantDefaultPermissionsToDefaultBrowser(String packageName, int userId) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy
+                        .grantDefaultPermissionsToDefaultBrowser(packageName, userId);
+            }
+        }
+
+        @Override
+        public boolean wereDefaultPermissionsGrantedSinceBoot(int userId) {
+            synchronized (mLock) {
+                return mDefaultPermissionGrantPolicy.wereDefaultPermissionsGrantedSinceBoot(userId);
+            }
+        }
+
+        @Override
+        public void onNewUserCreated(int userId) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
+                // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
+                PermissionManagerService.this.updateAllPermissions(
+                        StorageManager.UUID_PRIVATE_INTERNAL, true, mDefaultPermissionCallback);
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
index 2fdab4d..04ec5ba 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
@@ -27,6 +27,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.function.Consumer;
 
 /**
  * Internal interfaces services.
@@ -35,6 +36,109 @@
  */
 public abstract class PermissionManagerServiceInternal extends PermissionManagerInternal {
     /**
+     * Provider for package names.
+     */
+    public interface PackagesProvider {
+
+        /**
+         * Gets the packages for a given user.
+         * @param userId The user id.
+         * @return The package names.
+         */
+        String[] getPackages(int userId);
+    }
+
+    /**
+     * Provider for package names.
+     */
+    public interface SyncAdapterPackagesProvider {
+
+        /**
+         * Gets the sync adapter packages for given authority and user.
+         * @param authority The authority.
+         * @param userId The user id.
+         * @return The package names.
+         */
+        String[] getPackages(String authority, int userId);
+    }
+
+    /**
+     * Provider for default browser
+     */
+    public interface DefaultBrowserProvider {
+
+        /**
+         * Get the package name of the default browser.
+         *
+         * @param userId the user id
+         *
+         * @return the package name of the default browser, or {@code null} if none
+         */
+        @Nullable
+        String getDefaultBrowser(@UserIdInt int userId);
+
+        /**
+         * Set the package name of the default browser.
+         *
+         * @param packageName package name of the default browser, or {@code null} to remove
+         * @param userId the user id
+         *
+         * @return whether the default browser was successfully set.
+         */
+        boolean setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId);
+
+        /**
+         * Set the package name of the default browser asynchronously.
+         *
+         * @param packageName package name of the default browser, or {@code null} to remove
+         * @param userId the user id
+         */
+        void setDefaultBrowserAsync(@Nullable String packageName, @UserIdInt int userId);
+    }
+
+    /**
+     * Provider for default dialer
+     */
+    public interface DefaultDialerProvider {
+
+        /**
+         * Get the package name of the default dialer.
+         *
+         * @param userId the user id
+         *
+         * @return the package name of the default dialer, or {@code null} if none
+         */
+        @Nullable
+        String getDefaultDialer(@UserIdInt int userId);
+    }
+
+    /**
+     * Provider for default home
+     */
+    public interface DefaultHomeProvider {
+
+        /**
+         * Get the package name of the default home.
+         *
+         * @param userId the user id
+         *
+         * @return the package name of the default home, or {@code null} if none
+         */
+        @Nullable
+        String getDefaultHome(@UserIdInt int userId);
+
+        /**
+         * Set the package name of the default home.
+         *
+         * @param packageName package name of the default home, or {@code null} to remove
+         * @param userId the user id
+         * @param callback the callback made after the default home as been updated
+         */
+        void setDefaultHomeAsync(@Nullable String packageName, @UserIdInt int userId,
+                @NonNull Consumer<Boolean> callback);
+    }
+
+    /**
      * Callbacks invoked when interesting actions have been taken on a permission.
      * <p>
      * NOTE: The current arguments are merely to support the existing use cases. This
@@ -159,17 +263,6 @@
     public abstract @Nullable String[] getAppOpPermissionPackages(
             @NonNull String permName, int callingUid);
 
-    public abstract int getPermissionFlags(@NonNull String permName,
-            @NonNull String packageName, int callingUid, int userId);
-
-    /**
-     * Updates the flags associated with a permission by replacing the flags in
-     * the specified mask with the provided flag values.
-     */
-    public abstract void updatePermissionFlags(@NonNull String permName,
-            @NonNull String packageName, int flagMask, int flagValues, int callingUid, int userId,
-            boolean overridePolicy, @Nullable PermissionCallback callback);
-
     /**
      * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
      * or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userid} is not for the caller.
@@ -189,13 +282,13 @@
     public abstract void enforceGrantRevokeRuntimePermissionPermissions(@NonNull String message);
 
     public abstract @NonNull PermissionSettings getPermissionSettings();
-    public abstract @NonNull DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy();
+
+    /** Grants default browser permissions to the given package */
+    public abstract void grantDefaultPermissionsToDefaultBrowser(
+            @NonNull String packageName, @UserIdInt int userId);
 
     /** HACK HACK methods to allow for partial migration of data to the PermissionManager class */
     public abstract @Nullable BasePermission getPermissionTEMP(@NonNull String permName);
-    /** HACK HACK notify the permission listener; this shouldn't be needed after permissions
-     *  are fully removed from the package manager */
-    public abstract void notifyPermissionsChangedTEMP(int uid);
 
     /** Get all permission that have a certain protection level */
     public abstract @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtectionLevel(
@@ -214,4 +307,142 @@
      * @param delegate A delegate instance or {@code null} to clear.
      */
     public abstract void setCheckPermissionDelegate(@Nullable CheckPermissionDelegate delegate);
+
+    /**
+     * Sets the dialer application packages provider.
+     * @param provider The provider.
+     */
+    public abstract void setDialerAppPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Set the location extra packages provider.
+     * @param provider The packages provider.
+     */
+    public abstract  void setLocationExtraPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Sets the location provider packages provider.
+     * @param provider The packages provider.
+     */
+    public abstract void setLocationPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Sets the SIM call manager packages provider.
+     * @param provider The provider.
+     */
+    public abstract void setSimCallManagerPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Sets the SMS application packages provider.
+     * @param provider The provider.
+     */
+    public abstract void setSmsAppPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Sets the sync adapter packages provider.
+     * @param provider The provider.
+     */
+    public abstract void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider);
+
+    /**
+     * Sets the Use Open Wifi packages provider.
+     * @param provider The packages provider.
+     */
+    public abstract void setUseOpenWifiAppPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Sets the voice interaction packages provider.
+     * @param provider The packages provider.
+     */
+    public abstract void setVoiceInteractionPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Sets the default browser provider.
+     *
+     * @param provider the provider
+     */
+    public abstract void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider);
+
+    /**
+     * Sets the package name of the default browser provider for the given user.
+     *
+     * @param packageName The package name of the default browser or {@code null}
+     *          to clear the default browser
+     * @param async If {@code true}, set the default browser asynchronously,
+     *          otherwise set it synchronously
+     * @param doGrant If {@code true} and if {@code packageName} is not {@code null},
+     *          perform default permission grants on the browser, otherwise skip the
+     *          default permission grants.
+     * @param userId The user to set the default browser for.
+     */
+    public abstract void setDefaultBrowser(@Nullable String packageName, boolean async,
+            boolean doGrant, @UserIdInt int userId);
+
+    /**
+     * Sets the default dialer provider.
+     *
+     * @param provider the provider
+     */
+    public abstract void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider);
+
+    /**
+     * Sets the default home provider.
+     *
+     * @param provider the provider
+     */
+    public abstract void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider);
+
+    /**
+     * Asynchronously sets the package name of the default home provider for the given user.
+     *
+     * @param packageName The package name of the default home or {@code null}
+     *          to clear the default browser
+     * @param userId The user to set the default browser for
+     * @param callback Invoked after the default home has been set
+     */
+    public abstract void setDefaultHome(@Nullable String packageName, @UserIdInt int userId,
+            @NonNull Consumer<Boolean> callback);
+
+    /**
+     * Returns the default browser package name for the given user.
+     */
+    @Nullable
+    public abstract String getDefaultBrowser(@UserIdInt int userId);
+
+    /**
+     * Returns the default dialer package name for the given user.
+     */
+    @Nullable
+    public abstract String getDefaultDialer(@UserIdInt int userId);
+
+    /**
+     * Returns the default home package name for the given user.
+     */
+    @Nullable
+    public abstract String getDefaultHome(@UserIdInt int userId);
+
+    /**
+     * Requests granting of the default permissions to the current default Use Open Wifi app.
+     * @param packageName The default use open wifi package name.
+     * @param userId The user for which to grant the permissions.
+     */
+    public abstract void grantDefaultPermissionsToDefaultSimCallManager(
+            @NonNull String packageName, @UserIdInt int userId);
+
+    /**
+     * Requests granting of the default permissions to the current default Use Open Wifi app.
+     * @param packageName The default use open wifi package name.
+     * @param userId The user for which to grant the permissions.
+     */
+    public abstract void grantDefaultPermissionsToDefaultUseOpenWifiApp(
+            @NonNull String packageName, @UserIdInt int userId);
+
+    /**
+     * Returns whether or not default permission grants have been performed for the given
+     * user since the device booted.
+     */
+    public abstract boolean wereDefaultPermissionsGrantedSinceBoot(@UserIdInt int userId);
+
+    /** Called when a new user has been created. */
+    public abstract void onNewUserCreated(@UserIdInt int userId);
 }
diff --git a/services/core/java/com/android/server/pm/permission/TEST_MAPPING b/services/core/java/com/android/server/pm/permission/TEST_MAPPING
index ee7a098..af94e44 100644
--- a/services/core/java/com/android/server/pm/permission/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/permission/TEST_MAPPING
@@ -14,9 +14,6 @@
                 },
                 {
                     "include-filter": "android.permission.cts.SharedUidPermissionsTest"
-                },
-                {
-                    "include-filter": "android.permission.cts.PermissionUpdateListenerTest"
                 }
             ]
         },
@@ -56,6 +53,14 @@
                     "include-filter": "android.appsecurity.cts.AppSecurityTests#testPermissionDiffCert"
                 }
             ]
+        },
+        {
+            "name": "CtsPermissionTestCases",
+            "options": [
+                {
+                    "include-filter": "android.permission.cts.PermissionUpdateListenerTest"
+                }
+            ]
         }
     ]
 }
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index a569bff..8da7f7b 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -260,9 +260,11 @@
     private void grantOrUpgradeDefaultRuntimePermissionsIfNeeded(@UserIdInt int userId) {
         if (DEBUG) Slog.i(LOG_TAG, "grantOrUpgradeDefaultPermsIfNeeded(" + userId + ")");
 
-        final PackageManagerInternal packageManagerInternal = LocalServices.getService(
-                PackageManagerInternal.class);
-        if (packageManagerInternal.wereDefaultPermissionsGrantedSinceBoot(userId)) {
+        final PackageManagerInternal packageManagerInternal =
+                LocalServices.getService(PackageManagerInternal.class);
+        final PermissionManagerServiceInternal permissionManagerInternal =
+                LocalServices.getService(PermissionManagerServiceInternal.class);
+        if (permissionManagerInternal.wereDefaultPermissionsGrantedSinceBoot(userId)) {
             if (DEBUG) Slog.i(LOG_TAG, "defaultPermsWereGrantedSinceBoot(" + userId + ")");
 
             // Now call into the permission controller to apply policy around permissions
diff --git a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
index d53f685..c1a6dbd 100644
--- a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
+++ b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
@@ -28,11 +28,14 @@
 import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
 
+import static java.lang.Integer.min;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.os.Build;
 import android.os.UserHandle;
 
@@ -73,6 +76,41 @@
             };
 
     /**
+     * TargetSDK is per package. To make sure two apps int the same shared UID do not fight over
+     * what to set, always compute the combined targetSDK.
+     *
+     * @param context A context
+     * @param appInfo The app that is changed
+     * @param user The user the app belongs to
+     *
+     * @return The minimum targetSDK of all apps sharing the uid of the app
+     */
+    private static int getMinimumTargetSDK(@NonNull Context context,
+            @NonNull ApplicationInfo appInfo, @NonNull UserHandle user) {
+        PackageManager pm = context.getPackageManager();
+
+        int minimumTargetSDK = appInfo.targetSdkVersion;
+
+        String[] uidPkgs = pm.getPackagesForUid(appInfo.uid);
+        if (uidPkgs != null) {
+            for (String uidPkg : uidPkgs) {
+                if (!uidPkg.equals(appInfo.packageName)) {
+                    ApplicationInfo uidPkgInfo;
+                    try {
+                        uidPkgInfo = pm.getApplicationInfoAsUser(uidPkg, 0, user);
+                    } catch (PackageManager.NameNotFoundException e) {
+                        continue;
+                    }
+
+                    minimumTargetSDK = min(minimumTargetSDK, uidPkgInfo.targetSdkVersion);
+                }
+            }
+        }
+
+        return minimumTargetSDK;
+    }
+
+    /**
      * Get the policy for a soft restricted permission.
      *
      * @param context A context to use
@@ -99,12 +137,36 @@
                 final int targetSDK;
 
                 if (appInfo != null) {
-                    flags = context.getPackageManager().getPermissionFlags(permission,
-                            appInfo.packageName, user);
+                    PackageManager pm = context.getPackageManager();
+                    flags = pm.getPermissionFlags(permission, appInfo.packageName, user);
                     applyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
                     isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
-                    hasRequestedLegacyExternalStorage = appInfo.hasRequestedLegacyExternalStorage();
-                    targetSDK = appInfo.targetSdkVersion;
+                    targetSDK = getMinimumTargetSDK(context, appInfo, user);
+
+                    boolean hasAnyRequestedLegacyExternalStorage =
+                            appInfo.hasRequestedLegacyExternalStorage();
+
+                    // hasRequestedLegacyExternalStorage is per package. To make sure two apps in
+                    // the same shared UID do not fight over what to set, always compute the
+                    // combined hasRequestedLegacyExternalStorage
+                    String[] uidPkgs = pm.getPackagesForUid(appInfo.uid);
+                    if (uidPkgs != null) {
+                        for (String uidPkg : uidPkgs) {
+                            if (!uidPkg.equals(appInfo.packageName)) {
+                                ApplicationInfo uidPkgInfo;
+                                try {
+                                    uidPkgInfo = pm.getApplicationInfoAsUser(uidPkg, 0, user);
+                                } catch (PackageManager.NameNotFoundException e) {
+                                    continue;
+                                }
+
+                                hasAnyRequestedLegacyExternalStorage |=
+                                        uidPkgInfo.hasRequestedLegacyExternalStorage();
+                            }
+                        }
+                    }
+
+                    hasRequestedLegacyExternalStorage = hasAnyRequestedLegacyExternalStorage;
                 } else {
                     flags = 0;
                     applyRestriction = false;
@@ -155,7 +217,7 @@
                     final int flags = context.getPackageManager().getPermissionFlags(permission,
                             appInfo.packageName, user);
                     isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
-                    targetSDK = appInfo.targetSdkVersion;
+                    targetSDK = getMinimumTargetSDK(context, appInfo, user);
                 } else {
                     isWhiteListed = false;
                     targetSDK = 0;
diff --git a/services/core/java/com/android/server/policy/TEST_MAPPING b/services/core/java/com/android/server/policy/TEST_MAPPING
index 9f64039..484017b 100644
--- a/services/core/java/com/android/server/policy/TEST_MAPPING
+++ b/services/core/java/com/android/server/policy/TEST_MAPPING
@@ -33,6 +33,9 @@
       "options": [
         {
           "include-filter": "android.permission2.cts.RestrictedPermissionsTest"
+        },
+        {
+          "include-filter": "android.permission2.cts.RestrictedStoragePermissionSharedUidTest"
         }
       ]
     },
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index b503ce8..1948b20 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -76,6 +76,7 @@
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import java.io.ByteArrayOutputStream;
 import java.io.FileDescriptor;
@@ -166,11 +167,11 @@
 
         LocalServices.addService(RoleManagerInternal.class, new Internal());
 
-        PackageManagerInternal packageManagerInternal = LocalServices.getService(
-                PackageManagerInternal.class);
-        packageManagerInternal.setDefaultBrowserProvider(new DefaultBrowserProvider());
-        packageManagerInternal.setDefaultDialerProvider(new DefaultDialerProvider());
-        packageManagerInternal.setDefaultHomeProvider(new DefaultHomeProvider());
+        PermissionManagerServiceInternal permissionManagerInternal =
+                LocalServices.getService(PermissionManagerServiceInternal.class);
+        permissionManagerInternal.setDefaultBrowserProvider(new DefaultBrowserProvider());
+        permissionManagerInternal.setDefaultDialerProvider(new DefaultDialerProvider());
+        permissionManagerInternal.setDefaultHomeProvider(new DefaultHomeProvider());
 
         registerUserRemovedReceiver();
     }
@@ -755,7 +756,8 @@
         }
     }
 
-    private class DefaultBrowserProvider implements PackageManagerInternal.DefaultBrowserProvider {
+    private class DefaultBrowserProvider implements
+            PermissionManagerServiceInternal.DefaultBrowserProvider {
 
         @Nullable
         @Override
@@ -809,7 +811,8 @@
         }
     }
 
-    private class DefaultDialerProvider implements PackageManagerInternal.DefaultDialerProvider {
+    private class DefaultDialerProvider implements
+            PermissionManagerServiceInternal.DefaultDialerProvider {
 
         @Nullable
         @Override
@@ -819,7 +822,8 @@
         }
     }
 
-    private class DefaultHomeProvider implements PackageManagerInternal.DefaultHomeProvider {
+    private class DefaultHomeProvider implements
+            PermissionManagerServiceInternal.DefaultHomeProvider {
 
         @Nullable
         @Override
diff --git a/services/core/java/com/android/server/telecom/TelecomLoaderService.java b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
index 54369ca..a853529 100644
--- a/services/core/java/com/android/server/telecom/TelecomLoaderService.java
+++ b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
@@ -39,7 +39,6 @@
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.pm.UserManagerService;
-import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
 import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 /**
@@ -66,9 +65,9 @@
                 ServiceManager.addService(Context.TELECOM_SERVICE, service);
 
                 synchronized (mLock) {
+                    final PermissionManagerServiceInternal permissionManager =
+                            LocalServices.getService(PermissionManagerServiceInternal.class);
                     if (mDefaultSimCallManagerRequests != null) {
-                        final DefaultPermissionGrantPolicy permissionPolicy =
-                                getDefaultPermissionGrantPolicy();
                         if (mDefaultSimCallManagerRequests != null) {
                             TelecomManager telecomManager =
                                 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
@@ -80,7 +79,7 @@
                                 for (int i = requestCount - 1; i >= 0; i--) {
                                     final int userId = mDefaultSimCallManagerRequests.get(i);
                                     mDefaultSimCallManagerRequests.remove(i);
-                                    permissionPolicy
+                                    permissionManager
                                             .grantDefaultPermissionsToDefaultSimCallManager(
                                                     packageName, userId);
                                 }
@@ -99,11 +98,6 @@
         }
     }
 
-    private DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
-        return LocalServices.getService(PermissionManagerServiceInternal.class)
-                .getDefaultPermissionGrantPolicy();
-    }
-
     private static final ComponentName SERVICE_COMPONENT = new ComponentName(
             "com.android.server.telecom",
             "com.android.server.telecom.components.TelecomService");
@@ -162,10 +156,11 @@
 
 
     private void registerDefaultAppProviders() {
-        final DefaultPermissionGrantPolicy permissionPolicy = getDefaultPermissionGrantPolicy();
+        final PermissionManagerServiceInternal permissionManager =
+                LocalServices.getService(PermissionManagerServiceInternal.class);
 
         // Set a callback for the permission grant policy to query the default sms app.
-        permissionPolicy.setSmsAppPackagesProvider(userId -> {
+        permissionManager.setSmsAppPackagesProvider(userId -> {
             synchronized (mLock) {
                 if (mServiceConnection == null) {
                     return null;
@@ -180,7 +175,7 @@
         });
 
         // Set a callback for the permission grant policy to query the default dialer app.
-        permissionPolicy.setDialerAppPackagesProvider(userId -> {
+        permissionManager.setDialerAppPackagesProvider(userId -> {
             synchronized (mLock) {
                 if (mServiceConnection == null) {
                     return null;
@@ -194,7 +189,7 @@
         });
 
         // Set a callback for the permission grant policy to query the default sim call manager.
-        permissionPolicy.setSimCallManagerPackagesProvider(userId -> {
+        permissionManager.setSimCallManagerPackagesProvider(userId -> {
             synchronized (mLock) {
                 if (mServiceConnection == null) {
                     if (mDefaultSimCallManagerRequests == null) {
@@ -215,12 +210,11 @@
     }
 
     private void registerDefaultAppNotifier() {
-        final DefaultPermissionGrantPolicy permissionPolicy = getDefaultPermissionGrantPolicy();
         // Notify the package manager on default app changes
         final RoleManager roleManager = mContext.getSystemService(RoleManager.class);
         roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(),
-                (roleName, user) -> updateSimCallManagerPermissions(permissionPolicy,
-                        user.getIdentifier()), UserHandle.ALL);
+                (roleName, user) -> updateSimCallManagerPermissions(user.getIdentifier()),
+                UserHandle.ALL);
     }
 
 
@@ -230,7 +224,7 @@
             public void onReceive(Context context, Intent intent) {
                 if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
                     for (int userId : UserManagerService.getInstance().getUserIds()) {
-                        updateSimCallManagerPermissions(getDefaultPermissionGrantPolicy(), userId);
+                        updateSimCallManagerPermissions(userId);
                     }
                 }
             }
@@ -240,16 +234,16 @@
             new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED), null, null);
     }
 
-    private void updateSimCallManagerPermissions(
-            DefaultPermissionGrantPolicy permissionGrantPolicy, int userId) {
+    private void updateSimCallManagerPermissions(int userId) {
+        final PermissionManagerServiceInternal permissionManager =
+                LocalServices.getService(PermissionManagerServiceInternal.class);
         TelecomManager telecomManager =
             (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
         PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId);
         if (phoneAccount != null) {
             Slog.i(TAG, "updating sim call manager permissions for userId:" + userId);
             String packageName = phoneAccount.getComponentName().getPackageName();
-            permissionGrantPolicy.grantDefaultPermissionsToDefaultSimCallManager(
-                packageName, userId);
+            permissionManager.grantDefaultPermissionsToDefaultSimCallManager(packageName, userId);
         }
     }
 }
diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
index 55f062b..b2f1153 100644
--- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java
+++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
@@ -949,7 +949,25 @@
             return false;
         }
 
-        return readMet && writeMet;
+        // If this provider says that grants are always required, we need to
+        // consult it directly to determine if the UID has permission
+        final boolean forceMet;
+        if (pi.forceUriPermissions) {
+            final int providerUserId = UserHandle.getUserId(pi.applicationInfo.uid);
+            final int clientUserId = UserHandle.getUserId(uid);
+            if (providerUserId == clientUserId) {
+                forceMet = (mAmInternal.checkContentProviderUriPermission(grantUri.uri,
+                        providerUserId, uid, modeFlags) == PackageManager.PERMISSION_GRANTED);
+            } else {
+                // The provider can't track cross-user permissions, so we have
+                // to assume they're always denied
+                forceMet = false;
+            }
+        } else {
+            forceMet = true;
+        }
+
+        return readMet && writeMet && forceMet;
     }
 
     private void removeUriPermissionIfNeeded(UriPermission perm) {
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index bace7e3..8abfde2 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -22,6 +22,7 @@
 
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.utils.RegionUtils.forEachRect;
 
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
@@ -1126,14 +1127,13 @@
                 // Iterate until we figure out what is touchable for the entire screen.
                 for (int i = visibleWindowCount - 1; i >= 0; i--) {
                     final WindowState windowState = visibleWindows.valueAt(i);
+                    final Region regionInScreen = new Region();
+                    computeWindowRegionInScreen(windowState, regionInScreen);
 
-                    final Rect boundsInScreen = mTempRect;
-                    computeWindowBoundsInScreen(windowState, boundsInScreen);
-
-                    if (windowMattersToAccessibility(windowState, boundsInScreen, unaccountedSpace,
+                    if (windowMattersToAccessibility(windowState, regionInScreen, unaccountedSpace,
                             skipRemainingWindowsForTasks)) {
-                        addPopulatedWindowInfo(windowState, boundsInScreen, windows, addedWindows);
-                        updateUnaccountedSpace(windowState, boundsInScreen, unaccountedSpace,
+                        addPopulatedWindowInfo(windowState, regionInScreen, windows, addedWindows);
+                        updateUnaccountedSpace(windowState, regionInScreen, unaccountedSpace,
                                 skipRemainingWindowsForTasks);
                         focusedWindowAdded |= windowState.isFocused();
                     }
@@ -1171,8 +1171,9 @@
             clearAndRecycleWindows(windows);
         }
 
-        private boolean windowMattersToAccessibility(WindowState windowState, Rect boundsInScreen,
-                Region unaccountedSpace, HashSet<Integer> skipRemainingWindowsForTasks) {
+        private boolean windowMattersToAccessibility(WindowState windowState,
+                Region regionInScreen, Region unaccountedSpace,
+                HashSet<Integer> skipRemainingWindowsForTasks) {
             if (windowState.isFocused()) {
                 return true;
             }
@@ -1192,7 +1193,7 @@
             }
 
             // If the window is completely covered by other windows - ignore.
-            if (unaccountedSpace.quickReject(boundsInScreen)) {
+            if (unaccountedSpace.quickReject(regionInScreen)) {
                 return false;
             }
 
@@ -1204,7 +1205,7 @@
             return false;
         }
 
-        private void updateUnaccountedSpace(WindowState windowState, Rect boundsInScreen,
+        private void updateUnaccountedSpace(WindowState windowState, Region regionInScreen,
                 Region unaccountedSpace, HashSet<Integer> skipRemainingWindowsForTasks) {
             if (windowState.mAttrs.type
                     != WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY) {
@@ -1212,59 +1213,71 @@
                 // Account for the space this window takes if the window
                 // is not an accessibility overlay which does not change
                 // the reported windows.
-                unaccountedSpace.op(boundsInScreen, unaccountedSpace,
+                unaccountedSpace.op(regionInScreen, unaccountedSpace,
                         Region.Op.REVERSE_DIFFERENCE);
 
                 // If a window is modal it prevents other windows from being touched
                 if ((windowState.mAttrs.flags & (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                         | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL)) == 0) {
-                    // Account for all space in the task, whether the windows in it are
-                    // touchable or not. The modal window blocks all touches from the task's
-                    // area.
-                    unaccountedSpace.op(windowState.getDisplayFrameLw(), unaccountedSpace,
-                            Region.Op.REVERSE_DIFFERENCE);
+                    if (!windowState.hasTapExcludeRegion()) {
+                        // Account for all space in the task, whether the windows in it are
+                        // touchable or not. The modal window blocks all touches from the task's
+                        // area.
+                        unaccountedSpace.op(windowState.getDisplayFrameLw(), unaccountedSpace,
+                                Region.Op.REVERSE_DIFFERENCE);
+                    } else {
+                        // If a window has tap exclude region, we need to account it.
+                        final Region displayRegion = new Region(windowState.getDisplayFrameLw());
+                        final Region tapExcludeRegion = new Region();
+                        windowState.amendTapExcludeRegion(tapExcludeRegion);
+                        displayRegion.op(tapExcludeRegion, displayRegion,
+                                Region.Op.REVERSE_DIFFERENCE);
+                        unaccountedSpace.op(displayRegion, unaccountedSpace,
+                                Region.Op.REVERSE_DIFFERENCE);
+                    }
 
                     final Task task = windowState.getTask();
                     if (task != null) {
                         // If the window is associated with a particular task, we can skip the
                         // rest of the windows for that task.
                         skipRemainingWindowsForTasks.add(task.mTaskId);
-                    } else {
+                    } else if (!windowState.hasTapExcludeRegion()) {
                         // If the window is not associated with a particular task, then it is
-                        // globally modal. In this case we can skip all remaining windows.
+                        // globally modal. In this case we can skip all remaining windows when
+                        // it doesn't has tap exclude region.
                         unaccountedSpace.setEmpty();
                     }
                 }
             }
         }
 
-        private void computeWindowBoundsInScreen(WindowState windowState, Rect outBounds) {
+        private void computeWindowRegionInScreen(WindowState windowState, Region outRegion) {
             // Get the touchable frame.
             Region touchableRegion = mTempRegion1;
             windowState.getTouchableRegion(touchableRegion);
-            Rect touchableFrame = mTempRect;
-            touchableRegion.getBounds(touchableFrame);
-
-            // Move to origin as all transforms are captured by the matrix.
-            RectF windowFrame = mTempRectF;
-            windowFrame.set(touchableFrame);
-            windowFrame.offset(-windowState.getFrameLw().left, -windowState.getFrameLw().top);
 
             // Map the frame to get what appears on the screen.
             Matrix matrix = mTempMatrix;
             populateTransformationMatrixLocked(windowState, matrix);
-            matrix.mapRect(windowFrame);
 
-            // Got the bounds.
-            outBounds.set((int) windowFrame.left, (int) windowFrame.top,
-                    (int) windowFrame.right, (int) windowFrame.bottom);
+            forEachRect(touchableRegion, rect -> {
+                // Move to origin as all transforms are captured by the matrix.
+                RectF windowFrame = mTempRectF;
+                windowFrame.set(rect);
+                windowFrame.offset(-windowState.getFrameLw().left, -windowState.getFrameLw().top);
+
+                matrix.mapRect(windowFrame);
+
+                // Union all rects.
+                outRegion.union(new Rect((int) windowFrame.left, (int) windowFrame.top,
+                        (int) windowFrame.right, (int) windowFrame.bottom));
+            });
         }
 
-        private static void addPopulatedWindowInfo(
-                WindowState windowState, Rect boundsInScreen,
+        private static void addPopulatedWindowInfo(WindowState windowState, Region regionInScreen,
                 List<WindowInfo> out, Set<IBinder> tokenOut) {
             final WindowInfo window = windowState.getWindowInfo();
-            window.boundsInScreen.set(boundsInScreen);
+            window.regionInScreen.set(regionInScreen);
             window.layer = tokenOut.size();
             out.add(window);
             tokenOut.add(window.token);
@@ -1293,7 +1306,7 @@
         private void populateVisibleWindowsOnScreenLocked(SparseArray<WindowState> outWindows) {
             final List<WindowState> tempWindowStatesList = new ArrayList<>();
             final DisplayContent dc = mService.getDefaultDisplayContentLocked();
-            dc.forAllWindows((w) -> {
+            dc.forAllWindows(w -> {
                 if (w.isVisibleLw()) {
                     tempWindowStatesList.add(w);
                 }
@@ -1306,17 +1319,11 @@
                     return;
                 }
 
-                // TODO: Use Region instead to get rid of this complicated logic.
-                // Check the tap exclude region of the parent window. If the tap exclude region
-                // is empty, it means there is another can-receive-pointer-event view on top of
-                // the region. Hence, we don't count the window as visible.
                 if (w.isVisibleLw() && parentWindow.getDisplayContent().isDefaultDisplay
-                        && parentWindow.hasTapExcludeRegion()
                         && tempWindowStatesList.contains(parentWindow)) {
-                    tempWindowStatesList.add(
-                            tempWindowStatesList.lastIndexOf(parentWindow) + 1, w);
+                    tempWindowStatesList.add(tempWindowStatesList.lastIndexOf(parentWindow), w);
                 }
-            }, true /* traverseTopToBottom */);
+            }, false /* traverseTopToBottom */);
             for (int i = 0; i < tempWindowStatesList.size(); i++) {
                 outWindows.put(i, tempWindowStatesList.get(i));
             }
diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java
index fe4811d..cd72824 100644
--- a/services/core/java/com/android/server/wm/ActivityDisplay.java
+++ b/services/core/java/com/android/server/wm/ActivityDisplay.java
@@ -174,6 +174,7 @@
         mDisplayId = display.getDisplayId();
         mDisplay = display;
         mDisplayContent = createDisplayContent();
+        mDisplayContent.reconfigureDisplayLocked();
         updateBounds();
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 9c87ce8..99d2903 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -916,8 +916,9 @@
         return ResolverActivity.class.getName().equals(className);
     }
 
-    boolean isResolverActivity() {
-        return isResolverActivity(mActivityComponent.getClassName());
+    boolean isResolverOrDelegateActivity() {
+        return isResolverActivity(mActivityComponent.getClassName()) || Objects.equals(
+                mActivityComponent, mAtmService.mStackSupervisor.getSystemChooserActivity());
     }
 
     boolean isResolverOrChildActivity() {
@@ -1247,7 +1248,8 @@
                 && intent.getType() == null;
     }
 
-    private boolean canLaunchHomeActivity(int uid, ActivityRecord sourceRecord) {
+    @VisibleForTesting
+    boolean canLaunchHomeActivity(int uid, ActivityRecord sourceRecord) {
         if (uid == Process.myUid() || uid == 0) {
             // System process can launch home activity.
             return true;
@@ -1257,8 +1259,8 @@
         if (recentTasks != null && recentTasks.isCallerRecents(uid)) {
             return true;
         }
-        // Resolver activity can launch home activity.
-        return sourceRecord != null && sourceRecord.isResolverActivity();
+        // Resolver or system chooser activity can launch home activity.
+        return sourceRecord != null && sourceRecord.isResolverOrDelegateActivity();
     }
 
     /**
@@ -1277,7 +1279,7 @@
             ActivityOptions options, ActivityRecord sourceRecord) {
         int activityType = ACTIVITY_TYPE_UNDEFINED;
         if ((!componentSpecified || canLaunchHomeActivity(launchedFromUid, sourceRecord))
-                && isHomeIntent(intent) && !isResolverActivity()) {
+                && isHomeIntent(intent) && !isResolverOrDelegateActivity()) {
             // This sure looks like a home activity!
             activityType = ACTIVITY_TYPE_HOME;
 
@@ -1523,7 +1525,6 @@
         stack.moveToFront(reason, task);
         // Report top activity change to tracking services and WM
         if (mRootActivityContainer.getTopResumedActivity() == this) {
-            // TODO(b/111361570): Support multiple focused apps in WM
             mAtmService.setResumedActivityUncheckLocked(this, reason);
         }
         return true;
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 18a57ae..79098f1 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -565,7 +565,6 @@
                     + reason);
             setResumedActivity(record, reason + " - onActivityStateChanged");
             if (record == mRootActivityContainer.getTopResumedActivity()) {
-                // TODO(b/111361570): Support multiple focused apps in WM
                 mService.setResumedActivityUncheckLocked(record, reason);
             }
             mStackSupervisor.mRecentTasks.add(record.getTaskRecord());
@@ -3711,9 +3710,6 @@
         if (nextFocusableStack != null) {
             final ActivityRecord top = nextFocusableStack.topRunningActivityLocked();
             if (top != null && top == mRootActivityContainer.getTopResumedActivity()) {
-                // TODO(b/111361570): Remove this and update focused app per-display in
-                // WindowManager every time an activity becomes resumed in
-                // ActivityTaskManagerService#setResumedActivityUncheckLocked().
                 mService.setResumedActivityUncheckLocked(top, reason);
             }
             return;
@@ -5651,7 +5647,6 @@
         // If the original state is resumed, there is no state change to update focused app.
         // So here makes sure the activity focus is set if it is the top.
         if (origState == RESUMED && r == mRootActivityContainer.getTopResumedActivity()) {
-            // TODO(b/111361570): Support multiple focused apps in WM
             mService.setResumedActivityUncheckLocked(r, reason);
         }
     }
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index feb4a36..eb170bd 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -130,6 +130,7 @@
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 
+import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.ReferrerIntent;
@@ -323,6 +324,12 @@
     boolean mUserLeaving = false;
 
     /**
+     * The system chooser activity which worked as a delegate of
+     * {@link com.android.internal.app.ResolverActivity}.
+     */
+    private ComponentName mSystemChooserActivity;
+
+    /**
      * We don't want to allow the device to go to sleep while in the process
      * of launching an activity.  This is primarily to allow alarm intent
      * receivers to launch an activity and get that to run before the device
@@ -469,6 +476,14 @@
         return mKeyguardController;
     }
 
+    ComponentName getSystemChooserActivity() {
+        if (mSystemChooserActivity == null) {
+            mSystemChooserActivity = ComponentName.unflattenFromString(
+                    mService.mContext.getResources().getString(R.string.config_chooserActivity));
+        }
+        return mSystemChooserActivity;
+    }
+
     void setRecentTasks(RecentTasks recentTasks) {
         mRecentTasks = recentTasks;
         mRecentTasks.registerCallback(this);
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 54eb07f..6fd2ebc 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1980,8 +1980,8 @@
             // Also put noDisplay activities in the source task. These by itself can be placed
             // in any task/stack, however it could launch other activities like ResolverActivity,
             // and we want those to stay in the original task.
-            if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
-                    && mSourceRecord.inFreeformWindowingMode())  {
+            if ((mStartActivity.isResolverOrDelegateActivity() || mStartActivity.noDisplay)
+                    && mSourceRecord != null && mSourceRecord.inFreeformWindowingMode()) {
                 mAddingToTask = true;
             }
         }
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 971a24d..c37ced5 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -4912,7 +4912,7 @@
     }
 
     void dumpActivityContainersLocked(PrintWriter pw) {
-        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
+        pw.println("ACTIVITY MANAGER CONTAINERS (dumpsys activity containers)");
         mRootActivityContainer.dumpChildrenNames(pw, " ");
         pw.println(" ");
     }
@@ -4928,6 +4928,9 @@
      *  - the cmd arg isn't the flattened component name of an existing activity:
      *    dump all activity whose component contains the cmd as a substring
      *  - A hex number of the ActivityRecord object instance.
+     * <p>
+     * The caller should not hold lock when calling this method because it will wait for the
+     * activities to complete the dump.
      *
      *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
      *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
@@ -4980,29 +4983,28 @@
     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
             final ActivityRecord r, String[] args, boolean dumpAll) {
         String innerPrefix = prefix + "  ";
+        IApplicationThread appThread = null;
         synchronized (mGlobalLock) {
             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
             pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
             pw.print(" pid=");
-            if (r.hasProcess()) pw.println(r.app.getPid());
-            else pw.println("(not running)");
+            if (r.hasProcess()) {
+                pw.println(r.app.getPid());
+                appThread = r.app.getThread();
+            } else {
+                pw.println("(not running)");
+            }
             if (dumpAll) {
                 r.dump(pw, innerPrefix);
             }
         }
-        if (r.attachedToProcess()) {
+        if (appThread != null) {
             // flush anything that is already in the PrintWriter since the thread is going
             // to write to the file descriptor directly
             pw.flush();
-            try {
-                TransferPipe tp = new TransferPipe();
-                try {
-                    r.app.getThread().dumpActivity(tp.getWriteFd(),
-                            r.appToken, innerPrefix, args);
-                    tp.go(fd);
-                } finally {
-                    tp.kill();
-                }
+            try (TransferPipe tp = new TransferPipe()) {
+                appThread.dumpActivity(tp.getWriteFd(), r.appToken, innerPrefix, args);
+                tp.go(fd);
             } catch (IOException e) {
                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
             } catch (RemoteException e) {
@@ -7063,10 +7065,8 @@
         public boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name,
                 String[] args, int opti, boolean dumpAll, boolean dumpVisibleStacksOnly,
                 boolean dumpFocusedStackOnly) {
-            synchronized (mGlobalLock) {
-                return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti,
-                        dumpAll, dumpVisibleStacksOnly, dumpFocusedStackOnly);
-            }
+            return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti, dumpAll,
+                    dumpVisibleStacksOnly, dumpFocusedStackOnly);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 8007c0f..d15081c 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -260,9 +260,9 @@
     ActivityRecord mActivityRecord;
 
     /**
-     * See {@link #canTurnScreenOn()}
+     * @see #currentLaunchCanTurnScreenOn()
      */
-    private boolean mCanTurnScreenOn = true;
+    private boolean mCurrentLaunchCanTurnScreenOn = true;
 
     /**
      * If we are running an animation, this determines the transition type. Must be one of
@@ -1002,7 +1002,7 @@
                 + " " + this);
         mAppStopped = false;
         // Allow the window to turn the screen on once the app is resumed again.
-        setCanTurnScreenOn(true);
+        setCurrentLaunchCanTurnScreenOn(true);
         if (!wasStopped) {
             destroySurfaces(true /*cleanupOnResume*/);
         }
@@ -2420,21 +2420,25 @@
     }
 
     /**
-     * Sets whether the current launch can turn the screen on. See {@link #canTurnScreenOn()}
+     * Sets whether the current launch can turn the screen on.
+     * @see #currentLaunchCanTurnScreenOn()
      */
-    void setCanTurnScreenOn(boolean canTurnScreenOn) {
-        mCanTurnScreenOn = canTurnScreenOn;
+    void setCurrentLaunchCanTurnScreenOn(boolean currentLaunchCanTurnScreenOn) {
+        mCurrentLaunchCanTurnScreenOn = currentLaunchCanTurnScreenOn;
     }
 
     /**
      * Indicates whether the current launch can turn the screen on. This is to prevent multiple
      * relayouts from turning the screen back on. The screen should only turn on at most
      * once per activity resume.
+     * <p>
+     * Note this flag is only meaningful when {@link WindowManager.LayoutParams#FLAG_TURN_SCREEN_ON}
+     * or {@link ActivityRecord#canTurnScreenOn} is set.
      *
-     * @return true if the screen can be turned on.
+     * @return {@code true} if the activity is ready to turn on the screen.
      */
-    boolean canTurnScreenOn() {
-        return mCanTurnScreenOn;
+    boolean currentLaunchCanTurnScreenOn() {
+        return mCurrentLaunchCanTurnScreenOn;
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index e2d5928..e29fbdf 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -122,7 +122,6 @@
 import static com.android.server.wm.WindowManagerService.H.REPORT_FOCUS_CHANGE;
 import static com.android.server.wm.WindowManagerService.H.REPORT_HARD_KEYBOARD_STATUS_CHANGE;
 import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
-import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
 import static com.android.server.wm.WindowManagerService.H.UPDATE_DOCKED_STACK_DIVIDER;
 import static com.android.server.wm.WindowManagerService.H.WINDOW_HIDE_TIMEOUT;
 import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
@@ -1212,27 +1211,45 @@
         }
     }
 
-    /** Notify the configuration change of this display. */
-    void postNewConfigurationToHandler() {
-        mWmService.mH.obtainMessage(SEND_NEW_CONFIGURATION, this).sendToTarget();
+    void reconfigureDisplayLocked() {
+        if (!isReady()) {
+            return;
+        }
+        configureDisplayPolicy();
+        setLayoutNeeded();
+
+        boolean configChanged = updateOrientationFromAppTokens();
+        final Configuration currentDisplayConfig = getConfiguration();
+        mTmpConfiguration.setTo(currentDisplayConfig);
+        computeScreenConfiguration(mTmpConfiguration);
+        configChanged |= currentDisplayConfig.diff(mTmpConfiguration) != 0;
+
+        if (configChanged) {
+            mWaitingForConfig = true;
+            mWmService.startFreezingDisplayLocked(0 /* exitAnim */, 0 /* enterAnim */, this);
+            sendNewConfiguration();
+        }
+
+        mWmService.mWindowPlacerLocked.performSurfacePlacement();
     }
 
     void sendNewConfiguration() {
-        synchronized (mWmService.mGlobalLock) {
-            final boolean configUpdated = mAcitvityDisplay
-                    .updateDisplayOverrideConfigurationLocked();
-            if (!configUpdated) {
-                // Something changed (E.g. device rotation), but no configuration update is needed.
-                // E.g. changing device rotation by 180 degrees. Go ahead and perform surface
-                // placement to unfreeze the display since we froze it when the rotation was updated
-                // in DisplayContent#updateRotationUnchecked.
-                if (mWaitingForConfig) {
-                    mWaitingForConfig = false;
-                    mWmService.mLastFinishedFreezeSource = "config-unchanged";
-                    setLayoutNeeded();
-                    mWmService.mWindowPlacerLocked.performSurfacePlacement();
-                }
-            }
+        if (!isReady() || mAcitvityDisplay == null) {
+            return;
+        }
+        final boolean configUpdated = mAcitvityDisplay.updateDisplayOverrideConfigurationLocked();
+        if (configUpdated) {
+            return;
+        }
+        // Something changed (E.g. device rotation), but no configuration update is needed.
+        // E.g. changing device rotation by 180 degrees. Go ahead and perform surface placement to
+        // unfreeze the display since we froze it when the rotation was updated in
+        // DisplayContent#updateRotationUnchecked.
+        if (mWaitingForConfig) {
+            mWaitingForConfig = false;
+            mWmService.mLastFinishedFreezeSource = "config-unchanged";
+            setLayoutNeeded();
+            mWmService.mWindowPlacerLocked.performSurfacePlacement();
         }
     }
 
@@ -1351,7 +1368,7 @@
     boolean updateRotationAndSendNewConfigIfNeeded() {
         final boolean changed = updateRotationUnchecked(false /* forceUpdate */);
         if (changed) {
-            postNewConfigurationToHandler();
+            sendNewConfiguration();
         }
         return changed;
     }
@@ -2292,7 +2309,7 @@
             mInitialDisplayHeight = newHeight;
             mInitialDisplayDensity = newDensity;
             mInitialDisplayCutout = newCutout;
-            mWmService.reconfigureDisplayLocked(this);
+            reconfigureDisplayLocked();
         }
     }
 
@@ -2345,7 +2362,7 @@
         final boolean updateCurrent = userId == UserHandle.USER_CURRENT;
         if (mWmService.mCurrentUserId == userId || updateCurrent) {
             mBaseDisplayDensity = density;
-            mWmService.reconfigureDisplayLocked(this);
+            reconfigureDisplayLocked();
         }
         if (updateCurrent) {
             // We are applying existing settings so no need to save it again.
@@ -2366,7 +2383,7 @@
 
         mDisplayScalingDisabled = (mode != FORCE_SCALING_MODE_AUTO);
         Slog.i(TAG_WM, "Using display scaling mode: " + (mDisplayScalingDisabled ? "off" : "auto"));
-        mWmService.reconfigureDisplayLocked(this);
+        reconfigureDisplayLocked();
 
         mWmService.mDisplayWindowSettings.setForcedScalingMode(this, mode);
     }
@@ -2385,7 +2402,7 @@
 
         Slog.i(TAG_WM, "Using new display size: " + width + "x" + height);
         updateBaseDisplayMetrics(width, height, mBaseDisplayDensity);
-        mWmService.reconfigureDisplayLocked(this);
+        reconfigureDisplayLocked();
 
         if (clear) {
             width = height = 0;
@@ -3730,7 +3747,7 @@
                 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
                 if (updateOrientationFromAppTokens()) {
                     setLayoutNeeded();
-                    postNewConfigurationToHandler();
+                    sendNewConfiguration();
                 }
             }
 
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index cf87203..1576873 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -284,6 +284,8 @@
     /** See {@link #getNavigationBarFrameHeight} */
     private int[] mNavigationBarFrameHeightForRotationDefault = new int[4];
 
+    private boolean mIsFreeformWindowOverlappingWithNavBar;
+
     /** Cached value of {@link ScreenShapeHelper#getWindowOutsetBottomPx} */
     @Px private int mWindowOutsetBottom;
 
@@ -877,27 +879,24 @@
     }
 
     /**
-     * Preflight adding a window to the system.
+     * Check if a window can be added to the system.
      *
-     * Currently enforces that three window types are singletons per display:
+     * Currently enforces that two window types are singletons per display:
      * <ul>
      * <li>{@link WindowManager.LayoutParams#TYPE_STATUS_BAR}</li>
      * <li>{@link WindowManager.LayoutParams#TYPE_NAVIGATION_BAR}</li>
      * </ul>
      *
-     * @param win The window to be added
-     * @param attrs Information about the window to be added
+     * @param attrs Information about the window to be added.
      *
      * @return If ok, WindowManagerImpl.ADD_OKAY.  If too many singletons,
      * WindowManagerImpl.ADD_MULTIPLE_SINGLETON
      */
-    public int prepareAddWindowLw(WindowState win, WindowManager.LayoutParams attrs) {
-
+    int validateAddingWindowLw(WindowManager.LayoutParams attrs) {
         if ((attrs.privateFlags & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.STATUS_BAR_SERVICE,
                     "DisplayPolicy");
-            mScreenDecorWindows.add(win);
         }
 
         switch (attrs.type) {
@@ -910,6 +909,42 @@
                         return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
                     }
                 }
+                break;
+            case TYPE_NAVIGATION_BAR:
+                mContext.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.STATUS_BAR_SERVICE,
+                        "DisplayPolicy");
+                if (mNavigationBar != null) {
+                    if (mNavigationBar.isAlive()) {
+                        return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
+                    }
+                }
+                break;
+            case TYPE_NAVIGATION_BAR_PANEL:
+            case TYPE_STATUS_BAR_PANEL:
+            case TYPE_STATUS_BAR_SUB_PANEL:
+            case TYPE_VOICE_INTERACTION_STARTING:
+                mContext.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.STATUS_BAR_SERVICE,
+                        "DisplayPolicy");
+                break;
+        }
+        return ADD_OKAY;
+    }
+
+    /**
+     * Called when a window is being added to the system.  Must not throw an exception.
+     *
+     * @param win The window being added.
+     * @param attrs Information about the window to be added.
+     */
+    void addWindowLw(WindowState win, WindowManager.LayoutParams attrs) {
+        if ((attrs.privateFlags & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0) {
+            mScreenDecorWindows.add(win);
+        }
+
+        switch (attrs.type) {
+            case TYPE_STATUS_BAR:
                 mStatusBar = win;
                 mStatusBarController.setWindow(win);
                 if (mDisplayContent.isDefaultDisplay) {
@@ -925,14 +960,6 @@
                 mDisplayContent.setInsetProvider(TYPE_TOP_TAPPABLE_ELEMENT, win, frameProvider);
                 break;
             case TYPE_NAVIGATION_BAR:
-                mContext.enforceCallingOrSelfPermission(
-                        android.Manifest.permission.STATUS_BAR_SERVICE,
-                        "DisplayPolicy");
-                if (mNavigationBar != null) {
-                    if (mNavigationBar.isAlive()) {
-                        return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
-                    }
-                }
                 mNavigationBar = win;
                 mNavigationBarController.setWindow(win);
                 mNavigationBarController.setOnBarVisibilityChangedListener(
@@ -966,16 +993,7 @@
                         });
                 if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
                 break;
-            case TYPE_NAVIGATION_BAR_PANEL:
-            case TYPE_STATUS_BAR_PANEL:
-            case TYPE_STATUS_BAR_SUB_PANEL:
-            case TYPE_VOICE_INTERACTION_STARTING:
-                mContext.enforceCallingOrSelfPermission(
-                        android.Manifest.permission.STATUS_BAR_SERVICE,
-                        "DisplayPolicy");
-                break;
         }
-        return ADD_OKAY;
     }
 
     /**
@@ -984,7 +1002,7 @@
      *
      * @param win The window being removed.
      */
-    public void removeWindowLw(WindowState win) {
+    void removeWindowLw(WindowState win) {
         if (mStatusBar == win) {
             mStatusBar = null;
             mStatusBarController.setWindow(null);
@@ -2379,6 +2397,7 @@
         mAllowLockscreenWhenOn = false;
         mShowingDream = false;
         mWindowSleepTokenNeeded = false;
+        mIsFreeformWindowOverlappingWithNavBar = false;
     }
 
     /**
@@ -2478,6 +2497,13 @@
             }
         }
 
+        // Check if the freeform window overlaps with the navigation bar area.
+        final WindowState navBarWin = hasNavigationBar() ? mNavigationBar : null;
+        if (!mIsFreeformWindowOverlappingWithNavBar && win.inFreeformWindowingMode()
+                && isOverlappingWithNavBar(win, navBarWin)) {
+            mIsFreeformWindowOverlappingWithNavBar = true;
+        }
+
         // Also keep track of any windows that are dimming but not necessarily fullscreen in the
         // docked stack.
         if (mTopDockedOpaqueOrDimmingWindowState == null && affectsSystemUi && win.isDimming()
@@ -3458,7 +3484,11 @@
             }
         } else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) {
             if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) {
-                visibility = setNavBarOpaqueFlag(visibility);
+                if (mIsFreeformWindowOverlappingWithNavBar) {
+                    visibility = setNavBarTranslucentFlag(visibility);
+                } else {
+                    visibility = setNavBarOpaqueFlag(visibility);
+                }
             } else if (fullscreenDrawsBackground) {
                 visibility = setNavBarTransparentFlag(visibility);
             }
@@ -3747,4 +3777,14 @@
         wm.removeView(mPointerLocationView);
         mPointerLocationView = null;
     }
+
+    @VisibleForTesting
+    static boolean isOverlappingWithNavBar(WindowState targetWindow, WindowState navBarWindow) {
+        if (navBarWindow == null || !navBarWindow.isVisibleLw()
+                || targetWindow.mAppToken == null || !targetWindow.isVisibleLw()) {
+            return false;
+        }
+
+        return Rect.intersects(targetWindow.getFrameLw(), navBarWindow.getFrameLw());
+    }
 }
diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java
index b16d956..6830ade 100644
--- a/services/core/java/com/android/server/wm/InputManagerCallback.java
+++ b/services/core/java/com/android/server/wm/InputManagerCallback.java
@@ -133,7 +133,10 @@
     @Override
     public void notifyConfigurationChanged() {
         // TODO(multi-display): Notify proper displays that are associated with this input device.
-        mService.mRoot.getDisplayContent(DEFAULT_DISPLAY).sendNewConfiguration();
+
+        synchronized (mService.mGlobalLock) {
+            mService.getDefaultDisplayContentLocked().sendNewConfiguration();
+        }
 
         synchronized (mInputDevicesReadyMonitor) {
             if (!mInputDevicesReady) {
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index ca4749f..422b6e5 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -43,11 +43,13 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.Trace;
+import android.util.EventLog;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.policy.IKeyguardDismissCallback;
+import com.android.server.am.EventLogTags;
 import com.android.server.policy.WindowManagerPolicy;
 import com.android.server.wm.ActivityTaskManagerInternal.SleepToken;
 
@@ -142,6 +144,11 @@
         if (!keyguardChanged && !aodChanged) {
             return;
         }
+        EventLog.writeEvent(EventLogTags.AM_SET_KEYGUARD_SHOWN,
+                keyguardShowing ? 1 : 0,
+                aodShowing ? 1 : 0,
+                mKeyguardGoingAway ? 1 : 0,
+                "setKeyguardShown");
         mKeyguardShowing = keyguardShowing;
         mAodShowing = aodShowing;
         mWindowManager.setAodShowing(aodShowing);
@@ -178,6 +185,11 @@
         mWindowManager.deferSurfaceLayout();
         try {
             setKeyguardGoingAway(true);
+            EventLog.writeEvent(EventLogTags.AM_SET_KEYGUARD_SHOWN,
+                    1 /* keyguardShowing */,
+                    mAodShowing ? 1 : 0,
+                    1 /* keyguardGoingAway */,
+                    "keyguardGoingAway");
             mRootActivityContainer.getDefaultDisplay().mDisplayContent
                     .prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY,
                             false /* alwaysKeepCurrent */, convertTransitFlags(flags),
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 8a5f52f..a00bee0 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -248,8 +248,6 @@
             dc.configureDisplayPolicy();
         }
 
-        mWmService.reconfigureDisplayLocked(dc);
-
         return dc;
     }
 
@@ -267,7 +265,7 @@
             }
 
             displayContent.initializeDisplayOverrideConfiguration();
-            mWmService.reconfigureDisplayLocked(displayContent);
+            displayContent.reconfigureDisplayLocked();
 
             // We need to update global configuration as well if config of default display has
             // changed. Do it inline because ATMS#retrieveSettings() will soon update the
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index bd114d9..f9a6fe7 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -310,6 +310,7 @@
         }
         final boolean isWindowTranslucent = mainWindow.getAttrs().format != PixelFormat.OPAQUE;
         return new TaskSnapshot(
+                System.currentTimeMillis() /* id */,
                 appWindowToken.mActivityComponent, screenshotBuffer.getGraphicBuffer(),
                 screenshotBuffer.getColorSpace(),
                 appWindowToken.getTask().getConfiguration().orientation,
@@ -404,7 +405,9 @@
 
         // Note, the app theme snapshot is never translucent because we enforce a non-translucent
         // color above
-        return new TaskSnapshot(topChild.mActivityComponent, hwBitmap.createGraphicBufferHandle(),
+        return new TaskSnapshot(
+                System.currentTimeMillis() /* id */,
+                topChild.mActivityComponent, hwBitmap.createGraphicBufferHandle(),
                 hwBitmap.getColorSpace(), topChild.getTask().getConfiguration().orientation,
                 getInsets(mainWindow), ActivityManager.isLowRamDeviceStatic() /* reduced */,
                 mFullSnapshotScale, false /* isRealSnapshot */, task.getWindowingMode(),
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotLoader.java b/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
index fcd97c1..696e1c3 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
@@ -92,7 +92,7 @@
             // For legacy snapshots, restore the scale based on the reduced resolution state
             final float legacyScale = reducedResolution ? mPersister.getReducedScale() : 1f;
             final float scale = Float.compare(proto.scale, 0f) != 0 ? proto.scale : legacyScale;
-            return new TaskSnapshot(topActivityComponent, buffer, bitmap.getColorSpace(),
+            return new TaskSnapshot(proto.id, topActivityComponent, buffer, bitmap.getColorSpace(),
                     proto.orientation,
                     new Rect(proto.insetLeft, proto.insetTop, proto.insetRight, proto.insetBottom),
                     reducedResolution, scale, proto.isRealSnapshot, proto.windowingMode,
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index 72fc189..32a1d90 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -343,6 +343,7 @@
             proto.isTranslucent = mSnapshot.isTranslucent();
             proto.topActivityComponent = mSnapshot.getTopActivityComponent().flattenToString();
             proto.scale = mSnapshot.getScale();
+            proto.id = mSnapshot.getId();
             final byte[] bytes = TaskSnapshotProto.toByteArray(proto);
             final File file = getProtoFile(mTaskId, mUserId);
             final AtomicFile atomicFile = new AtomicFile(file);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index f52bde9..11d7fb7 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -79,7 +79,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
@@ -1432,7 +1431,7 @@
                     Binder.getCallingUid());
             win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
 
-            res = displayPolicy.prepareAddWindowLw(win, attrs);
+            res = displayPolicy.validateAddingWindowLw(attrs);
             if (res != WindowManagerGlobal.ADD_OKAY) {
                 return res;
             }
@@ -1508,6 +1507,7 @@
             boolean imMayMove = true;
 
             win.mToken.addWindow(win);
+            displayPolicy.addWindowLw(win, attrs);
             if (type == TYPE_INPUT_METHOD) {
                 displayContent.setInputMethodWindowLocked(win);
                 imMayMove = false;
@@ -1651,6 +1651,7 @@
 
             if (display != null) {
                 displayContent = mRoot.createDisplayContent(display, null /* activityDisplay */);
+                displayContent.reconfigureDisplayLocked();
             }
         }
 
@@ -3751,7 +3752,7 @@
                         layoutNeeded = true;
                     }
                     if (rotationChanged || alwaysSendConfiguration) {
-                        displayContent.postNewConfigurationToHandler();
+                        displayContent.sendNewConfiguration();
                     }
                 }
 
@@ -4421,7 +4422,7 @@
             mDisplayReady = true;
             // Reconfigure all displays to make sure that forced properties and
             // DisplayWindowSettings are applied.
-            mRoot.forAllDisplays(this::reconfigureDisplayLocked);
+            mRoot.forAllDisplays(DisplayContent::reconfigureDisplayLocked);
             mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
                     PackageManager.FEATURE_TOUCHSCREEN);
         }
@@ -4500,7 +4501,6 @@
         public static final int FORCE_GC = 15;
         public static final int ENABLE_SCREEN = 16;
         public static final int APP_FREEZE_TIMEOUT = 17;
-        public static final int SEND_NEW_CONFIGURATION = 18;
         public static final int REPORT_WINDOWS_CHANGE = 19;
 
         public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
@@ -4712,23 +4712,6 @@
                     break;
                 }
 
-                case SEND_NEW_CONFIGURATION: {
-                    final DisplayContent displayContent = (DisplayContent) msg.obj;
-                    removeMessages(SEND_NEW_CONFIGURATION, displayContent);
-                    if (displayContent.isReady()) {
-                        displayContent.sendNewConfiguration();
-                    } else {
-                        // Message could come after display has already been removed.
-                        if (DEBUG_CONFIGURATION) {
-                            final String reason = displayContent.getParent() == null
-                                    ? "detached" : "unready";
-                            Slog.w(TAG, "Trying to send configuration to " + reason + " display="
-                                    + displayContent);
-                        }
-                    }
-                    break;
-                }
-
                 case REPORT_WINDOWS_CHANGE: {
                     if (mWindowsChanged) {
                         synchronized (mGlobalLock) {
@@ -5183,29 +5166,6 @@
         return 0;
     }
 
-    void reconfigureDisplayLocked(@NonNull DisplayContent displayContent) {
-        if (!displayContent.isReady()) {
-            return;
-        }
-        displayContent.configureDisplayPolicy();
-        displayContent.setLayoutNeeded();
-
-        boolean configChanged = displayContent.updateOrientationFromAppTokens();
-        final Configuration currentDisplayConfig = displayContent.getConfiguration();
-        mTempConfiguration.setTo(currentDisplayConfig);
-        displayContent.computeScreenConfiguration(mTempConfiguration);
-        configChanged |= currentDisplayConfig.diff(mTempConfiguration) != 0;
-
-        if (configChanged) {
-            displayContent.mWaitingForConfig = true;
-            startFreezingDisplayLocked(0 /* exitAnim */,
-                    0 /* enterAnim */, displayContent);
-            displayContent.postNewConfigurationToHandler();
-        }
-
-        mWindowPlacerLocked.performSurfacePlacement();
-    }
-
     @Override
     public void setOverscan(int displayId, int left, int top, int right, int bottom) {
         if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
@@ -5235,7 +5195,7 @@
 
         mDisplayWindowSettings.setOverscanLocked(displayInfo, left, top, right, bottom);
 
-        reconfigureDisplayLocked(displayContent);
+        displayContent.reconfigureDisplayLocked();
     }
 
     @Override
@@ -5547,7 +5507,7 @@
         }
 
         if (configChanged) {
-            displayContent.postNewConfigurationToHandler();
+            displayContent.sendNewConfiguration();
         }
         mLatencyTracker.onActionEnd(ACTION_ROTATE_SCREEN);
     }
@@ -6863,12 +6823,11 @@
             int lastWindowingMode = displayContent.getWindowingMode();
             mDisplayWindowSettings.setWindowingModeLocked(displayContent, mode);
 
-            reconfigureDisplayLocked(displayContent);
+            displayContent.reconfigureDisplayLocked();
 
             if (lastWindowingMode != displayContent.getWindowingMode()) {
                 // reconfigure won't detect this change in isolation because the windowing mode is
                 // already set on the display, so fire off a new config now.
-                mH.removeMessages(H.SEND_NEW_CONFIGURATION);
 
                 final long origId = Binder.clearCallingIdentity();
                 try {
@@ -6916,7 +6875,7 @@
 
             mDisplayWindowSettings.setRemoveContentModeLocked(displayContent, mode);
 
-            reconfigureDisplayLocked(displayContent);
+            displayContent.reconfigureDisplayLocked();
         }
     }
 
@@ -6955,7 +6914,7 @@
             mDisplayWindowSettings.setShouldShowWithInsecureKeyguardLocked(displayContent,
                     shouldShow);
 
-            reconfigureDisplayLocked(displayContent);
+            displayContent.reconfigureDisplayLocked();
         }
     }
 
@@ -6999,7 +6958,7 @@
 
             mDisplayWindowSettings.setShouldShowSystemDecorsLocked(displayContent, shouldShow);
 
-            reconfigureDisplayLocked(displayContent);
+            displayContent.reconfigureDisplayLocked();
         }
     }
 
@@ -7044,7 +7003,7 @@
 
             mDisplayWindowSettings.setShouldShowImeLocked(displayContent, shouldShow);
 
-            reconfigureDisplayLocked(displayContent);
+            displayContent.reconfigureDisplayLocked();
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 8b1baeb..95db4486 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1633,7 +1633,7 @@
                 || !mRelayoutCalled
                 || (atoken == null && mToken.isHidden())
                 || (atoken != null && atoken.hiddenRequested)
-                || isParentWindowHidden()
+                || isParentWindowGoneForLayout()
                 || (mAnimatingExit && !isAnimatingLw())
                 || mDestroying;
     }
@@ -2063,7 +2063,7 @@
             if (wasVisible) {
                 final DisplayContent displayContent = getDisplayContent();
                 if (displayContent.updateOrientationFromAppTokens()) {
-                    displayContent.postNewConfigurationToHandler();
+                    displayContent.sendNewConfiguration();
                 }
             }
             mWmService.updateFocusedWindowLocked(isFocused()
@@ -2393,10 +2393,11 @@
 
     void prepareWindowToDisplayDuringRelayout(boolean wasVisible) {
         // We need to turn on screen regardless of visibility.
-        boolean hasTurnScreenOnFlag = (mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0;
+        final boolean hasTurnScreenOnFlag = (mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0
+                || (mAppToken != null && mAppToken.mActivityRecord.canTurnScreenOn());
 
         // The screen will turn on if the following conditions are met
-        // 1. The window has the flag FLAG_TURN_SCREEN_ON
+        // 1. The window has the flag FLAG_TURN_SCREEN_ON or ActivityRecord#canTurnScreenOn.
         // 2. The WMS allows theater mode.
         // 3. No AWT or the AWT allows the screen to be turned on. This should only be true once
         // per resume to prevent the screen getting getting turned on for each relayout. Set
@@ -2410,7 +2411,7 @@
             boolean allowTheaterMode = mWmService.mAllowTheaterModeWakeFromLayout
                     || Settings.Global.getInt(mWmService.mContext.getContentResolver(),
                             Settings.Global.THEATER_MODE_ON, 0) == 0;
-            boolean canTurnScreenOn = mAppToken == null || mAppToken.canTurnScreenOn();
+            boolean canTurnScreenOn = mAppToken == null || mAppToken.currentLaunchCanTurnScreenOn();
 
             if (allowTheaterMode && canTurnScreenOn && !mPowerManagerWrapper.isInteractive()) {
                 if (DEBUG_VISIBILITY || DEBUG_POWER) {
@@ -2421,7 +2422,7 @@
             }
 
             if (mAppToken != null) {
-                mAppToken.setCanTurnScreenOn(false);
+                mAppToken.setCurrentLaunchCanTurnScreenOn(false);
             }
         }
 
@@ -3847,6 +3848,11 @@
         return parent != null && parent.mHidden;
     }
 
+    private boolean isParentWindowGoneForLayout() {
+        final WindowState parent = getParentWindow();
+        return parent != null && parent.isGoneForLayoutLw();
+    }
+
     void setWillReplaceWindow(boolean animate) {
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             final WindowState c = mChildren.get(i);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 73344ac..3ba3280 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1508,6 +1508,12 @@
     }
 
     void detachChildren() {
+
+        // Do not detach children of starting windows, as their lifecycle is well under control and
+        // it may lead to issues in case we relaunch when we just added the starting window.
+        if (mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
+            return;
+        }
         if (mSurfaceController != null) {
             mSurfaceController.detachChildren();
         }
diff --git a/services/core/java/com/android/server/wm/utils/RegionUtils.java b/services/core/java/com/android/server/wm/utils/RegionUtils.java
index b1b3070..ce7776f 100644
--- a/services/core/java/com/android/server/wm/utils/RegionUtils.java
+++ b/services/core/java/com/android/server/wm/utils/RegionUtils.java
@@ -50,6 +50,20 @@
     /**
      * Applies actions on each rect contained within a {@code Region}.
      *
+     * @param region the given region.
+     * @param rectConsumer the action holder.
+     */
+    public static void forEachRect(Region region, Consumer<Rect> rectConsumer) {
+        final RegionIterator it = new RegionIterator(region);
+        final Rect rect = new Rect();
+        while (it.next(rect)) {
+            rectConsumer.accept(rect);
+        }
+    }
+
+    /**
+     * Applies actions on each rect contained within a {@code Region}.
+     *
      * Order is bottom to top, then right to left.
      *
      * @param region the given region.
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayTransformManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayTransformManagerTest.java
index 73b3b8b..a785300 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayTransformManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayTransformManagerTest.java
@@ -19,6 +19,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyString;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY;
+import static com.android.server.display.color.DisplayTransformManager.PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE;
 import static com.android.server.display.color.DisplayTransformManager.PERSISTENT_PROPERTY_DISPLAY_COLOR;
 import static com.android.server.display.color.DisplayTransformManager.PERSISTENT_PROPERTY_SATURATION;
 
@@ -28,6 +29,7 @@
 
 import android.hardware.display.ColorDisplayManager;
 import android.os.SystemProperties;
+import android.view.Display;
 
 import androidx.test.runner.AndroidJUnit4;
 
@@ -79,7 +81,7 @@
 
     @Test
     public void setColorMode_natural() {
-        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix);
+        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix, -1);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
                 .isEqualTo("0" /* managed */);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
@@ -88,7 +90,7 @@
 
     @Test
     public void setColorMode_boosted() {
-        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED, mNightDisplayMatrix);
+        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED, mNightDisplayMatrix, -1);
 
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
                 .isEqualTo("0" /* managed */);
@@ -98,7 +100,7 @@
 
     @Test
     public void setColorMode_saturated() {
-        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_SATURATED, mNightDisplayMatrix);
+        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_SATURATED, mNightDisplayMatrix, -1);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
                 .isEqualTo("1" /* unmanaged */);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
@@ -107,7 +109,7 @@
 
     @Test
     public void setColorMode_automatic() {
-        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC, mNightDisplayMatrix);
+        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC, mNightDisplayMatrix, -1);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
                 .isEqualTo("2" /* enhanced */);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
@@ -116,7 +118,7 @@
 
     @Test
     public void setColorMode_vendor() {
-        mDtm.setColorMode(0x100, mNightDisplayMatrix);
+        mDtm.setColorMode(0x100, mNightDisplayMatrix, -1);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
                 .isEqualTo(Integer.toString(0x100) /* pass-through */);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
@@ -125,10 +127,38 @@
 
     @Test
     public void setColorMode_outOfBounds() {
-        mDtm.setColorMode(0x50, mNightDisplayMatrix);
+        mDtm.setColorMode(0x50, mNightDisplayMatrix, -1);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
                 .isEqualTo(null);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
                 .isEqualTo(null);
     }
+
+    @Test
+    public void setColorMode_withoutColorSpace() {
+        String magicPropertyValue = "magic";
+
+        // Start with a known state, which we expect to remain unmodified
+        SystemProperties.set(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE, magicPropertyValue);
+
+        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix,
+                Display.COLOR_MODE_INVALID);
+        assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE))
+                .isEqualTo(magicPropertyValue);
+    }
+
+    @Test
+    public void setColorMode_withColorSpace() {
+        String magicPropertyValue = "magic";
+        int testPropertyValue = Display.COLOR_MODE_SRGB;
+
+        // Start with a known state, which we expect to get modified
+        SystemProperties.set(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE, magicPropertyValue);
+
+        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix,
+                testPropertyValue);
+        assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE))
+                .isEqualTo(Integer.toString(testPropertyValue));
+    }
+
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java
index 70b7bb6..3614763 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java
@@ -71,7 +71,6 @@
     private static final String SOURCE_PACKAGE = "com.android.frameworks.mockingservicestests";
     private static final int SOURCE_USER_ID = 0;
 
-    private TimeController.TcConstants mConstants;
     private TimeController mTimeController;
 
     private MockitoSession mMockingSession;
@@ -111,7 +110,6 @@
 
         // Initialize real objects.
         mTimeController = new TimeController(mJobSchedulerService);
-        mConstants = mTimeController.getTcConstants();
         spyOn(mTimeController);
     }
 
@@ -159,18 +157,7 @@
     }
 
     @Test
-    public void testMaybeStartTrackingJobLocked_DelayInOrder_NoSkipping() {
-        mConstants.SKIP_NOT_READY_JOBS = false;
-        mTimeController.onConstantsUpdatedLocked();
-
-        runTestMaybeStartTrackingJobLocked_DelayInOrder();
-    }
-
-    @Test
-    public void testMaybeStartTrackingJobLocked_DelayInOrder_WithSkipping_AllReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
-
+    public void testMaybeStartTrackingJobLocked_DelayInOrder_AllReady() {
         doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
 
         runTestMaybeStartTrackingJobLocked_DelayInOrder();
@@ -201,9 +188,7 @@
     }
 
     @Test
-    public void testMaybeStartTrackingJobLocked_DelayInOrder_WithSkipping_SomeNotReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
+    public void testMaybeStartTrackingJobLocked_DelayInOrder_SomeNotReady() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
         JobStatus jobLatest = createJobStatus("testMaybeStartTrackingJobLocked_DelayInOrder",
@@ -235,18 +220,7 @@
     }
 
     @Test
-    public void testMaybeStartTrackingJobLocked_DelayReverseOrder_NoSkipping() {
-        mConstants.SKIP_NOT_READY_JOBS = false;
-        mTimeController.onConstantsUpdatedLocked();
-
-        runTestMaybeStartTrackingJobLocked_DelayReverseOrder();
-    }
-
-    @Test
-    public void testMaybeStartTrackingJobLocked_DelayReverseOrder_WithSkipping_AllReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
-
+    public void testMaybeStartTrackingJobLocked_DelayReverseOrder_AllReady() {
         doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
 
         runTestMaybeStartTrackingJobLocked_DelayReverseOrder();
@@ -279,9 +253,7 @@
     }
 
     @Test
-    public void testMaybeStartTrackingJobLocked_DelayReverseOrder_WithSkipping_SomeNotReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
+    public void testMaybeStartTrackingJobLocked_DelayReverseOrder_SomeNotReady() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
         JobStatus jobLatest = createJobStatus("testMaybeStartTrackingJobLocked_DelayReverseOrder",
@@ -315,18 +287,7 @@
     }
 
     @Test
-    public void testMaybeStartTrackingJobLocked_DeadlineInOrder_NoSkipping() {
-        mConstants.SKIP_NOT_READY_JOBS = false;
-        mTimeController.onConstantsUpdatedLocked();
-
-        runTestMaybeStartTrackingJobLocked_DeadlineInOrder();
-    }
-
-    @Test
-    public void testMaybeStartTrackingJobLocked_DeadlineInOrder_WithSkipping_AllReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
-
+    public void testMaybeStartTrackingJobLocked_DeadlineInOrder_AllReady() {
         doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
 
         runTestMaybeStartTrackingJobLocked_DeadlineInOrder();
@@ -357,9 +318,7 @@
     }
 
     @Test
-    public void testMaybeStartTrackingJobLocked_DeadlineInOrder_WithSkipping_SomeNotReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
+    public void testMaybeStartTrackingJobLocked_DeadlineInOrder_SomeNotReady() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
         JobStatus jobLatest = createJobStatus("testMaybeStartTrackingJobLocked_DeadlineInOrder",
@@ -391,18 +350,7 @@
     }
 
     @Test
-    public void testMaybeStartTrackingJobLocked_DeadlineReverseOrder_NoSkipping() {
-        mConstants.SKIP_NOT_READY_JOBS = false;
-        mTimeController.onConstantsUpdatedLocked();
-
-        runTestMaybeStartTrackingJobLocked_DeadlineReverseOrder();
-    }
-
-    @Test
-    public void testMaybeStartTrackingJobLocked_DeadlineReverseOrder_WithSkipping_AllReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
-
+    public void testMaybeStartTrackingJobLocked_DeadlineReverseOrder_AllReady() {
         doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
 
         runTestMaybeStartTrackingJobLocked_DeadlineReverseOrder();
@@ -438,9 +386,7 @@
     }
 
     @Test
-    public void testMaybeStartTrackingJobLocked_DeadlineReverseOrder_WithSkipping_SomeNotReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
+    public void testMaybeStartTrackingJobLocked_DeadlineReverseOrder_SomeNotReady() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
         JobStatus jobLatest = createJobStatus(
@@ -478,62 +424,7 @@
     }
 
     @Test
-    public void testJobSkipToggling() {
-        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
-
-        JobStatus jobLatest = createJobStatus(
-                "testMaybeStartTrackingJobLocked_DeadlineReverseOrder",
-                createJob().setOverrideDeadline(HOUR_IN_MILLIS));
-        JobStatus jobEarliest = createJobStatus(
-                "testMaybeStartTrackingJobLocked_DeadlineReverseOrder",
-                createJob().setOverrideDeadline(5 * MINUTE_IN_MILLIS));
-
-        doReturn(true).when(mTimeController)
-                .wouldBeReadyWithConstraintLocked(eq(jobLatest), anyInt());
-        doReturn(false).when(mTimeController)
-                .wouldBeReadyWithConstraintLocked(eq(jobEarliest), anyInt());
-
-        // Starting off with the skipping off, we should still set an alarm for the earlier job.
-        mConstants.SKIP_NOT_READY_JOBS = false;
-        mTimeController.recheckAlarmsLocked();
-        InOrder inOrder = inOrder(mAlarmManager);
-
-        mTimeController.maybeStartTrackingJobLocked(jobEarliest, null);
-        mTimeController.maybeStartTrackingJobLocked(jobLatest, null);
-        inOrder.verify(mAlarmManager, times(1))
-                .set(anyInt(), eq(now + 5 * MINUTE_IN_MILLIS), anyLong(), anyLong(),
-                        eq(TAG_DEADLINE), any(), any(), any());
-
-        // Turn it on, use alarm for later job.
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.recheckAlarmsLocked();
-
-        inOrder.verify(mAlarmManager, times(1))
-                .set(anyInt(), eq(now + HOUR_IN_MILLIS), anyLong(), anyLong(), eq(TAG_DEADLINE),
-                        any(), any(), any());
-
-        // Back off, use alarm for earlier job.
-        mConstants.SKIP_NOT_READY_JOBS = false;
-        mTimeController.recheckAlarmsLocked();
-
-        inOrder.verify(mAlarmManager, times(1))
-                .set(anyInt(), eq(now + 5 * MINUTE_IN_MILLIS), anyLong(), anyLong(),
-                        eq(TAG_DEADLINE), any(), any(), any());
-    }
-
-    @Test
-    public void testCheckExpiredDelaysAndResetAlarm_NoSkipping() {
-        mConstants.SKIP_NOT_READY_JOBS = false;
-        mTimeController.recheckAlarmsLocked();
-
-        runTestCheckExpiredDelaysAndResetAlarm();
-    }
-
-    @Test
-    public void testCheckExpiredDelaysAndResetAlarm_WithSkipping_AllReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.recheckAlarmsLocked();
-
+    public void testCheckExpiredDelaysAndResetAlarm_AllReady() {
         doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
 
         runTestCheckExpiredDelaysAndResetAlarm();
@@ -589,9 +480,7 @@
     }
 
     @Test
-    public void testCheckExpiredDelaysAndResetAlarm_WithSkipping_SomeNotReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.recheckAlarmsLocked();
+    public void testCheckExpiredDelaysAndResetAlarm_SomeNotReady() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
         JobStatus jobLatest = createJobStatus("testCheckExpiredDelaysAndResetAlarm",
@@ -639,18 +528,7 @@
     }
 
     @Test
-    public void testCheckExpiredDeadlinesAndResetAlarm_NoSkipping() {
-        mConstants.SKIP_NOT_READY_JOBS = false;
-        mTimeController.recheckAlarmsLocked();
-
-        runTestCheckExpiredDeadlinesAndResetAlarm();
-    }
-
-    @Test
-    public void testCheckExpiredDeadlinesAndResetAlarm_WithSkipping_AllReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.recheckAlarmsLocked();
-
+    public void testCheckExpiredDeadlinesAndResetAlarm_AllReady() {
         doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
 
         runTestCheckExpiredDeadlinesAndResetAlarm();
@@ -706,9 +584,7 @@
     }
 
     @Test
-    public void testCheckExpiredDeadlinesAndResetAlarm_WithSkipping_SomeNotReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.recheckAlarmsLocked();
+    public void testCheckExpiredDeadlinesAndResetAlarm_SomeNotReady() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
         JobStatus jobLatest = createJobStatus("testCheckExpiredDeadlinesAndResetAlarm",
@@ -756,28 +632,14 @@
     }
 
     @Test
-    public void testEvaluateStateLocked_SkippingOff() {
-        mConstants.SKIP_NOT_READY_JOBS = false;
-        mTimeController.recheckAlarmsLocked();
-        JobStatus job = createJobStatus("testEvaluateStateLocked_SkippingOff",
-                createJob().setOverrideDeadline(HOUR_IN_MILLIS));
-
-        mTimeController.evaluateStateLocked(job);
-        verify(mAlarmManager, never())
-                .set(anyInt(), anyLong(), anyLong(), anyLong(), anyString(), any(), any(), any());
-    }
-
-    @Test
-    public void testEvaluateStateLocked_SkippingOn_Delay() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.recheckAlarmsLocked();
+    public void testEvaluateStateLocked_Delay() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
-        JobStatus jobLatest = createJobStatus("testEvaluateStateLocked_SkippingOn_Delay",
+        JobStatus jobLatest = createJobStatus("testEvaluateStateLocked_Delay",
                 createJob().setMinimumLatency(HOUR_IN_MILLIS));
-        JobStatus jobMiddle = createJobStatus("testEvaluateStateLocked_SkippingOn_Delay",
+        JobStatus jobMiddle = createJobStatus("testEvaluateStateLocked_Delay",
                 createJob().setMinimumLatency(30 * MINUTE_IN_MILLIS));
-        JobStatus jobEarliest = createJobStatus("testEvaluateStateLocked_SkippingOn_Delay",
+        JobStatus jobEarliest = createJobStatus("testEvaluateStateLocked_Delay",
                 createJob().setMinimumLatency(5 * MINUTE_IN_MILLIS));
 
         doReturn(false).when(mTimeController)
@@ -827,16 +689,14 @@
     }
 
     @Test
-    public void testEvaluateStateLocked_SkippingOn_Deadline() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.recheckAlarmsLocked();
+    public void testEvaluateStateLocked_Deadline() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
-        JobStatus jobLatest = createJobStatus("testEvaluateStateLocked_SkippingOn_Deadline",
+        JobStatus jobLatest = createJobStatus("testEvaluateStateLocked_Deadline",
                 createJob().setOverrideDeadline(HOUR_IN_MILLIS));
-        JobStatus jobMiddle = createJobStatus("testEvaluateStateLocked_SkippingOn_Deadline",
+        JobStatus jobMiddle = createJobStatus("testEvaluateStateLocked_Deadline",
                 createJob().setOverrideDeadline(30 * MINUTE_IN_MILLIS));
-        JobStatus jobEarliest = createJobStatus("testEvaluateStateLocked_SkippingOn_Deadline",
+        JobStatus jobEarliest = createJobStatus("testEvaluateStateLocked_Deadline",
                 createJob().setOverrideDeadline(5 * MINUTE_IN_MILLIS));
 
         doReturn(false).when(mTimeController)
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index e9e96c9..1ad7b6e 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -72,6 +72,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.devicepolicy.MockUtils;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import com.google.android.collect.Lists;
 
@@ -132,9 +133,10 @@
     @Mock private UnaryOperator<List<ScoredNetwork>> mScanResultsFilter;
     @Mock private WifiInfo mWifiInfo;
     @Mock private NetworkScoreService.ScoringServiceConnection mServiceConnection;
-    @Mock private PackageManagerInternal mPackageManagerInternal;
+    @Mock private PermissionManagerServiceInternal mPermissionManagerInternal;
     @Captor private ArgumentCaptor<List<ScoredNetwork>> mScoredNetworkCaptor;
-    @Captor private ArgumentCaptor<PackageManagerInternal.PackagesProvider> mPackagesProviderCaptor;
+    @Captor private
+    ArgumentCaptor<PermissionManagerServiceInternal.PackagesProvider> mPackagesProviderCaptor;
 
     private ContentResolver mContentResolver;
     private NetworkScoreService mNetworkScoreService;
@@ -162,7 +164,8 @@
         when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
         mHandlerThread = new HandlerThread("NetworkScoreServiceTest");
         mHandlerThread.start();
-        LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternal);
+        LocalServices.addService(
+                PermissionManagerServiceInternal.class, mPermissionManagerInternal);
         mNetworkScoreService = new NetworkScoreService(mContext, mNetworkScorerAppManager,
                 networkScorerAppData -> mServiceConnection, mHandlerThread.getLooper());
         WifiConfiguration configuration = new WifiConfiguration();
@@ -196,7 +199,7 @@
         Settings.Global.putString(mContentResolver,
                 Settings.Global.USE_OPEN_WIFI_PACKAGE, "com.some.app");
 
-        verify(mPackageManagerInternal)
+        verify(mPermissionManagerInternal)
                 .setUseOpenWifiAppPackagesProvider(mPackagesProviderCaptor.capture());
 
         String[] packages = mPackagesProviderCaptor.getValue().getPackages(0);
@@ -209,7 +212,7 @@
         Settings.Global.putString(mContentResolver,
                 Settings.Global.USE_OPEN_WIFI_PACKAGE, "com.some.other.app");
 
-        verify(mPackageManagerInternal, timeout(500))
+        verify(mPermissionManagerInternal, timeout(500))
                 .grantDefaultPermissionsToDefaultUseOpenWifiApp("com.some.other.app", 0);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
index 22408cc..e125329 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
@@ -238,7 +238,7 @@
         windowInfo.type = AccessibilityWindowInfo.TYPE_APPLICATION;
         windowInfo.token = token.asBinder();
         windowInfo.layer = 0;
-        windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+        windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
         mWindowInfos.set(0, windowInfo);
 
         mA11yWindowManager.onWindowsForAccessibilityChanged(SEND_ON_WINDOW_CHANGES, mWindowInfos);
@@ -305,67 +305,73 @@
     }
 
     @Test
-    public void computePartialInteractiveRegionForWindow_wholeWindowVisible_returnWholeRegion() {
+    public void computePartialInteractiveRegionForWindow_wholeVisible_returnWholeRegion() {
         // Updates top 2 z-order WindowInfo are whole visible.
         WindowInfo windowInfo = mWindowInfos.get(0);
-        windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2);
+        windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2);
         windowInfo = mWindowInfos.get(1);
-        windowInfo.boundsInScreen.set(0, SCREEN_HEIGHT / 2,
-                SCREEN_WIDTH, SCREEN_HEIGHT);
+        windowInfo.regionInScreen.set(0, SCREEN_HEIGHT / 2, SCREEN_WIDTH, SCREEN_HEIGHT);
         mA11yWindowManager.onWindowsForAccessibilityChanged(SEND_ON_WINDOW_CHANGES, mWindowInfos);
 
         final List<AccessibilityWindowInfo> a11yWindows = mA11yWindowManager.getWindowListLocked();
         final Region outBounds = new Region();
         int windowId = a11yWindows.get(0).getId();
 
-        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(
-                windowId, outBounds);
+        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
         assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
         assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT / 2));
 
         windowId = a11yWindows.get(1).getId();
 
-        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(
-                windowId, outBounds);
+        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
         assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
         assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT / 2));
     }
 
     @Test
-    public void computePartialInteractiveRegionForWindow_halfWindowVisible_returnHalfRegion() {
+    public void computePartialInteractiveRegionForWindow_halfVisible_returnHalfRegion() {
         // Updates z-order #1 WindowInfo is half visible
         WindowInfo windowInfo = mWindowInfos.get(0);
-        windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2);
-        windowInfo = mWindowInfos.get(1);
-        windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+        windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2);
 
         mA11yWindowManager.onWindowsForAccessibilityChanged(SEND_ON_WINDOW_CHANGES, mWindowInfos);
         final List<AccessibilityWindowInfo> a11yWindows = mA11yWindowManager.getWindowListLocked();
         final Region outBounds = new Region();
         int windowId = a11yWindows.get(1).getId();
 
-        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(
-                windowId, outBounds);
+        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
         assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
         assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT / 2));
     }
 
     @Test
-    public void computePartialInteractiveRegionForWindow_windowNotVisible_returnEmptyRegion() {
-        // Updates z-order #1 WindowInfo is not visible
+    public void computePartialInteractiveRegionForWindow_notVisible_returnEmptyRegion() {
+        // Since z-order #0 WindowInfo is full screen, z-order #1 WindowInfo should be invisible.
+        final List<AccessibilityWindowInfo> a11yWindows = mA11yWindowManager.getWindowListLocked();
+        final Region outBounds = new Region();
+        int windowId = a11yWindows.get(1).getId();
+
+        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
+        assertTrue(outBounds.getBounds().isEmpty());
+    }
+
+    @Test
+    public void computePartialInteractiveRegionForWindow_partialVisible_returnVisibleRegion() {
+        // Updates z-order #0 WindowInfo to have two interact-able areas.
+        Region region = new Region(0, 0, SCREEN_WIDTH, 200);
+        region.op(0, SCREEN_HEIGHT - 200, SCREEN_WIDTH, SCREEN_HEIGHT, Region.Op.UNION);
         WindowInfo windowInfo = mWindowInfos.get(0);
-        windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
-        windowInfo = mWindowInfos.get(1);
-        windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+        windowInfo.regionInScreen.set(region);
         mA11yWindowManager.onWindowsForAccessibilityChanged(SEND_ON_WINDOW_CHANGES, mWindowInfos);
 
         final List<AccessibilityWindowInfo> a11yWindows = mA11yWindowManager.getWindowListLocked();
         final Region outBounds = new Region();
         int windowId = a11yWindows.get(1).getId();
 
-        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(
-                windowId, outBounds);
-        assertTrue(outBounds.getBounds().isEmpty());
+        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
+        assertFalse(outBounds.getBounds().isEmpty());
+        assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
+        assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT - 400));
     }
 
     @Test
@@ -588,7 +594,7 @@
         windowInfo.type = AccessibilityWindowInfo.TYPE_APPLICATION;
         windowInfo.token = windowToken.asBinder();
         windowInfo.layer = layer;
-        windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+        windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
         mWindowInfos.add(windowInfo);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/UiAutomationManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/UiAutomationManagerTest.java
index d854582..210de53 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/UiAutomationManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/UiAutomationManagerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server.accessibility;
 
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -31,6 +33,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.hardware.display.DisplayManager;
 import android.os.IBinder;
 import android.view.accessibility.AccessibilityEvent;
 
@@ -78,6 +81,11 @@
 
         when(mMockAccessibilityServiceClient.asBinder()).thenReturn(mMockServiceAsBinder);
 
+        final Context context = getInstrumentation().getTargetContext();
+        when(mMockContext.getSystemService(Context.DISPLAY_SERVICE)).thenReturn(
+                context.getSystemService(
+                        DisplayManager.class));
+
         mMessageCapturingHandler = new MessageCapturingHandler(null);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java b/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java
index fb2913b..a19b387 100644
--- a/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java
@@ -18,13 +18,19 @@
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.content.Context;
 import android.content.ContextWrapper;
+import android.content.res.Resources;
 import android.hardware.display.ColorDisplayManager;
 import android.hardware.display.Time;
 import android.os.Handler;
@@ -33,6 +39,7 @@
 import android.provider.Settings.Secure;
 import android.provider.Settings.System;
 import android.test.mock.MockContentResolver;
+import android.view.Display;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
@@ -73,6 +80,8 @@
     private ColorDisplayService mCds;
     private ColorDisplayService.BinderService mBinderService;
 
+    private Resources mResourcesSpy;
+
     @BeforeClass
     public static void setDtm() {
         final DisplayTransformManager dtm = Mockito.mock(DisplayTransformManager.class);
@@ -84,6 +93,9 @@
         mContext = Mockito.spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
         doReturn(mContext).when(mContext).getApplicationContext();
 
+        mResourcesSpy = Mockito.spy(mContext.getResources());
+        when(mContext.getResources()).thenReturn(mResourcesSpy);
+
         mUserId = ActivityManager.getCurrentUser();
 
         final MockContentResolver cr = new MockContentResolver(mContext);
@@ -1050,6 +1062,80 @@
         assertDwbActive(true);
     }
 
+    @Test
+    public void compositionColorSpaces_noResources() {
+        final DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class);
+        reset(dtm);
+
+        when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
+            .thenReturn(new int[] {});
+        when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
+            .thenReturn(new int[] {});
+        setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
+        startService();
+        verify(dtm).setColorMode(eq(ColorDisplayManager.COLOR_MODE_NATURAL), any(),
+                eq(Display.COLOR_MODE_INVALID));
+    }
+
+    @Test
+    public void compositionColorSpaces_invalidResources() {
+        final DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class);
+        reset(dtm);
+
+        when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
+            .thenReturn(new int[] {
+               ColorDisplayManager.COLOR_MODE_NATURAL,
+               // Missing second color mode
+            });
+        when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
+            .thenReturn(new int[] {
+               Display.COLOR_MODE_SRGB,
+               Display.COLOR_MODE_DISPLAY_P3
+            });
+        setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
+        startService();
+        verify(dtm).setColorMode(eq(ColorDisplayManager.COLOR_MODE_NATURAL), any(),
+                eq(Display.COLOR_MODE_INVALID));
+    }
+
+    @Test
+    public void compositionColorSpaces_validResources_validColorMode() {
+        final DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class);
+        reset(dtm);
+
+        when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
+            .thenReturn(new int[] {
+               ColorDisplayManager.COLOR_MODE_NATURAL
+            });
+        when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
+            .thenReturn(new int[] {
+               Display.COLOR_MODE_SRGB,
+            });
+        setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
+        startService();
+        verify(dtm).setColorMode(eq(ColorDisplayManager.COLOR_MODE_NATURAL), any(),
+                eq(Display.COLOR_MODE_SRGB));
+    }
+
+    @Test
+    public void compositionColorSpaces_validResources_invalidColorMode() {
+        final DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class);
+        reset(dtm);
+
+        when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
+            .thenReturn(new int[] {
+               ColorDisplayManager.COLOR_MODE_NATURAL
+            });
+        when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
+            .thenReturn(new int[] {
+               Display.COLOR_MODE_SRGB,
+            });
+        setColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED);
+        startService();
+        verify(dtm).setColorMode(eq(ColorDisplayManager.COLOR_MODE_BOOSTED), any(),
+                eq(Display.COLOR_MODE_INVALID));
+    }
+
     /**
      * Configures Night display to use a custom schedule.
      *
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index ce1edcd..09ae3a2 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -559,7 +559,25 @@
                 .build();
         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
 
-        // RestrictBackground should be on, following its previous state
+        // RestrictBackground should be on, as before.
+        assertTrue(mService.getRestrictBackground());
+
+        stateOn = new PowerSaveState.Builder()
+                .setGlobalBatterySaverEnabled(true)
+                .setBatterySaverEnabled(true)
+                .build();
+        mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
+
+        // RestrictBackground should be on.
+        assertTrue(mService.getRestrictBackground());
+
+        stateOff = new PowerSaveState.Builder()
+                .setGlobalBatterySaverEnabled(false)
+                .setBatterySaverEnabled(false)
+                .build();
+        mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
+
+        // RestrictBackground should be on, as it was enabled manually before battery saver.
         assertTrue(mService.getRestrictBackground());
     }
 
@@ -585,6 +603,20 @@
 
         // RestrictBackground should be off, following its previous state
         assertFalse(mService.getRestrictBackground());
+
+        PowerSaveState stateOnRestrictOff = new PowerSaveState.Builder()
+                .setGlobalBatterySaverEnabled(true)
+                .setBatterySaverEnabled(false)
+                .build();
+
+        mService.updateRestrictBackgroundByLowPowerModeUL(stateOnRestrictOff);
+
+        assertFalse(mService.getRestrictBackground());
+
+        mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
+
+        // RestrictBackground should still be off.
+        assertFalse(mService.getRestrictBackground());
     }
 
     @Test
@@ -602,11 +634,49 @@
 
         // User turns off RestrictBackground manually
         setRestrictBackground(false);
-        PowerSaveState stateOff = new PowerSaveState.Builder().setBatterySaverEnabled(
-                false).build();
+        // RestrictBackground should be off because user changed it manually
+        assertFalse(mService.getRestrictBackground());
+
+        PowerSaveState stateOff = new PowerSaveState.Builder()
+                .setGlobalBatterySaverEnabled(false)
+                .setBatterySaverEnabled(false)
+                .build();
         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
 
-        // RestrictBackground should be off because user changes it manually
+        // RestrictBackground should remain off.
+        assertFalse(mService.getRestrictBackground());
+    }
+
+    @Test
+    public void updateRestrictBackgroundByLowPowerMode_RestrictOnWithGlobalOff()
+            throws Exception {
+        setRestrictBackground(false);
+        PowerSaveState stateOn = new PowerSaveState.Builder()
+                .setGlobalBatterySaverEnabled(false)
+                .setBatterySaverEnabled(true)
+                .build();
+
+        mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
+
+        // RestrictBackground should be turned on because of battery saver.
+        assertTrue(mService.getRestrictBackground());
+
+        PowerSaveState stateRestrictOff = new PowerSaveState.Builder()
+                .setGlobalBatterySaverEnabled(true)
+                .setBatterySaverEnabled(false)
+                .build();
+        mService.updateRestrictBackgroundByLowPowerModeUL(stateRestrictOff);
+
+        // RestrictBackground should be off, returning to its state before battery saver's change.
+        assertFalse(mService.getRestrictBackground());
+
+        PowerSaveState stateOff = new PowerSaveState.Builder()
+                .setGlobalBatterySaverEnabled(false)
+                .setBatterySaverEnabled(false)
+                .build();
+        mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
+
+        // RestrictBackground should still be off, back in its pre-battery saver state.
         assertFalse(mService.getRestrictBackground());
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
index 95ec3d9..fc7cfec 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
@@ -115,7 +115,7 @@
 
     @Test
     public void testPartitions() throws Exception {
-        String[] partitions = { "system", "vendor", "odm", "oem", "product", "product_services" };
+        String[] partitions = { "system", "vendor", "odm", "oem", "product", "system_ext" };
         String[] appdir = { "app", "priv-app" };
         for (int i = 0; i < partitions.length; i++) {
             for (int j = 0; j < appdir.length; j++) {
@@ -128,7 +128,7 @@
                 Assert.assertEquals(i == 1 || i == 2, PackageManagerService.locationIsVendor(path));
                 Assert.assertEquals(i == 3, PackageManagerService.locationIsOem(path));
                 Assert.assertEquals(i == 4, PackageManagerService.locationIsProduct(path));
-                Assert.assertEquals(i == 5, PackageManagerService.locationIsProductServices(path));
+                Assert.assertEquals(i == 5, PackageManagerService.locationIsSystemExt(path));
             }
         }
     }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 6061d51..8c3373f 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -156,7 +156,7 @@
         mService.setUsageStats(mUsageStats);
         mService.setAccessibilityManager(accessibilityManager);
         mService.mScreenOn = false;
-        mService.mInCall = false;
+        mService.mInCallStateOffHook = false;
         mService.mNotificationPulseEnabled = true;
     }
 
@@ -681,7 +681,7 @@
         mService.buzzBeepBlinkLocked(r);
         Mockito.reset(mRingtonePlayer);
 
-        mService.mInCall = true;
+        mService.mInCallStateOffHook = true;
         mService.buzzBeepBlinkLocked(r);
 
         verify(mService, times(1)).playInCallNotification();
@@ -1137,7 +1137,7 @@
 
     @Test
     public void testLightsInCall() {
-        mService.mInCall = true;
+        mService.mInCallStateOffHook = true;
         NotificationRecord r = getLightsNotification();
         mService.buzzBeepBlinkLocked(r);
         verifyNeverLights();
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index efbae2b..deca57e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.os.Process.NOBODY_UID;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_90;
@@ -40,6 +41,8 @@
 import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
 import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
@@ -54,8 +57,10 @@
 import android.app.servertransaction.ActivityConfigurationChangeItem;
 import android.app.servertransaction.ClientTransaction;
 import android.app.servertransaction.PauseActivityItem;
+import android.content.ComponentName;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.util.MergedConfiguration;
@@ -67,6 +72,7 @@
 
 import androidx.test.filters.MediumTest;
 
+import com.android.internal.R;
 import com.android.server.wm.utils.WmDisplayCutout;
 
 import org.junit.Before;
@@ -611,6 +617,15 @@
         assertNull(mActivity.pendingOptions);
     }
 
+    @Test
+    public void testCanLaunchHomeActivityFromChooser() {
+        ComponentName chooserComponent = ComponentName.unflattenFromString(
+                Resources.getSystem().getString(R.string.config_chooserActivity));
+        ActivityRecord chooserActivity = new ActivityBuilder(mService).setComponent(
+                chooserComponent).build();
+        assertThat(mActivity.canLaunchHomeActivity(NOBODY_UID, chooserActivity)).isTrue();
+    }
+
     /** Setup {@link #mActivity} as a size-compat-mode-able activity without fixed orientation. */
     private void prepareFixedAspectRatioUnresizableActivity() {
         setupDisplayContentForCompatDisplayInsets();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index 1684f97..6a3c81a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -32,6 +32,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -49,10 +50,12 @@
 import static org.mockito.Mockito.when;
 
 import android.graphics.PixelFormat;
+import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.view.Surface;
 import android.view.WindowManager;
 
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Test;
@@ -273,4 +276,37 @@
         win.mHasSurface = true;
         return win;
     }
+
+    @Test
+    @FlakyTest(bugId = 131005232)
+    public void testOverlappingWithNavBar() {
+        final WindowState targetWin = createApplicationWindow();
+        final WindowFrames winFrame = targetWin.getWindowFrames();
+        winFrame.mFrame.set(new Rect(100, 100, 200, 200));
+
+        final WindowState navigationBar = createNavigationBarWindow();
+
+        navigationBar.getFrameLw().set(new Rect(100, 200, 200, 300));
+
+        assertFalse("Freeform is overlapping with navigation bar",
+                DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar));
+
+        winFrame.mFrame.set(new Rect(100, 101, 200, 201));
+        assertTrue("Freeform should be overlapping with navigation bar (bottom)",
+                DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar));
+
+        winFrame.mFrame.set(new Rect(99, 200, 199, 300));
+        assertTrue("Freeform should be overlapping with navigation bar (right)",
+                DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar));
+
+        winFrame.mFrame.set(new Rect(199, 200, 299, 300));
+        assertTrue("Freeform should be overlapping with navigation bar (left)",
+                DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar));
+    }
+
+    private WindowState createNavigationBarWindow() {
+        final WindowState win = createWindow(null, TYPE_NAVIGATION_BAR, "NavigationBar");
+        win.mHasSurface = true;
+        return win;
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
index a735b09..2933b4a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
@@ -102,7 +102,8 @@
         mDisplayPolicy.adjustWindowParamsLw(win, win.mAttrs, Binder.getCallingPid(),
                 Binder.getCallingUid());
         assertEquals(WindowManagerGlobal.ADD_OKAY,
-                mDisplayPolicy.prepareAddWindowLw(win, win.mAttrs));
+                mDisplayPolicy.validateAddingWindowLw(win.mAttrs));
+        mDisplayPolicy.addWindowLw(win, win.mAttrs);
         win.mHasSurface = true;
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
index 2bffc16..bfede51 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
@@ -23,7 +23,6 @@
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.atLeastOnce;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
@@ -624,11 +623,8 @@
         assertFalse(dc.mWaitingForConfig);
 
         // Notify WM that the displays are ready and check that they are reconfigured.
-        spyOn(mWm);
         mWm.displayReady();
         waitUntilHandlersIdle();
-        verify(mWm, atLeastOnce()).reconfigureDisplayLocked(eq(mPrimaryDisplay));
-        verify(mWm, atLeastOnce()).reconfigureDisplayLocked(eq(dc));
 
         final Configuration config = new Configuration();
         mPrimaryDisplay.computeScreenConfiguration(config);
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index d0ee634..df7c9a4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -177,7 +177,9 @@
         final Display display = mWindowManagerService.mDisplayManager.getDisplay(DEFAULT_DISPLAY);
         // Display creation is driven by the ActivityManagerService via
         // ActivityStackSupervisor. We emulate those steps here.
-        mWindowManagerService.mRoot.createDisplayContent(display, mock(ActivityDisplay.class));
+        DisplayContent displayContent = mWindowManagerService.mRoot
+                .createDisplayContent(display, mock(ActivityDisplay.class));
+        displayContent.reconfigureDisplayLocked();
 
         mMockTracker.stopTracking();
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
index f958867..b29453a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
@@ -64,6 +64,7 @@
         assertTrueForFiles(files, File::exists, " must exist");
         final TaskSnapshot snapshot = mLoader.loadTask(1, mTestUserId, false /* reduced */);
         assertNotNull(snapshot);
+        assertEquals(MOCK_SNAPSHOT_ID, snapshot.getId());
         assertEquals(TEST_INSETS, snapshot.getContentInsets());
         assertNotNull(snapshot.getSnapshot());
         assertEquals(Configuration.ORIENTATION_PORTRAIT, snapshot.getOrientation());
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
index e004cd3..f749622 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
@@ -45,6 +45,7 @@
 
     private static final Rect TEST_INSETS = new Rect(10, 20, 30, 40);
     static final File FILES_DIR = getInstrumentation().getTargetContext().getFilesDir();
+    static final long MOCK_SNAPSHOT_ID = 12345678;
 
     TaskSnapshotPersister mPersister;
     TaskSnapshotLoader mLoader;
@@ -129,7 +130,7 @@
             Canvas c = buffer.lockCanvas();
             c.drawColor(Color.RED);
             buffer.unlockCanvasAndPost(c);
-            return new TaskSnapshot(new ComponentName("", ""), buffer,
+            return new TaskSnapshot(MOCK_SNAPSHOT_ID, new ComponentName("", ""), buffer,
                     ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT, TEST_INSETS,
                     mReducedResolution, mScale, mIsRealSnapshot,
                     mWindowingMode, mSystemUiVisibility, mIsTranslucent);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
index 4ca01ec..74db820 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
@@ -64,7 +64,9 @@
             int windowFlags, Rect taskBounds) {
         final GraphicBuffer buffer = GraphicBuffer.create(width, height, PixelFormat.RGBA_8888,
                 GraphicBuffer.USAGE_SW_READ_RARELY | GraphicBuffer.USAGE_SW_WRITE_NEVER);
-        final TaskSnapshot snapshot = new TaskSnapshot(new ComponentName("", ""), buffer,
+        final TaskSnapshot snapshot = new TaskSnapshot(
+                System.currentTimeMillis(),
+                new ComponentName("", ""), buffer,
                 ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT, contentInsets, false,
                 1.0f, true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN,
                 0 /* systemUiVisibility */, false /* isTranslucent */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 1b57c79..36698ea 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -302,43 +302,38 @@
 
     @Test
     public void testPrepareWindowToDisplayDuringRelayout() {
-        testPrepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
-        testPrepareWindowToDisplayDuringRelayout(true /*wasVisible*/);
-
-        // Call prepareWindowToDisplayDuringRelayout for a window without FLAG_TURN_SCREEN_ON
-        // before calling prepareWindowToDisplayDuringRelayout for windows with flag in the same
-        // appWindowToken.
+        // Call prepareWindowToDisplayDuringRelayout for a window without FLAG_TURN_SCREEN_ON before
+        // calling setCurrentLaunchCanTurnScreenOn for windows with flag in the same appWindowToken.
         final AppWindowToken appWindowToken = createAppWindowToken(mDisplayContent,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
         final WindowState first = createWindow(null, TYPE_APPLICATION, appWindowToken, "first");
         final WindowState second = createWindow(null, TYPE_APPLICATION, appWindowToken, "second");
         second.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
 
-        reset(sPowerManagerWrapper);
-        first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
-        verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString());
-        assertTrue(appWindowToken.canTurnScreenOn());
-
-        reset(sPowerManagerWrapper);
-        second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
-        verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
-        assertFalse(appWindowToken.canTurnScreenOn());
+        testPrepareWindowToDisplayDuringRelayout(first, false /* expectedWakeupCalled */,
+                true /* expectedCurrentLaunchCanTurnScreenOn */);
+        testPrepareWindowToDisplayDuringRelayout(second, true /* expectedWakeupCalled */,
+                false /* expectedCurrentLaunchCanTurnScreenOn */);
 
         // Call prepareWindowToDisplayDuringRelayout for two window that have FLAG_TURN_SCREEN_ON
         // from the same appWindowToken. Only one should trigger the wakeup.
-        appWindowToken.setCanTurnScreenOn(true);
+        appWindowToken.setCurrentLaunchCanTurnScreenOn(true);
         first.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
         second.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
 
-        reset(sPowerManagerWrapper);
-        first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
-        verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
-        assertFalse(appWindowToken.canTurnScreenOn());
+        testPrepareWindowToDisplayDuringRelayout(first, true /* expectedWakeupCalled */,
+                false /* expectedCurrentLaunchCanTurnScreenOn */);
+        testPrepareWindowToDisplayDuringRelayout(second, false /* expectedWakeupCalled */,
+                false /* expectedCurrentLaunchCanTurnScreenOn */);
 
-        reset(sPowerManagerWrapper);
-        second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
-        verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString());
-        assertFalse(appWindowToken.canTurnScreenOn());
+        // Without window flags, the state of ActivityRecord.canTurnScreenOn should still be able to
+        // turn on the screen.
+        appWindowToken.setCurrentLaunchCanTurnScreenOn(true);
+        first.mAttrs.flags &= ~WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
+        doReturn(true).when(appWindowToken.mActivityRecord).canTurnScreenOn();
+
+        testPrepareWindowToDisplayDuringRelayout(first, true /* expectedWakeupCalled */,
+                false /* expectedCurrentLaunchCanTurnScreenOn */);
 
         // Call prepareWindowToDisplayDuringRelayout for a windows that are not children of an
         // appWindowToken. Both windows have the FLAG_TURNS_SCREEN_ON so both should call wakeup
@@ -360,6 +355,22 @@
         verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
     }
 
+    private void testPrepareWindowToDisplayDuringRelayout(WindowState appWindow,
+            boolean expectedWakeupCalled, boolean expectedCurrentLaunchCanTurnScreenOn) {
+        reset(sPowerManagerWrapper);
+        appWindow.prepareWindowToDisplayDuringRelayout(false /* wasVisible */);
+
+        if (expectedWakeupCalled) {
+            verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
+        } else {
+            verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString());
+        }
+        // If wakeup is expected to be called, the currentLaunchCanTurnScreenOn should be false
+        // because the state will be consumed.
+        assertThat(appWindow.mAppToken.currentLaunchCanTurnScreenOn(),
+                is(expectedCurrentLaunchCanTurnScreenOn));
+    }
+
     @Test
     public void testCanAffectSystemUiFlags() {
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
@@ -487,15 +498,6 @@
         assertThat(app.getWmDisplayCutout().getDisplayCutout(), is(cutout.inset(7, 10, 5, 20)));
     }
 
-    private void testPrepareWindowToDisplayDuringRelayout(boolean wasVisible) {
-        reset(sPowerManagerWrapper);
-        final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
-        root.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
-
-        root.prepareWindowToDisplayDuringRelayout(wasVisible /*wasVisible*/);
-        verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
-    }
-
     @Test
     public void testVisibilityChangeSwitchUser() {
         final WindowState window = createWindow(null, TYPE_APPLICATION, "app");
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 3a702cb9..dc461d1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -435,7 +435,9 @@
             // Display creation is driven by DisplayWindowController via ActivityStackSupervisor.
             // We skip those steps here.
             final ActivityDisplay mockAd = mock(ActivityDisplay.class);
-            return mWm.mRoot.createDisplayContent(display, mockAd);
+            final DisplayContent displayContent = mWm.mRoot.createDisplayContent(display, mockAd);
+            displayContent.reconfigureDisplayLocked();
+            return displayContent;
         }
     }
 
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index e1ffb0f..b2fde54 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -33,7 +33,6 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.pm.ShortcutServiceInternal;
@@ -79,6 +78,7 @@
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.UiThread;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
 import com.android.server.soundtrigger.SoundTriggerInternal;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
@@ -120,10 +120,10 @@
         mUserManager = Preconditions.checkNotNull(
                 context.getSystemService(UserManager.class));
 
-        PackageManagerInternal packageManagerInternal = LocalServices.getService(
-                PackageManagerInternal.class);
-        packageManagerInternal.setVoiceInteractionPackagesProvider(
-                new PackageManagerInternal.PackagesProvider() {
+        PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService(
+                PermissionManagerServiceInternal.class);
+        permissionManagerInternal.setVoiceInteractionPackagesProvider(
+                new PermissionManagerServiceInternal.PackagesProvider() {
             @Override
             public String[] getPackages(int userId) {
                 mServiceStub.initForUser(userId);
diff --git a/startop/scripts/app_startup/run_app_with_prefetch.py b/startop/scripts/app_startup/run_app_with_prefetch.py
index 8a9135b..464742d 100644
--- a/startop/scripts/app_startup/run_app_with_prefetch.py
+++ b/startop/scripts/app_startup/run_app_with_prefetch.py
@@ -101,7 +101,7 @@
 
   return parser.parse_args(argv)
 
-def validate_options(args: argparse.Namespace) -> Tuple[bool, RunCommandArgs]:
+def validate_options(args: RunCommandArgs) -> Tuple[bool, RunCommandArgs]:
   """Validates the activity and trace file if needed.
 
   Returns:
diff --git a/startop/scripts/app_startup/run_app_with_prefetch_test.py b/startop/scripts/app_startup/run_app_with_prefetch_test.py
index a642385..8536ce5 100644
--- a/startop/scripts/app_startup/run_app_with_prefetch_test.py
+++ b/startop/scripts/app_startup/run_app_with_prefetch_test.py
@@ -156,7 +156,8 @@
   args = '--package com.fake.package --activity act -s'
   opts = run.parse_options(shlex.split(args))
 
-  result = run.run_test(opts)
+  args = run.get_args_from_opts(opts)
+  result = run.run_test(args)
   assert result == [('TotalTime', '123')]
 
 def test_set_up_adb_env():
diff --git a/startop/scripts/iorap/compiler.py b/startop/scripts/iorap/compiler.py
index 7914960..1e15736 100755
--- a/startop/scripts/iorap/compiler.py
+++ b/startop/scripts/iorap/compiler.py
@@ -23,20 +23,18 @@
 # $> pip3 install --user protobuf sqlalchemy sqlite3
 #
 
-import collections
 import optparse
 import os
 import re
 import sys
+from typing import Iterable, Optional
 
-from typing import Iterable
-
-from lib.inode2filename import Inode2Filename
 from generated.TraceFile_pb2 import *
+from lib.inode2filename import Inode2Filename
 
 parent_dir_name = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
 sys.path.append(parent_dir_name + "/trace_analyzer")
-from lib.trace2db import Trace2Db, MmFilemapAddToPageCache
+from lib.trace2db import Trace2Db, MmFilemapAddToPageCache, RawFtraceEntry
 
 _PAGE_SIZE = 4096 # adb shell getconf PAGESIZE ## size of a memory page in bytes.
 
@@ -165,9 +163,32 @@
 
   return trace_file
 
-def query_add_to_page_cache(trace2db: Trace2Db):
+def calc_trace_end_time(trace2db: Trace2Db,
+                        trace_duration: Optional[int]) -> float:
+  """
+  Calculates the end time based on the trace duration.
+  The start time is the first receiving mm file map event.
+  The end time is the start time plus the trace duration.
+  All of them are in milliseconds.
+  """
+  # If the duration is not set, assume all time is acceptable.
+  if trace_duration is None:
+    # float('inf')
+    return RawFtraceEntry.__table__.c.timestamp.type.python_type('inf')
+
+  first_event = trace2db.session.query(MmFilemapAddToPageCache).join(
+      MmFilemapAddToPageCache.raw_ftrace_entry).order_by(
+      RawFtraceEntry.timestamp).first()
+
+  return first_event.raw_ftrace_entry.timestamp + trace_duration
+
+def query_add_to_page_cache(trace2db: Trace2Db, trace_duration: Optional[int]):
+  end_time = calc_trace_end_time(trace2db, trace_duration)
   # SELECT * FROM tbl ORDER BY id;
-  return trace2db.session.query(MmFilemapAddToPageCache).order_by(MmFilemapAddToPageCache.id).all()
+  return trace2db.session.query(MmFilemapAddToPageCache).join(
+      MmFilemapAddToPageCache.raw_ftrace_entry).filter(
+      RawFtraceEntry.timestamp <= end_time).order_by(
+      MmFilemapAddToPageCache.id).all()
 
 def main(argv):
   parser = optparse.OptionParser(usage="Usage: %prog [options]", description="Compile systrace file into TraceFile.pb")
@@ -188,6 +209,9 @@
   parser.add_option('-o', dest='output_file', metavar='FILE',
                     help='Output protobuf file')
 
+  parser.add_option('--duration', dest='trace_duration', action="store",
+                    type=int, help='The duration of trace in milliseconds.')
+
   options, categories = parser.parse_args(argv[1:])
 
   # TODO: OptionParser should have some flags to make these mandatory.
@@ -217,7 +241,8 @@
   # TODO: parse multiple trace files here.
   parse_count = trace2db.parse_file_into_db(options.trace_file)
 
-  mm_filemap_add_to_page_cache_rows = query_add_to_page_cache(trace2db)
+  mm_filemap_add_to_page_cache_rows = query_add_to_page_cache(trace2db,
+                                                              options.trace_duration)
   print("DONE. Parsed %d entries into sql db." %(len(mm_filemap_add_to_page_cache_rows)))
 
   page_runs = page_cache_entries_to_runs(mm_filemap_add_to_page_cache_rows)
@@ -241,4 +266,6 @@
 
   return 0
 
-sys.exit(main(sys.argv))
+if __name__ == '__main__':
+  print(sys.argv)
+  sys.exit(main(sys.argv))
diff --git a/startop/scripts/iorap/compiler_test.py b/startop/scripts/iorap/compiler_test.py
new file mode 100644
index 0000000..fcb7269
--- /dev/null
+++ b/startop/scripts/iorap/compiler_test.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python3
+#
+# Copyright 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.
+#
+
+"""
+Unit tests for the compiler.py script.
+
+Install:
+  $> sudo apt-get install python3-pytest   ##  OR
+  $> pip install -U pytest
+See also https://docs.pytest.org/en/latest/getting-started.html
+
+Usage:
+  $> pytest compiler_test.py
+
+See also https://docs.pytest.org/en/latest/usage.html
+"""
+import os
+
+import compiler
+
+DIR = os.path.abspath(os.path.dirname(__file__))
+TEXTCACHE = os.path.join(DIR, 'test_fixtures/compiler/common_textcache')
+SYSTRACE = os.path.join(DIR, 'test_fixtures/compiler/common_systrace')
+ARGV = [os.path.join(DIR, 'compiler.py'), '-i', TEXTCACHE, '-t', SYSTRACE]
+
+def assert_compile_result(output, expected, *extra_argv):
+  argv = ARGV + ['-o', output] + [args for args in extra_argv]
+
+  compiler.main(argv)
+
+  with open(output, 'rb') as f1, open(expected, 'rb') as f2:
+    assert f1.read() == f2.read()
+
+def test_compiler_main(tmpdir):
+  output = tmpdir.mkdir('compiler').join('output')
+
+  # No duration
+  expected = os.path.join(DIR,
+                          'test_fixtures/compiler/test_result_without_duration.TraceFile.pb')
+  assert_compile_result(output, expected)
+
+  # 10ms duration
+  expected = os.path.join(DIR,
+                          'test_fixtures/compiler/test_result_with_duration.TraceFile.pb')
+  assert_compile_result(output, expected, '--duration', '10')
+
+  # 30ms duration
+  expected = os.path.join(DIR,
+                          'test_fixtures/compiler/test_result_without_duration.TraceFile.pb')
+  assert_compile_result(output, expected, '--duration', '30')
diff --git a/startop/scripts/iorap/test_fixtures/compiler/common_systrace b/startop/scripts/iorap/test_fixtures/compiler/common_systrace
new file mode 100644
index 0000000..4573738
--- /dev/null
+++ b/startop/scripts/iorap/test_fixtures/compiler/common_systrace
@@ -0,0 +1,5 @@
+<...>-2965  (-----) [001] .... 10000.746629: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000679ee1ec pfn=1299913 ofs=192512
+<...>-2965  (-----) [001] .... 10010.746664: mm_filemap_add_to_page_cache: dev 253:6 ino 2 page=0000000006cd2fb7 pfn=1296251 ofs=196608
+<...>-2965  (-----) [001] .... 10020.746677: mm_filemap_add_to_page_cache: dev 253:6 ino 3 page=00000000af82f3d6 pfn=1419330 ofs=200704
+<...>-2965  (-----) [001] .... 10030.746693: mm_filemap_add_to_page_cache: dev 253:6 ino 4 page=000000002840f054 pfn=1304928 ofs=204800
+<...>-2965  (-----) [001] .... 10040.746706: mm_filemap_add_to_page_cache: dev 253:6 ino 5 page=000000004a59da17 pfn=1288069 ofs=208896
diff --git a/startop/scripts/iorap/test_fixtures/compiler/common_textcache b/startop/scripts/iorap/test_fixtures/compiler/common_textcache
new file mode 100644
index 0000000..da03004
--- /dev/null
+++ b/startop/scripts/iorap/test_fixtures/compiler/common_textcache
@@ -0,0 +1,2 @@
+64774 1 -1 /system/test1
+64774 3 -1 /data/test2
diff --git a/startop/scripts/iorap/test_fixtures/compiler/test_result_with_duration.TraceFile.pb b/startop/scripts/iorap/test_fixtures/compiler/test_result_with_duration.TraceFile.pb
new file mode 100644
index 0000000..ab3df45
--- /dev/null
+++ b/startop/scripts/iorap/test_fixtures/compiler/test_result_with_duration.TraceFile.pb
Binary files differ
diff --git a/startop/scripts/iorap/test_fixtures/compiler/test_result_without_duration.TraceFile.pb b/startop/scripts/iorap/test_fixtures/compiler/test_result_without_duration.TraceFile.pb
new file mode 100644
index 0000000..17cb116
--- /dev/null
+++ b/startop/scripts/iorap/test_fixtures/compiler/test_result_without_duration.TraceFile.pb
Binary files differ
diff --git a/startop/scripts/trace_analyzer/lib/trace2db.py b/startop/scripts/trace_analyzer/lib/trace2db.py
index f60d6ab..42a33af 100644
--- a/startop/scripts/trace_analyzer/lib/trace2db.py
+++ b/startop/scripts/trace_analyzer/lib/trace2db.py
@@ -19,6 +19,7 @@
 from sqlalchemy import create_engine
 from sqlalchemy import Column, Date, Integer, Float, String, ForeignKey
 from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import relationship
 
 from sqlalchemy.orm import sessionmaker
 
@@ -43,6 +44,10 @@
   function = Column(String, nullable=False)
   function_args = Column(String, nullable=False)
 
+  # 1:1 relation with MmFilemapAddToPageCache.
+  mm_filemap_add_to_page_cache = relationship("MmFilemapAddToPageCache",
+                                              back_populates="raw_ftrace_entry")
+
   @staticmethod
   def parse_dict(line):
     # '           <...>-5521  (-----) [003] ...1 17148.446877: tracing_mark_write: trace_event_clock_sync: parent_ts=17148.447266'
@@ -155,6 +160,9 @@
   pfn = Column(Integer, nullable=False)
   ofs = Column(Integer, nullable=False)
 
+  # 1:1 relation with RawFtraceEntry.
+  raw_ftrace_entry = relationship("RawFtraceEntry", uselist=False)
+
   @staticmethod
   def parse_dict(function_args, id = None):
     # dev 253:6 ino b2c7 page=00000000ec787cd9 pfn=1478539 ofs=4096
@@ -251,6 +259,8 @@
 def parse_file_buf(filebuf, session, engine, raw_ftrace_entry_filter, limit=None) -> int:
   global _FLUSH_LIMIT
   count = 0
+  # count and id are not equal, because count still increases for invalid lines.
+  id = 0
 
   pending_entries = []
   pending_sched_switch = []
@@ -305,9 +315,10 @@
       continue
 
     pending_entries.append(raw_ftrace_entry)
+    id = id + 1
 
     if raw_ftrace_entry['function'] == 'sched_switch':
-      sched_switch = SchedSwitch.parse_dict(raw_ftrace_entry['function_args'], count)
+      sched_switch = SchedSwitch.parse_dict(raw_ftrace_entry['function_args'], id)
 
       if not sched_switch:
         print("WARNING: Failed to parse sched_switch: " + l)
@@ -315,7 +326,7 @@
         pending_sched_switch.append(sched_switch)
 
     elif raw_ftrace_entry['function'] == 'sched_blocked_reason':
-      sbr = SchedBlockedReason.parse_dict(raw_ftrace_entry['function_args'], count)
+      sbr = SchedBlockedReason.parse_dict(raw_ftrace_entry['function_args'], id)
 
       if not sbr:
         print("WARNING: Failed to parse sched_blocked_reason: " + l)
@@ -323,7 +334,8 @@
         pending_sched_blocked_reasons.append(sbr)
 
     elif raw_ftrace_entry['function'] == 'mm_filemap_add_to_page_cache':
-      d = MmFilemapAddToPageCache.parse_dict(raw_ftrace_entry['function_args'], count)
+      d = MmFilemapAddToPageCache.parse_dict(raw_ftrace_entry['function_args'],
+                                             id)
       if not d:
         print("WARNING: Failed to parse mm_filemap_add_to_page_cache: " + l)
       else:
diff --git a/startop/scripts/trace_analyzer/lib/trace2db_test.py b/startop/scripts/trace_analyzer/lib/trace2db_test.py
index b67cffa..3b326f0 100755
--- a/startop/scripts/trace_analyzer/lib/trace2db_test.py
+++ b/startop/scripts/trace_analyzer/lib/trace2db_test.py
@@ -32,17 +32,10 @@
 """
 
 # global imports
-from contextlib import contextmanager
 import io
-import shlex
-import sys
-import typing
-
 from copy import deepcopy
 
 # pip imports
-import pytest
-
 # local imports
 from trace2db import *
 
@@ -197,6 +190,33 @@
   assert_eq_ignore_id(MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
       ino=0x9a64, page=0x000000006e0f8322, pfn=797894, ofs=4096), second_to_last_row)
 
+def test_timestamp_filter():
+  test_contents = """
+    MediaStoreImpor-27212 (27176) [000] .... 16136.595194: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744
+    NonUserFacing6-5246  ( 1322) [005] .... 16139.357581: mm_filemap_add_to_page_cache: dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096
+    MediaStoreImpor-27212 (27176) [000] .... 16136.604126: mm_filemap_add_to_page_cache: dev 253:6 ino b1d8 page=0000000098d4d2e2 pfn=829676 ofs=0
+  """
+
+  t2d = parse_trace_file_to_db(test_contents)
+  session = t2d.session
+
+  end_time = 16137.0
+
+  results = session.query(MmFilemapAddToPageCache).join(
+      MmFilemapAddToPageCache.raw_ftrace_entry).filter(
+      RawFtraceEntry.timestamp <= end_time).order_by(
+      MmFilemapAddToPageCache.id).all()
+
+  assert len(results) == 2
+  assert_eq_ignore_id(
+      MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
+                              ino=0x7580, page=0x0000000060e990c7, pfn=677646,
+                              ofs=159744), results[0])
+  assert_eq_ignore_id(
+      MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
+                              ino=0xb1d8, page=0x0000000098d4d2e2, pfn=829676,
+                              ofs=0), results[1])
+
 
 if __name__ == '__main__':
   pytest.main()
diff --git a/startop/scripts/trace_analyzer/test_fixtures/common_systrace b/startop/scripts/trace_analyzer/test_fixtures/common_systrace
new file mode 100644
index 0000000..802cb55
--- /dev/null
+++ b/startop/scripts/trace_analyzer/test_fixtures/common_systrace
@@ -0,0 +1,518 @@
+# tracer: nop
+#
+# entries-in-buffer/entries-written: 411983/411983   #P:8
+#
+#                                      _-----=> irqs-off
+#                                     / _----=> need-resched
+#                                    | / _---=> hardirq/softirq
+#                                    || / _--=> preempt-depth
+#                                    ||| /     delay
+#           TASK-PID    TGID   CPU#  ||||    TIMESTAMP  FUNCTION
+#              | |        |      |   ||||       |         |
+           <...>-14603 (-----) [000] ...1 14592.893157: tracing_mark_write: trace_event_clock_sync: parent_ts=14592.892578
+           <...>-14603 (-----) [000] ...1 14592.893172: tracing_mark_write: trace_event_clock_sync: realtime_ts=1557129597951
+           <...>-18150 (-----) [004] d..2 14594.182110: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=kworker/u16:16 next_pid=23269 next_prio=120
+  kworker/u16:16-23269 (23269) [004] d.h3 14594.182228: sched_blocked_reason: pid=18150 iowait=0 caller=a6xx_oob_set+0x194/0x3dc
+  kworker/u16:16-23269 (23269) [004] d..2 14594.182248: sched_switch: prev_comm=kworker/u16:16 prev_pid=23269 prev_prio=120 prev_state=D ==> next_comm=kworker/u16:18 next_pid=18150 next_prio=120
+           <...>-18150 (-----) [004] d..2 14594.182312: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
+           <...>-18150 (-----) [004] d..2 14594.182488: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
+  kworker/u16:16-23269 (23269) [005] d..2 14594.182610: sched_switch: prev_comm=kworker/u16:16 prev_pid=23269 prev_prio=120 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
+           <...>-18150 (-----) [004] d..2 14594.182626: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
+           <...>-18150 (-----) [004] d..2 14594.182755: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
+           <...>-18150 (-----) [004] d..2 14594.182975: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
+           <...>-18150 (-----) [004] d..2 14594.183209: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
+           <...>-18150 (-----) [004] d..2 14594.183371: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
+           <...>-18150 (-----) [004] d..2 14594.184286: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120
+  kworker/u16:16-23269 (23269) [005] d..2 14594.184495: sched_switch: prev_comm=kworker/u16:16 prev_pid=23269 prev_prio=120 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
+           <...>-18150 (-----) [004] d..2 14594.184498: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120
+     ksoftirqd/4-47    (   47) [004] d..2 14594.185678: sched_switch: prev_comm=ksoftirqd/4 prev_pid=47 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120
+     kworker/6:2-10610 (10610) [006] d..2 14594.186012: sched_switch: prev_comm=kworker/6:2 prev_pid=10610 prev_prio=120 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
+           <...>-656   (-----) [001] .... 14594.219464: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
+           <...>-1803  (-----) [000] d..2 14594.219595: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
+           <...>-3359  (-----) [001] ...1 14594.219856: tracing_mark_write: S|1368|launching: com.google.android.dialer|0
+           <...>-3359  (-----) [001] ...1 14594.219863: tracing_mark_write: B|1368|MetricsLogger:launchObserverNotifyActivityLaunched
+           <...>-3359  (-----) [001] ...1 14594.219869: tracing_mark_write: B|1368|MetricsLogger:convertActivityRecordToProto
+           <...>-1398  (-----) [006] ...1 14594.220160: tracing_mark_write: B|1368|updateInputWindows
+           <...>-3359  (-----) [001] .... 14594.220230: binder_set_priority: proc=1368 thread=3359 old=110 => new=120 desired=120
+           <...>-1398  (-----) [006] ...1 14594.220588: tracing_mark_write: B|1368|android.os.Handler: com.android.server.wm.AppWindowToken$1
+           <...>-1398  (-----) [006] ...1 14594.220722: tracing_mark_write: B|1368|ResourcesManager#getResources
+           <...>-1052  (-----) [002] d..2 14594.220884: sched_switch: prev_comm=statsd.writer prev_pid=1052 prev_prio=120 prev_state=S ==> next_comm=UiThreadHelper next_pid=2045 next_prio=118
+           <...>-1398  (-----) [006] ...1 14594.220926: tracing_mark_write: B|1368|Theme::ApplyStyle
+           <...>-1398  (-----) [006] ...1 14594.220929: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-2007  (-----) [007] ...1 14594.220996: tracing_mark_write: B|2007|Choreographer#doFrame
+           <...>-2007  (-----) [007] ...1 14594.221005: tracing_mark_write: B|2007|animation
+           <...>-1398  (-----) [006] ...1 14594.221015: tracing_mark_write: B|1368|ResourcesManager#getResources
+           <...>-2045  (-----) [002] ...2 14594.221035: binder_set_priority: proc=1368 thread=1903 old=120 => new=118 desired=118
+           <...>-2045  (-----) [002] d..2 14594.221065: sched_switch: prev_comm=UiThreadHelper prev_pid=2045 prev_prio=118 prev_state=S ==> next_comm=Binder:1368_4 next_pid=1903 next_prio=118
+           <...>-1398  (-----) [006] ...1 14594.221080: tracing_mark_write: B|1368|AssetManager::SetApkAssets
+           <...>-2007  (-----) [007] ...1 14594.221110: tracing_mark_write: B|2007|traversal
+           <...>-656   (-----) [000] ...1 14594.221137: tracing_mark_write: B|625|requestNextVsync
+           <...>-656   (-----) [000] ...1 14594.221141: tracing_mark_write: B|625|resetIdleTimer
+           <...>-2007  (-----) [007] ...1 14594.221146: tracing_mark_write: B|2007|draw
+           <...>-2007  (-----) [007] ...1 14594.221160: tracing_mark_write: B|2007|Record View#draw()
+           <...>-660   (-----) [005] d..2 14594.221285: sched_switch: prev_comm=app prev_pid=660 prev_prio=97 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110
+           <...>-658   (-----) [004] d..2 14594.221327: sched_switch: prev_comm=DispSync prev_pid=658 prev_prio=97 prev_state=S ==> next_comm=android.display next_pid=1397 next_prio=117
+           <...>-2738  (-----) [005] ...1 14594.221342: tracing_mark_write: B|2007|notifyFramePending
+           <...>-2738  (-----) [005] ...1 14594.221362: tracing_mark_write: B|2007|DrawFrame
+           <...>-2738  (-----) [005] ...1 14594.221369: tracing_mark_write: B|2007|query
+           <...>-2007  (-----) [007] d..2 14594.221369: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
+           <...>-1903  (-----) [002] .... 14594.221397: binder_set_priority: proc=1368 thread=1903 old=118 => new=120 desired=120
+           <...>-2738  (-----) [005] ...2 14594.221400: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
+           <...>-2738  (-----) [005] d..2 14594.221430: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
+           <...>-1368  (-----) [003] ...1 14594.221431: tracing_mark_write: B|1368|Lock contention on GC thread flip lock (owner tid: 0)
+           <...>-656   (-----) [005] ...1 14594.221460: tracing_mark_write: B|625|query
+           <...>-656   (-----) [005] .... 14594.221528: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
+           <...>-2738  (-----) [007] ...1 14594.221552: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...2 14594.221563: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
+           <...>-2738  (-----) [007] d..2 14594.221600: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
+           <...>-1368  (-----) [003] d..2 14594.221623: sched_switch: prev_comm=system_server prev_pid=1368 prev_prio=118 prev_state=S ==> next_comm=swapper/3 next_pid=0 next_prio=120
+           <...>-656   (-----) [007] ...1 14594.221628: tracing_mark_write: B|625|query
+           <...>-23031 (-----) [001] d..2 14594.221643: sched_switch: prev_comm=UiAutomation prev_pid=23031 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-2738  (-----) [007] ...1 14594.221664: tracing_mark_write: B|2007|syncFrameState
+           <...>-2738  (-----) [007] ...1 14594.221697: tracing_mark_write: B|2007|prepareTree
+           <...>-23008 (-----) [005] d..2 14594.221706: sched_switch: prev_comm=hub.uiautomator prev_pid=23008 prev_prio=120 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
+           <...>-656   (-----) [000] .... 14594.221737: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
+           <...>-1803  (-----) [003] d..2 14594.221747: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=swapper/3 next_pid=0 next_prio=120
+           <...>-1397  (-----) [004] d..2 14594.221806: sched_switch: prev_comm=android.display prev_pid=1397 prev_prio=117 prev_state=S ==> next_comm=Binder:2007_A next_pid=4180 next_prio=120
+           <...>-1398  (-----) [006] d..2 14594.221816: sched_switch: prev_comm=android.anim prev_pid=1398 prev_prio=110 prev_state=R ==> next_comm=s.nexuslauncher next_pid=2007 next_prio=110
+           <...>-2738  (-----) [007] ...1 14594.221824: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...1 14594.221830: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...1 14594.221834: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...1 14594.221841: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...1 14594.221843: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...1 14594.221846: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...1 14594.221850: tracing_mark_write: B|2007|dequeueBuffer
+           <...>-2738  (-----) [007] ...2 14594.221864: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
+           <...>-2738  (-----) [007] d..2 14594.221985: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=crtc_event:97 next_pid=303 next_prio=83
+           <...>-2007  (-----) [006] ...1 14594.221989: tracing_mark_write: B|2007|topResumedActivityChangeItem
+           <...>-303   (-----) [007] d..2 14594.222016: sched_switch: prev_comm=crtc_event:97 prev_pid=303 prev_prio=83 prev_state=S ==> next_comm=rcu_preempt next_pid=7 next_prio=120
+     rcu_preempt-7     (    7) [007] d..2 14594.222035: sched_switch: prev_comm=rcu_preempt prev_pid=7 prev_prio=120 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110
+     migration/4-46    (   46) [004] d..2 14594.222037: sched_switch: prev_comm=migration/4 prev_pid=46 prev_prio=0 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
+           <...>-2738  (-----) [007] d..2 14594.222039: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=kworker/u16:18 next_pid=18150 next_prio=120
+           <...>-656   (-----) [004] ...1 14594.222100: tracing_mark_write: B|625|dequeueBuffer
+           <...>-656   (-----) [004] ...1 14594.222114: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2
+           <...>-2007  (-----) [006] ...2 14594.222131: binder_set_priority: proc=1368 thread=1903 old=120 => new=110 desired=110
+           <...>-2007  (-----) [006] d..2 14594.222143: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=UiThreadHelper next_pid=2045 next_prio=118
+           <...>-2613  (-----) [001] d..2 14594.222158: sched_switch: prev_comm=ogle.android.as prev_pid=2613 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-18150 (-----) [007] d..2 14594.222193: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
+           <...>-656   (-----) [004] .... 14594.222220: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
+           <...>-2738  (-----) [007] ...1 14594.222267: tracing_mark_write: B|2007|HWC release fence 36027 has signaled
+           <...>-656   (-----) [007] ...1 14594.223842: tracing_mark_write: B|625|queueBuffer
+           <...>-656   (-----) [007] ...1 14594.223845: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2
+           <...>-656   (-----) [007] ...1 14594.223871: tracing_mark_write: B|625|requestNextVsync
+           <...>-656   (-----) [007] ...1 14594.223873: tracing_mark_write: B|625|resetIdleTimer
+           <...>-656   (-----) [007] ...1 14594.223881: tracing_mark_write: B|625|addAndGetFrameTimestamps
+           <...>-1395  (-----) [001] d..2 14594.223909: sched_switch: prev_comm=android.ui prev_pid=1395 prev_prio=118 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-2738  (-----) [007] ...1 14594.223959: tracing_mark_write: B|2007|Trace GPU completion fence 36027
+           <...>-11799 (-----) [006] ...1 14594.224006: tracing_mark_write: B|2007|waiting for GPU completion 36027
+           <...>-11799 (-----) [006] ...1 14594.224009: tracing_mark_write: B|2007|waitForever
+           <...>-2613  (-----) [004] d..2 14594.224014: sched_switch: prev_comm=ogle.android.as prev_pid=2613 prev_prio=120 prev_state=S ==> next_comm=Binder:1803_6 next_pid=2173 next_prio=120
+           <...>-11799 (-----) [006] d..1 14594.224014: fence_enable_signal: driver=kgsl-timeline timeline=kgsl-3d0_13-s.nexuslauncher(200 context=27 seqno=78002
+           <...>-11799 (-----) [006] d..2 14594.224021: sched_switch: prev_comm=GPU completion prev_pid=11799 prev_prio=110 prev_state=S ==> next_comm=rcuop/6 next_pid=68 next_prio=120
+         rcuop/6-68    (   68) [006] d..2 14594.224044: sched_switch: prev_comm=rcuop/6 prev_pid=68 prev_prio=120 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
+           <...>-259   (-----) [006] d..2 14594.224132: sched_switch: prev_comm=kgsl_worker_thr prev_pid=259 prev_prio=97 prev_state=S ==> next_comm=Binder:2007_A next_pid=4180 next_prio=120
+           <...>-3206  (-----) [001] d..2 14594.224167: sched_switch: prev_comm=aiai-vc-0 prev_pid=3206 prev_prio=139 prev_state=R ==> next_comm=ndroid.systemui next_pid=1803 next_prio=120
+    lowpool[847]-14589 ( 2446) [005] d..1 14594.224300: mm_filemap_delete_from_page_cache: dev 0:1 ino 3d0034 page=000000008247d586 pfn=676904 ofs=0
+           <...>-1803  (-----) [001] d..2 14594.224302: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=aiai-vc-0 next_pid=3206 next_prio=139
+           <...>-3206  (-----) [001] d..2 14594.224433: sched_switch: prev_comm=aiai-vc-0 prev_pid=3206 prev_prio=139 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-1903  (-----) [003] ...1 14594.224490: tracing_mark_write: B|1368|dispatchingStartProcess:com.google.android.dialer
+           <...>-1903  (-----) [003] ...1 14594.224659: tracing_mark_write: B|1368|wmLayout
+           <...>-1903  (-----) [003] ...1 14594.224666: tracing_mark_write: B|1368|performSurfacePlacement
+           <...>-1903  (-----) [003] ...1 14594.224683: tracing_mark_write: B|1368|applySurfaceChanges
+           <...>-1903  (-----) [003] ...1 14594.224688: tracing_mark_write: B|1368|openSurfaceTransaction
+           <...>-2738  (-----) [007] ...1 14594.224711: tracing_mark_write: B|2007|query
+           <...>-1903  (-----) [003] ...1 14594.224714: tracing_mark_write: B|1368|performLayout
+           <...>-2738  (-----) [007] ...1 14594.224714: tracing_mark_write: B|2007|query
+           <...>-1903  (-----) [003] ...1 14594.224723: tracing_mark_write: B|1368|applyPostLayoutPolicy
+           <...>-2738  (-----) [007] d..2 14594.224752: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
+           <...>-656   (-----) [007] .... 14594.224766: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
+           <...>-1398  (-----) [002] ...1 14594.224801: tracing_mark_write: B|1368|Theme::ApplyStyle
+           <...>-1398  (-----) [002] ...1 14594.224805: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-1398  (-----) [002] ...1 14594.224820: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-1398  (-----) [002] ...1 14594.224826: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-1398  (-----) [002] ...1 14594.224833: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-1398  (-----) [002] ...1 14594.224838: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-1398  (-----) [002] ...1 14594.224846: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-1398  (-----) [002] ...1 14594.224853: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-1398  (-----) [002] ...1 14594.224859: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-1398  (-----) [002] ...1 14594.224864: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-18150 (-----) [006] d..2 14594.228407: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=R+ ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98
+           <...>-2738  (-----) [007] d..2 14594.228411: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=kworker/7:0H next_pid=76 next_prio=100
+           <...>-1409  (-----) [004] ...1 14594.228417: tracing_mark_write: B|1368|Start proc: com.google.android.dialer
+           <...>-440   (-----) [006] d..2 14594.228418: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=kworker/u16:18 next_pid=18150 next_prio=120
+           <...>-76    (-----) [007] d..2 14594.228430: sched_switch: prev_comm=kworker/7:0H prev_pid=76 prev_prio=100 prev_state=R+ ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98
+           <...>-440   (-----) [007] d..2 14594.228434: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=kworker/7:0H next_pid=76 next_prio=100
+           <...>-18150 (-----) [006] d..3 14594.228442: sched_blocked_reason: pid=1398 iowait=1 caller=wait_on_page_bit_common+0x2a8/0x5f8
+           <...>-76    (-----) [007] d..2 14594.228442: sched_switch: prev_comm=kworker/7:0H prev_pid=76 prev_prio=100 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110
+           <...>-2738  (-----) [007] ...2 14594.228446: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
+           <...>-18150 (-----) [006] d..2 14594.228447: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=R+ ==> next_comm=android.anim next_pid=1398 next_prio=110
+           <...>-2738  (-----) [007] d..2 14594.228479: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
+           <...>-1409  (-----) [004] d..2 14594.228499: sched_switch: prev_comm=ActivityManager prev_pid=1409 prev_prio=118 prev_state=D ==> next_comm=Binder:965_2 next_pid=1041 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.229271: tracing_mark_write: B|625|handleTransaction
+           <...>-1773  (-----) [004] .... 14594.229285: binder_set_priority: proc=625 thread=1773 old=110 => new=120 desired=120
+           <...>-440   (-----) [007] d..2 14594.229301: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=RenderThread next_pid=2738 next_prio=110
+           <...>-2738  (-----) [007] ...1 14594.229318: tracing_mark_write: B|2007|HWC release fence 36028 has signaled
+           <...>-2738  (-----) [007] ...1 14594.229331: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...1 14594.229337: tracing_mark_write: B|2007|eglBeginFrame
+           <...>-2738  (-----) [007] ...1 14594.229352: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...1 14594.229354: tracing_mark_write: B|2007|query
+           <...>-791   (-----) [000] d..2 14594.229357: sched_switch: prev_comm=main prev_pid=791 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.229440: tracing_mark_write: B|625|doTransaction
+           <...>-13916 (-----) [002] d..2 14594.229482: sched_switch: prev_comm=HeapTaskDaemon prev_pid=13916 prev_prio=124 prev_state=D|K ==> next_comm=swapper/2 next_pid=0 next_prio=120
+           <...>-13917 (-----) [001] d..2 14594.229492: sched_blocked_reason: pid=13916 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-625   (-----) [003] ...1 14594.229492: tracing_mark_write: B|625|doTransaction
+           <...>-625   (-----) [003] ...1 14594.229507: tracing_mark_write: B|625|doTransaction
+           <...>-13917 (-----) [001] d..2 14594.229523: sched_switch: prev_comm=ReferenceQueueD prev_pid=13917 prev_prio=124 prev_state=D ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-13916 (-----) [002] d..2 14594.229535: sched_blocked_reason: pid=13917 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-625   (-----) [003] ...1 14594.229538: tracing_mark_write: B|625|doTransaction
+           <...>-2738  (-----) [007] ...1 14594.229543: tracing_mark_write: B|2007|flush commands
+           <...>-13916 (-----) [002] .... 14594.229562: sched_process_exit: comm=HeapTaskDaemon pid=13916 prio=124
+           <...>-625   (-----) [003] ...1 14594.229567: tracing_mark_write: B|625|doTransaction
+           <...>-625   (-----) [003] ...1 14594.229588: tracing_mark_write: B|625|doTransaction
+           <...>-625   (-----) [003] ...1 14594.229628: tracing_mark_write: B|625|doTransaction
+           <...>-625   (-----) [003] ...1 14594.229652: tracing_mark_write: B|625|doTransaction
+           <...>-13916 (-----) [002] d..2 14594.229676: sched_switch: prev_comm=HeapTaskDaemon prev_pid=13916 prev_prio=124 prev_state=x ==> next_comm=swapper/2 next_pid=0 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.229676: tracing_mark_write: B|625|doTransaction
+           <...>-2007  (-----) [006] d..2 14594.229688: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.229703: tracing_mark_write: B|625|doTransaction
+           <...>-625   (-----) [003] ...1 14594.229725: tracing_mark_write: B|625|doTransaction
+           <...>-625   (-----) [003] ...1 14594.229750: tracing_mark_write: B|625|doTransaction
+           <...>-625   (-----) [003] ...1 14594.229772: tracing_mark_write: B|625|doTransaction
+           <...>-625   (-----) [003] ...1 14594.229792: tracing_mark_write: B|625|doTransaction
+           <...>-791   (-----) [000] d..2 14594.229811: sched_switch: prev_comm=main prev_pid=791 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.229824: tracing_mark_write: B|625|doTransaction
+           <...>-2738  (-----) [007] ...1 14594.229827: tracing_mark_write: B|2007|eglSwapBuffersWithDamageKHR
+           <...>-13917 (-----) [001] d..2 14594.229836: sched_switch: prev_comm=ReferenceQueueD prev_pid=13917 prev_prio=124 prev_state=D ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-2738  (-----) [007] ...1 14594.229837: tracing_mark_write: B|2007|setSurfaceDamage
+           <...>-625   (-----) [003] ...1 14594.229850: tracing_mark_write: B|625|doTransaction
+           <...>-13918 (-----) [002] d..2 14594.229856: sched_blocked_reason: pid=13917 iowait=0 caller=SyS_madvise+0xd34/0xd3c
+           <...>-5281  (-----) [001] d..2 14594.229932: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=D ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-89    (-----) [006] d..2 14594.229951: sched_switch: prev_comm=lpass_smem_glin prev_pid=89 prev_prio=98 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.229982: tracing_mark_write: B|625|handleMessageInvalidate
+           <...>-625   (-----) [003] ...1 14594.229984: tracing_mark_write: B|625|handlePageFlip
+           <...>-625   (-----) [003] ...1 14594.230013: tracing_mark_write: B|625|latchBuffer
+           <...>-13917 (-----) [000] .... 14594.230015: sched_process_exit: comm=ReferenceQueueD pid=13917 prio=124
+           <...>-625   (-----) [003] ...1 14594.230020: tracing_mark_write: B|625|query
+           <...>-625   (-----) [003] ...1 14594.230028: tracing_mark_write: B|625|updateTexImage
+           <...>-625   (-----) [003] ...1 14594.230035: tracing_mark_write: B|625|acquireBuffer
+           <...>-625   (-----) [003] ...1 14594.230044: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2
+           <...>-2738  (-----) [007] d..2 14594.230057: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=D ==> next_comm=smem_native_lpa next_pid=88 next_prio=120
+           <...>-14607 (-----) [000] d..2 14594.259609: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-2738  (-----) [005] d..2 14594.259620: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=120 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120
+           <...>-1773  (-----) [005] ...1 14594.259649: tracing_mark_write: B|625|query
+           <...>-2738  (-----) [005] ...1 14594.259714: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [005] d..2 14594.259743: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=120 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120
+           <...>-1773  (-----) [005] ...1 14594.259757: tracing_mark_write: B|625|query
+           <...>-2738  (-----) [005] ...1 14594.259810: tracing_mark_write: B|2007|syncFrameState
+           <...>-2738  (-----) [005] ...1 14594.259856: tracing_mark_write: B|2007|prepareTree
+  Binder:14607_1-14624 (14607) [002] ...1 14594.259863: tracing_mark_write: B|14607|AttachCurrentThread
+  Binder:14607_1-14624 (14607) [002] ...1 14594.259869: tracing_mark_write: B|14607|Thread::Attach
+  Binder:14607_1-14624 (14607) [002] ...1 14594.259873: tracing_mark_write: B|14607|Thread birth
+  Binder:14607_1-14624 (14607) [002] ...1 14594.259916: tracing_mark_write: B|14607|Thread::Init
+  Binder:14607_1-14624 (14607) [002] ...1 14594.259920: tracing_mark_write: B|14607|InitStackHwm
+           <...>-14607 (-----) [000] d..2 14594.259932: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_1-14624 (14607) [002] d..2 14594.259941: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-3198  (-----) [001] ...1 14594.259942: tracing_mark_write: B|2007|Update SurfaceView position
+  Binder:14607_1-14624 (14607) [002] ...1 14594.259963: tracing_mark_write: B|14607|InitTlsEntryPoints
+  Binder:14607_1-14624 (14607) [002] ...1 14594.259974: tracing_mark_write: B|14607|InitInterpreterTls
+           <...>-14607 (-----) [000] d..2 14594.260005: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-3198  (-----) [001] d..2 14594.260007: sched_switch: prev_comm=hwuiTask1 prev_pid=3198 prev_prio=118 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-14607 (-----) [000] d..2 14594.260024: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_1-14624 (14607) [002] d..2 14594.260038: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-14607 (-----) [000] d..2 14594.260064: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+  Binder:14607_1-14624 (14607) [002] ...1 14594.260101: tracing_mark_write: B|14607|ThreadList::Register
+           <...>-2738  (-----) [005] ...1 14594.260128: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [005] ...1 14594.260140: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [005] ...1 14594.260148: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [005] ...1 14594.260155: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [005] ...1 14594.260161: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [005] ...1 14594.260167: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [005] ...1 14594.260173: tracing_mark_write: B|2007|dequeueBuffer
+           <...>-2007  (-----) [001] d..2 14594.260201: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-2738  (-----) [005] d..2 14594.260214: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=120 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120
+           <...>-1773  (-----) [005] ...1 14594.260236: tracing_mark_write: B|625|dequeueBuffer
+           <...>-1773  (-----) [005] ...1 14594.260249: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2
+           <...>-14607 (-----) [000] d..2 14594.260334: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_1-14624 (14607) [002] d..2 14594.260343: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-14607 (-----) [000] d..2 14594.260376: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-14607 (-----) [000] d..2 14594.260387: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+           <...>-2738  (-----) [005] ...1 14594.260401: tracing_mark_write: B|2007|HWC release fence 36030 has signaled
+  Binder:14607_1-14624 (14607) [002] d..2 14594.260407: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-2738  (-----) [005] ...1 14594.260419: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [005] ...1 14594.260427: tracing_mark_write: B|2007|eglBeginFrame
+           <...>-2738  (-----) [005] ...1 14594.260445: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [005] ...1 14594.260450: tracing_mark_write: B|2007|query
+  Binder:14607_1-14624 (14607) [002] .... 14594.260472: task_newtask: pid=14625 comm=Binder:14607_1 clone_flags=3d0f00 oom_score_adj=-1000
+           <...>-14607 (-----) [000] d..2 14594.260517: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_2-14625 (14607) [001] d..2 14594.260525: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-14607 (-----) [000] d..2 14594.260555: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-14607 (-----) [000] ...1 14594.260569: tracing_mark_write: B|14607|ActivityThreadMain
+           <...>-14607 (-----) [000] d..2 14594.260581: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_2-14625 (14607) [001] d..2 14594.260588: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-14607 (-----) [000] d..2 14594.260611: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-14607 (-----) [000] d..2 14594.260623: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_2-14625 (14607) [001] d..2 14594.260636: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-14607 (-----) [000] d..2 14594.260663: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-14607 (-----) [000] d..2 14594.260674: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_2-14625 (14607) [001] d..2 14594.260694: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-14607 (-----) [000] d..2 14594.260724: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-2738  (-----) [005] ...1 14594.260734: tracing_mark_write: B|2007|flush commands
+           <...>-14607 (-----) [000] d..2 14594.260735: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_2-14625 (14607) [001] d..2 14594.260753: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+  Binder:14607_2-14625 (14607) [001] ...1 14594.260925: tracing_mark_write: B|14607|AttachCurrentThread
+  Binder:14607_2-14625 (14607) [001] ...1 14594.260930: tracing_mark_write: B|14607|Thread::Attach
+  Binder:14607_2-14625 (14607) [001] ...1 14594.260933: tracing_mark_write: B|14607|Thread birth
+  Binder:14607_2-14625 (14607) [001] ...1 14594.260973: tracing_mark_write: B|14607|Thread::Init
+  Binder:14607_2-14625 (14607) [001] ...1 14594.260977: tracing_mark_write: B|14607|InitStackHwm
+           <...>-14607 (-----) [000] d..2 14594.260990: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_2-14625 (14607) [001] d..2 14594.260998: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+  Binder:14607_2-14625 (14607) [001] ...1 14594.261023: tracing_mark_write: B|14607|InitTlsEntryPoints
+  Binder:14607_2-14625 (14607) [001] ...1 14594.261034: tracing_mark_write: B|14607|InitInterpreterTls
+           <...>-14607 (-----) [000] d..2 14594.261064: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-14607 (-----) [000] d..2 14594.261075: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_2-14625 (14607) [001] d..2 14594.261094: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-14607 (-----) [000] d..2 14594.261120: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-14607 (-----) [000] d..2 14594.261132: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_2-14625 (14607) [001] d..2 14594.261146: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+  Binder:14607_2-14625 (14607) [001] ...1 14594.261167: tracing_mark_write: B|14607|ThreadList::Register
+           <...>-14607 (-----) [000] d..2 14594.261209: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-2738  (-----) [005] ...1 14594.261212: tracing_mark_write: B|2007|waitOnFences
+           <...>-14607 (-----) [000] d..2 14594.261220: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+           <...>-2738  (-----) [005] ...1 14594.261232: tracing_mark_write: B|2007|eglSwapBuffersWithDamageKHR
+           <...>-2738  (-----) [005] ...1 14594.261244: tracing_mark_write: B|2007|setSurfaceDamage
+  Binder:14607_2-14625 (14607) [001] d..2 14594.261246: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-14607 (-----) [000] ...1 14594.261326: tracing_mark_write: B|14607|VerifyClass com.android.org.conscrypt.TrustedCertificateStore$PreloadHolder
+           <...>-2738  (-----) [005] .... 14594.261621: fence_init: driver=kgsl-timeline timeline=kgsl-3d0_13-s.nexuslauncher(200 context=27 seqno=78005
+           <...>-625   (-----) [003] ...1 14594.263903: tracing_mark_write: B|625|resetIdleTimer
+           <...>-625   (-----) [003] ...1 14594.263912: tracing_mark_write: B|625|rebuildLayerStacks
+           <...>-625   (-----) [003] ...1 14594.263915: tracing_mark_write: B|625|rebuildLayerStacks VR Dirty
+           <...>-625   (-----) [003] ...1 14594.263919: tracing_mark_write: B|625|computeVisibleRegions
+           <...>-1398  (-----) [006] d..2 14594.263966: sched_switch: prev_comm=android.anim prev_pid=1398 prev_prio=110 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120
+           <...>-1695  (-----) [001] d..2 14594.264086: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=S ==> next_comm=Binder:1368_14 next_pid=3253 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.264293: tracing_mark_write: B|625|calculateWorkingSet
+           <...>-625   (-----) [003] ...1 14594.264500: tracing_mark_write: B|625|prepare
+           <...>-625   (-----) [003] ...1 14594.264513: tracing_mark_write: B|625|HIDL::IComposerClient::executeCommands_2_2::client
+           <...>-625   (-----) [003] ...2 14594.264584: binder_set_priority: proc=627 thread=627 old=97 => new=98 desired=98
+           <...>-625   (-----) [003] d..2 14594.264617: sched_switch: prev_comm=surfaceflinger prev_pid=625 prev_prio=98 prev_state=S ==> next_comm=logd.writer next_pid=588 next_prio=130
+           <...>-588   (-----) [003] d..2 14594.264851: sched_switch: prev_comm=logd.writer prev_pid=588 prev_prio=130 prev_state=S ==> next_comm=swapper/3 next_pid=0 next_prio=120
+     rcu_preempt-7     (    7) [007] d..2 14594.265273: sched_switch: prev_comm=rcu_preempt prev_pid=7 prev_prio=120 prev_state=S ==> next_comm=kworker/u16:3 next_pid=18008 next_prio=120
+           <...>-18008 (-----) [007] d..2 14594.265404: sched_switch: prev_comm=kworker/u16:3 prev_pid=18008 prev_prio=120 prev_state=D ==> next_comm=swapper/7 next_pid=0 next_prio=120
+           <...>-18008 (-----) [007] d..2 14594.265471: sched_switch: prev_comm=kworker/u16:3 prev_pid=18008 prev_prio=120 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.265496: tracing_mark_write: B|625|doComposition
+           <...>-625   (-----) [003] ...1 14594.265507: tracing_mark_write: B|625|doComposeSurfaces
+           <...>-625   (-----) [003] ...1 14594.265552: tracing_mark_write: B|625|acquireBuffer
+           <...>-625   (-----) [003] ...1 14594.265563: tracing_mark_write: B|625|postFramebuffer
+           <...>-625   (-----) [003] ...1 14594.265567: tracing_mark_write: B|625|presentAndGetReleaseFences
+           <...>-625   (-----) [003] d..1 14594.265601: fence_enable_signal: driver=sde_fence:crtc97:91650 timeline=crtc97 context=3 seqno=91650
+           <...>-625   (-----) [003] ...1 14594.265735: tracing_mark_write: B|625|logLayerStats
+           <...>-625   (-----) [003] ...1 14594.265744: tracing_mark_write: B|625|postComposition
+           <...>-625   (-----) [003] ...1 14594.265749: tracing_mark_write: B|625|releaseBuffer
+           <...>-625   (-----) [003] ...1 14594.265753: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 1
+           <...>-625   (-----) [003] ...1 14594.265791: tracing_mark_write: B|625|releaseBuffer
+           <...>-440   (-----) [007] d..2 14594.342366: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=kworker/u17:2 next_pid=1778 next_prio=100
+           <...>-2007  (-----) [006] ...1 14594.342375: tracing_mark_write: B|2007|input
+           <...>-2007  (-----) [006] ...1 14594.342399: tracing_mark_write: B|2007|animation
+           <...>-625   (-----) [003] ...1 14594.342447: tracing_mark_write: B|625|doTransaction
+           <...>-625   (-----) [003] ...1 14594.342489: tracing_mark_write: B|625|doTransaction
+   kworker/u17:2-1778  ( 1778) [007] d..3 14594.342532: sched_blocked_reason: pid=14607 iowait=1 caller=wait_on_page_bit_common+0x2a8/0x5f8
+   kworker/u17:2-1778  ( 1778) [007] d..2 14594.342544: sched_switch: prev_comm=kworker/u17:2 prev_pid=1778 prev_prio=100 prev_state=S ==> next_comm=kworker/u16:2 next_pid=27544 next_prio=120
+           <...>-1773  (-----) [000] ...1 14594.342575: tracing_mark_write: B|625|requestNextVsync
+           <...>-1773  (-----) [000] ...1 14594.342579: tracing_mark_write: B|625|resetIdleTimer
+           <...>-27544 (-----) [007] d..2 14594.342589: sched_switch: prev_comm=kworker/u16:2 prev_pid=27544 prev_prio=120 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
+           <...>-656   (-----) [002] d.h3 14594.342604: sched_blocked_reason: pid=1233 iowait=0 caller=geni_i2c_xfer+0x4d8/0x1398
+           <...>-1803  (-----) [001] d..2 14594.342605: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.342632: tracing_mark_write: B|625|handleMessageInvalidate
+           <...>-625   (-----) [003] ...1 14594.342634: tracing_mark_write: B|625|handlePageFlip
+           <...>-2738  (-----) [007] ...1 14594.342641: tracing_mark_write: B|2007|notifyFramePending
+           <...>-658   (-----) [002] d..2 14594.342653: sched_switch: prev_comm=DispSync prev_pid=658 prev_prio=97 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=120
+           <...>-656   (-----) [002] ...1 14594.342656: tracing_mark_write: B|625|requestNextVsync
+           <...>-2738  (-----) [007] d..2 14594.342658: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
+           <...>-656   (-----) [002] ...1 14594.342660: tracing_mark_write: B|625|resetIdleTimer
+           <...>-660   (-----) [005] d..2 14594.342663: sched_switch: prev_comm=app prev_pid=660 prev_prio=97 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.342665: tracing_mark_write: B|625|latchBuffer
+           <...>-625   (-----) [003] ...1 14594.342673: tracing_mark_write: B|625|query
+           <...>-625   (-----) [003] ...1 14594.342682: tracing_mark_write: B|625|updateTexImage
+           <...>-625   (-----) [003] ...1 14594.342693: tracing_mark_write: B|625|acquireBuffer
+           <...>-625   (-----) [003] ...1 14594.342703: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 1
+           <...>-660   (-----) [005] d..2 14594.342709: sched_switch: prev_comm=app prev_pid=660 prev_prio=97 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
+           <...>-2007  (-----) [006] ...1 14594.342733: tracing_mark_write: B|2007|traversal
+           <...>-2007  (-----) [006] ...1 14594.342776: tracing_mark_write: B|2007|draw
+           <...>-2007  (-----) [006] ...1 14594.342791: tracing_mark_write: B|2007|Record View#draw()
+           <...>-625   (-----) [003] ...1 14594.342849: tracing_mark_write: B|625|updateInputFlinger
+           <...>-2007  (-----) [006] d..2 14594.342903: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=kworker/6:2H next_pid=24261 next_prio=100
+           <...>-2738  (-----) [007] ...1 14594.342910: tracing_mark_write: B|2007|DrawFrame
+           <...>-2738  (-----) [007] d..2 14594.342917: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98
+           <...>-24261 (-----) [006] d..2 14594.342918: sched_switch: prev_comm=kworker/6:2H prev_pid=24261 prev_prio=100 prev_state=S ==> next_comm=.android.dialer next_pid=14607 next_prio=110
+           <...>-440   (-----) [007] d..2 14594.342926: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=RenderThread next_pid=2738 next_prio=110
+           <...>-2738  (-----) [007] ...1 14594.342927: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...2 14594.342959: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
+           <...>-2738  (-----) [007] d..2 14594.342975: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
+           <...>-656   (-----) [007] ...1 14594.343021: tracing_mark_write: B|625|query
+           <...>-656   (-----) [007] .... 14594.343033: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
+           <...>-2738  (-----) [007] ...1 14594.343070: tracing_mark_write: B|2007|query
+           <...>-1233  (-----) [004] d..2 14594.343074: sched_switch: prev_comm=sound trigger c prev_pid=1233 prev_prio=120 prev_state=R+ ==> next_comm=irq/144-1436400 next_pid=2522 next_prio=49
+           <...>-2738  (-----) [007] ...2 14594.343078: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
+           <...>-625   (-----) [003] ...1 14594.343084: tracing_mark_write: B|625|onMessageReceived
+           <...>-625   (-----) [003] ...1 14594.343087: tracing_mark_write: B|625|handleMessageRefresh
+           <...>-625   (-----) [003] ...1 14594.343090: tracing_mark_write: B|625|preComposition
+           <...>-2738  (-----) [007] d..2 14594.343090: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
+           <...>-625   (-----) [003] ...1 14594.343122: tracing_mark_write: B|625|rebuildLayerStacks
+           <...>-625   (-----) [003] ...1 14594.343124: tracing_mark_write: B|625|rebuildLayerStacks VR Dirty
+           <...>-89    (-----) [007] d..2 14594.343126: sched_switch: prev_comm=lpass_smem_glin prev_pid=89 prev_prio=98 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
+           <...>-625   (-----) [003] ...1 14594.343129: tracing_mark_write: B|625|computeVisibleRegions
+           <...>-656   (-----) [007] ...1 14594.343136: tracing_mark_write: B|625|query
+           <...>-14607 (-----) [006] ...2 14594.343141: binder_set_priority: proc=1368 thread=3253 old=120 => new=110 desired=110
+                      <...>-2965  (-----) [001] .... 14596.746610: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000002ae8fcff pfn=1522884 ofs=188416
+          <idle>-0     (-----) [002] d..2 14596.746619: sched_switch: prev_comm=swapper/2 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98
+           <...>-2965  (-----) [001] .... 14596.746629: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000679ee1ec pfn=1299913 ofs=192512
+           <...>-2965  (-----) [001] .... 14596.746664: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=0000000006cd2fb7 pfn=1296251 ofs=196608
+           <...>-2965  (-----) [001] .... 14596.746677: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000af82f3d6 pfn=1419330 ofs=200704
+           <...>-2965  (-----) [001] .... 14596.746693: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000002840f054 pfn=1304928 ofs=204800
+           <...>-2965  (-----) [001] .... 14596.746706: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000004a59da17 pfn=1288069 ofs=208896
+           <...>-2965  (-----) [001] .... 14596.746717: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=0000000023a80dca pfn=1419686 ofs=212992
+           <...>-2965  (-----) [001] .... 14596.746730: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000001cf89eab pfn=1315372 ofs=217088
+           <...>-2965  (-----) [001] .... 14596.746743: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000005b4c6cb6 pfn=1380698 ofs=221184
+           <...>-2965  (-----) [001] .... 14596.746760: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000f8304ae7 pfn=1206753 ofs=225280
+           <...>-2965  (-----) [001] .... 14596.746773: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000cb912305 pfn=1325465 ofs=229376
+           <...>-2965  (-----) [001] .... 14596.746785: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000f16f3774 pfn=1408056 ofs=233472
+           <...>-2965  (-----) [001] .... 14596.746801: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=0000000056d4c926 pfn=1418352 ofs=237568
+           <...>-2965  (-----) [001] .... 14596.746815: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000f3eeb42c pfn=1320957 ofs=241664
+           <...>-440   (-----) [002] d..2 14596.746916: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=swapper/2 next_pid=0 next_prio=120
+
+           <...>-656   (-----) [007] .... 14594.343145: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
+           <...>-14607 (-----) [006] d..2 14594.343164: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=110 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
+           <...>-5281  (-----) [002] d..2 14594.343177: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110
+ irq/144-1436400-2522  ( 2522) [004] d..2 14594.343223: sched_switch: prev_comm=irq/144-1436400 prev_pid=2522 prev_prio=49 prev_state=D ==> next_comm=sound trigger c next_pid=1233 next_prio=120
+           <...>-88    (-----) [006] d..2 14594.343240: sched_switch: prev_comm=smem_native_lpa prev_pid=88 prev_prio=98 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
+           <...>-1238  (-----) [001] d..2 14594.343243: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-2738  (-----) [002] ...1 14594.343244: tracing_mark_write: B|2007|syncFrameState
+           <...>-2738  (-----) [002] ...1 14594.343293: tracing_mark_write: B|2007|prepareTree
+           <...>-1695  (-----) [001] d..2 14594.343318: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=R+ ==> next_comm=FastMixer next_pid=1238 next_prio=96
+           <...>-5281  (-----) [005] d..2 14594.343322: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:1368_14 next_pid=3253 next_prio=110
+           <...>-1238  (-----) [001] d..2 14594.343442: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=InputDispatcher next_pid=1695 next_prio=112
+           <...>-1695  (-----) [001] d..2 14594.343467: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-5281  (-----) [000] d..2 14594.343484: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.343519: tracing_mark_write: B|625|calculateWorkingSet
+           <...>-2738  (-----) [002] ...1 14594.343568: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [002] ...1 14594.343577: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [002] ...1 14594.343586: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [002] ...1 14594.343591: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [002] ...1 14594.343597: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [002] ...1 14594.343602: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [002] ...1 14594.343609: tracing_mark_write: B|2007|dequeueBuffer
+           <...>-2007  (-----) [006] d..2 14594.343612: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
+           <...>-2738  (-----) [002] ...2 14594.343633: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
+           <...>-2738  (-----) [002] d..2 14594.343683: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
+           <...>-625   (-----) [003] ...1 14594.343704: tracing_mark_write: B|625|prepare
+           <...>-656   (-----) [002] ...1 14594.343707: tracing_mark_write: B|625|dequeueBuffer
+           <...>-625   (-----) [004] ...1 14594.812869: tracing_mark_write: B|625|com.google.android.dialer/com.google.android.dialer.extensions.GoogleDialtactsActivity#0: 2
+           <...>-2048  (-----) [000] d..2 14594.812895: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=Binder:625_3 next_pid=1431 next_prio=120
+           <...>-1431  (-----) [000] ...1 14594.812911: tracing_mark_write: B|625|query
+           <...>-625   (-----) [004] ...1 14594.812914: tracing_mark_write: B|625|latchBuffer
+           <...>-625   (-----) [004] ...1 14594.812919: tracing_mark_write: B|625|query
+           <...>-625   (-----) [004] ...1 14594.812925: tracing_mark_write: B|625|updateTexImage
+           <...>-625   (-----) [004] ...1 14594.812928: tracing_mark_write: B|625|acquireBuffer
+           <...>-625   (-----) [004] ...1 14594.812934: tracing_mark_write: B|625|StatusBar#0: 1
+           <...>-2048  (-----) [000] ...1 14594.812962: tracing_mark_write: B|1803|syncFrameState
+           <...>-656   (-----) [002] ...1 14594.813044: tracing_mark_write: B|625|setTransactionState
+           <...>-14607 (-----) [007] ...2 14594.813083: binder_set_priority: proc=10691 thread=18733 old=120 => new=110 desired=110
+           <...>-14607 (-----) [007] d..2 14594.813114: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=110 prev_state=S ==> next_comm=kworker/7:1 next_pid=7092 next_prio=120
+           <...>-14655 (-----) [006] d..2 14594.813128: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R ==> next_comm=lpass_smem_glin next_pid=89 next_prio=98
+           <...>-89    (-----) [006] d..2 14594.813163: sched_switch: prev_comm=lpass_smem_glin prev_pid=89 prev_prio=98 prev_state=S ==> next_comm=DialerExecutors next_pid=14655 next_prio=130
+           <...>-656   (-----) [002] ...1 14594.813218: tracing_mark_write: B|625|requestNextVsync
+           <...>-656   (-----) [002] ...1 14594.813222: tracing_mark_write: B|625|resetIdleTimer
+     kworker/7:1-7092  ( 7092) [007] d..2 14594.813239: sched_switch: prev_comm=kworker/7:1 prev_pid=7092 prev_prio=120 prev_state=R+ ==> next_comm=smem_native_lpa next_pid=88 next_prio=98
+           <...>-5281  (-----) [001] d..2 14594.813245: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:10691_B next_pid=18733 next_prio=110
+           <...>-88    (-----) [007] d..2 14594.813248: sched_switch: prev_comm=smem_native_lpa prev_pid=88 prev_prio=98 prev_state=R ==> next_comm=kgsl_worker_thr next_pid=259 next_prio=97
+           <...>-2048  (-----) [000] d..2 14594.813249: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=FastMixer next_pid=1238 next_prio=96
+           <...>-14655 (-----) [006] d..2 14594.813263: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R+ ==> next_comm=smem_native_lpa next_pid=88 next_prio=98
+           <...>-661   (-----) [002] d..2 14594.813265: sched_switch: prev_comm=sf prev_pid=661 prev_prio=97 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116
+           <...>-259   (-----) [007] d..2 14594.813265: sched_switch: prev_comm=kgsl_worker_thr prev_pid=259 prev_prio=97 prev_state=S ==> next_comm=kworker/7:1 next_pid=7092 next_prio=120
+     kworker/7:1-7092  ( 7092) [007] d..2 14594.813271: sched_switch: prev_comm=kworker/7:1 prev_pid=7092 prev_prio=120 prev_state=S ==> next_comm=system next_pid=108 next_prio=120
+           <...>-108   (-----) [007] .... 14594.813275: ion_heap_shrink: heap_name=system, len=9469952, total_allocated=189620224
+           <...>-88    (-----) [006] d..2 14594.813294: sched_switch: prev_comm=smem_native_lpa prev_pid=88 prev_prio=98 prev_state=S ==> next_comm=DialerExecutors next_pid=14655 next_prio=130
+           <...>-625   (-----) [004] ...1 14594.813310: tracing_mark_write: B|625|updateInputFlinger
+           <...>-1238  (-----) [000] d..2 14594.813312: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120
+           <...>-661   (-----) [002] d..2 14594.813317: sched_switch: prev_comm=sf prev_pid=661 prev_prio=97 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116
+           <...>-14640 (-----) [005] d..2 14594.813319: sched_switch: prev_comm=DialerExecutors prev_pid=14640 prev_prio=130 prev_state=R ==> next_comm=DispSync next_pid=658 next_prio=97
+           <...>-656   (-----) [002] ...1 14594.813336: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-658   (-----) [005] d..2 14594.813345: sched_switch: prev_comm=DispSync prev_pid=658 prev_prio=97 prev_state=S ==> next_comm=DialerExecutors next_pid=14640 next_prio=130
+           <...>-656   (-----) [002] ...1 14594.813345: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] ...1 14594.813353: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-2048  (-----) [000] d..2 14594.813358: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=FastMixer next_pid=1238 next_prio=96
+           <...>-656   (-----) [002] ...1 14594.813364: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-5281  (-----) [001] d..2 14594.813369: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:10691_B next_pid=18733 next_prio=110
+           <...>-656   (-----) [002] ...1 14594.813372: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] ...1 14594.813380: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] ...1 14594.813391: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] ...1 14594.813398: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] ...1 14594.813408: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] ...1 14594.813416: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] ...1 14594.813424: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] ...1 14594.813432: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] .n.1 14594.813443: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-1238  (-----) [000] d..2 14594.813464: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120
+           <...>-5281  (-----) [002] d..2 14594.813525: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116
+           <...>-656   (-----) [002] ...1 14594.813544: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] ...1 14594.813557: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-2048  (-----) [000] d..2 14594.813594: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=Binder:1368_15 next_pid=3359 next_prio=120
+           <...>-18733 (-----) [001] ...2 14594.813635: binder_set_priority: proc=1368 thread=3514 old=120 => new=110 desired=110
+           <...>-656   (-----) [002] .... 14594.813637: binder_set_priority: proc=625 thread=656 old=116 => new=120 desired=120
+           <...>-108   (-----) [007] d..2 14594.813646: sched_switch: prev_comm=system prev_pid=108 prev_prio=120 prev_state=R+ ==> next_comm=android.anim next_pid=1398 next_prio=116
+           <...>-625   (-----) [004] ...1 14594.813646: tracing_mark_write: B|625|onMessageReceived
+           <...>-625   (-----) [004] ...1 14594.813649: tracing_mark_write: B|625|handleMessageRefresh
+           <...>-625   (-----) [004] ...1 14594.813651: tracing_mark_write: B|625|preComposition
+           <...>-625   (-----) [004] ...1 14594.813693: tracing_mark_write: B|625|rebuildLayerStacks
+           <...>-625   (-----) [004] ...1 14594.813696: tracing_mark_write: B|625|rebuildLayerStacks VR Dirty
+           <...>-625   (-----) [004] ...1 14594.813701: tracing_mark_write: B|625|computeVisibleRegions
+           <...>-1398  (-----) [007] d..2 14594.813718: sched_switch: prev_comm=android.anim prev_pid=1398 prev_prio=116 prev_state=S ==> next_comm=system next_pid=108 next_prio=120
+           <...>-108   (-----) [007] d..2 14594.813739: sched_switch: prev_comm=system prev_pid=108 prev_prio=120 prev_state=R+ ==> next_comm=android.anim next_pid=1398 next_prio=116
+           <...>-1695  (-----) [002] d..2 14594.813970: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=S ==> next_comm=system next_pid=108 next_prio=120
+           <...>-1398  (-----) [007] ...1 14594.814029: tracing_mark_write: B|1368|wmLayout
+           <...>-1398  (-----) [007] ...1 14594.814033: tracing_mark_write: B|1368|performSurfacePlacement
+           <...>-1398  (-----) [007] ...1 14594.814040: tracing_mark_write: B|1368|applySurfaceChanges
+           <...>-1398  (-----) [007] ...1 14594.814043: tracing_mark_write: B|1368|openSurfaceTransaction
+           <...>-1398  (-----) [007] ...1 14594.814063: tracing_mark_write: B|1368|performLayout
+           <...>-625   (-----) [004] ...1 14594.814119: tracing_mark_write: B|625|calculateWorkingSet
+           <...>-1398  (-----) [007] ...1 14594.814241: tracing_mark_write: B|1368|layoutInputConsumer
+           <...>-2048  (-----) [000] ...1 14594.814260: tracing_mark_write: B|1803|prepareTree
+           <...>-1398  (-----) [007] ...1 14594.814263: tracing_mark_write: B|1368|applyPostLayoutPolicy
+           <...>-2048  (-----) [000] d..2 14594.814408: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R ==> next_comm=Binder:1368_15 next_pid=3359 next_prio=120
+           <...>-625   (-----) [004] ...1 14594.814411: tracing_mark_write: B|625|prepare
+           <...>-625   (-----) [004] ...1 14594.814428: tracing_mark_write: B|625|HIDL::IComposerClient::executeCommands_2_2::client
+           <...>-2048  (-----) [000] d..2 14594.814533: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=ndroid.systemui next_pid=1803 next_prio=120
+           <...>-1803  (-----) [000] d..2 14594.814558: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120
+           <...>-2048  (-----) [000] d..2 14594.814572: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=ndroid.systemui next_pid=1803 next_prio=120
+           <...>-625   (-----) [004] ...2 14594.814589: binder_set_priority: proc=627 thread=627 old=97 => new=98 desired=98
+           <...>-108   (-----) [002] d..2 14594.814650: sched_switch: prev_comm=system prev_pid=108 prev_prio=120 prev_state=R+ ==> next_comm=composer@2.2-se next_pid=627 next_prio=98
+           <...>-625   (-----) [004] d..2 14594.814664: sched_switch: prev_comm=surfaceflinger prev_pid=625 prev_prio=98 prev_state=S ==> next_comm=ashmemd next_pid=854 next_prio=129
+           <...>-1398  (-----) [007] ...1 14594.814723: tracing_mark_write: B|1368|applyWindowSurfaceChanges
+           <...>-854   (-----) [004] .... 14594.814746: binder_set_priority: proc=854 thread=854 old=129 => new=120 desired=120
+           <...>-854   (-----) [004] d..2 14594.814757: sched_switch: prev_comm=ashmemd prev_pid=854 prev_prio=120 prev_state=R+ ==> next_comm=highpool[0] next_pid=3493 next_prio=129
+           <...>-1803  (-----) [000] d..2 14594.814763: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120
+           <...>-18733 (-----) [001] d..1 14594.814819: mm_filemap_delete_from_page_cache: dev 0:1 ino 3ce5e7 page=0000000083f10c7a pfn=1298474 ofs=0
+           <...>-2048  (-----) [000] ...1 14594.814842: tracing_mark_write: B|1803|dequeueBuffer
+           <...>-1398  (-----) [007] ...1 14594.814850: tracing_mark_write: F|1368|launching: com.google.android.dialer|0
+           <...>-1398  (-----) [007] ...1 14594.814855: tracing_mark_write: B|1368|MetricsLogger:launchObserverNotifyActivityLaunchFinished
+           <...>-1398  (-----) [007] ...1 14594.814857: tracing_mark_write: B|1368|MetricsLogger:convertActivityRecordToProto
+           <...>-2048  (-----) [000] d..2 14594.814905: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=120
+           <...>-1410  (-----) [006] .... 14592.997816: mm_filemap_add_to_page_cache: dev 253:6 ino b785 page=00000000615a8f24 pfn=1134764 ofs=0
+           <...>-1410  (-----) [006] .... 14592.997831: mm_filemap_add_to_page_cache: dev 253:6 ino b785 page=000000008768a58f pfn=1134751 ofs=4096
+
+           <...>-18733 (-----) [001] .... 14594.814914: binder_set_priority: proc=10691 thread=18733 old=110 => new=120 desired=120
+           <...>-14655 (-----) [006] d..2 14594.814932: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R ==> next_comm=.android.dialer next_pid=14607 next_prio=110
+           <...>-656   (-----) [000] ...1 14594.814948: tracing_mark_write: B|625|dequeueBuffer
+           <...>-3514  (-----) [001] .... 14594.814954: binder_set_priority: proc=1368 thread=3514 old=110 => new=120 desired=120
+           <...>-656   (-----) [000] ...1 14594.814963: tracing_mark_write: B|625|NavigationBar0#0: 2
+           <...>-14607 (-----) [006] ...2 14594.815022: binder_set_priority: proc=1368 thread=3514 old=120 => new=110 desired=110
+           <...>-1398  (-----) [007] ...1 14594.815039: tracing_mark_write: B|1368|prepareSurfaces
+           <...>-14607 (-----) [006] d..2 14594.815041: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=110 prev_state=S ==> next_comm=DialerExecutors next_pid=14655 next_prio=130
+           <...>-3493  (-----) [004] d..2 14594.815057: sched_switch: prev_comm=highpool[0] prev_pid=3493 prev_prio=129 prev_state=R ==> next_comm=Binder:1368_18 next_pid=3514 next_prio=110
+           <...>-2048  (-----) [000] ...1 14594.815088: tracing_mark_write: B|1803|HWC release fence 45750 has signaled
+           <...>-2048  (-----) [000] ...1 14594.815119: tracing_mark_write: B|1803|eglBeginFrame
+           <...>-14655 (-----) [006] d..2 14594.815190: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R ==> next_comm=crtc_commit:97 next_pid=301 next_prio=83
+           <...>-3514  (-----) [004] .... 14594.815193: binder_set_priority: proc=1368 thread=3514 old=110 => new=120 desired=120
+           <...>-1398  (-----) [007] ...1 14594.815322: tracing_mark_write: B|1368|closeSurfaceTransaction
+           <...>-3493  (-----) [004] .... 14594.815353: mm_filemap_add_to_page_cache: dev 253:6 ino 113b page=0000000069e2b98a pfn=628464 ofs=2723840
+           <...>-1398  (-----) [007] ...2 14594.815393: binder_set_priority: proc=625 thread=656 old=120 => new=116 desired=116
+       rcu_sched-8     (    8) [007] d..2 14594.815449: sched_switch: prev_comm=rcu_sched prev_pid=8 prev_prio=120 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116
diff --git a/startop/scripts/trace_analyzer/trace_analyzer_test.py b/startop/scripts/trace_analyzer/trace_analyzer_test.py
new file mode 100644
index 0000000..579529c
--- /dev/null
+++ b/startop/scripts/trace_analyzer/trace_analyzer_test.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+#
+# Copyright 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.
+#
+
+"""
+Unit tests for trace_analyzer module.
+
+Install:
+  $> sudo apt-get install python3-pytest   ##  OR
+  $> pip install -U pytest
+See also https://docs.pytest.org/en/latest/getting-started.html
+
+Usage:
+  $> pytest trace_analyzer_test.py
+
+See also https://docs.pytest.org/en/latest/usage.html
+"""
+
+# global imports
+import os
+import sys
+
+DIR = os.path.abspath(os.path.dirname(__file__))
+
+sys.path.append(os.path.dirname(DIR))
+import lib.cmd_utils as cmd_utils
+
+def test_trace_analyzer(tmpdir):
+  # Setup
+  bin = os.path.join(DIR, 'trace_analyzer')
+  systrace = os.path.join(DIR, 'test_fixtures/common_systrace')
+  db_file = tmpdir.mkdir('trace_analyzer').join('test.db')
+
+  # Act
+  passed, output = cmd_utils.execute_arbitrary_command([bin, systrace,
+                                                        str(db_file)],
+                                                       timeout=300,
+                                                       shell=False,
+                                                       simulate=False)
+
+  # Assert
+  assert passed
+  assert output == """\
+'blocked_iowait_duration_ms',\
+'process_name',\
+'launching_duration_ms',\
+'launching_started_timestamp_ms',\
+'launching_finished_timestamp_ms'
+81.697999999960302375,\
+'com.google.android.dialer',\
+594.99400000095192808,\
+14594219.85600000061,\
+14594814.85000000149"""
diff --git a/telephony/java/com/android/internal/telephony/CarrierAppUtils.java b/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
index a1bea4d..6498e49 100644
--- a/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
@@ -22,6 +22,7 @@
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.os.RemoteException;
+import android.permission.IPermissionManager;
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.util.ArrayMap;
@@ -71,8 +72,8 @@
      * privileged apps may have changed.
      */
     public synchronized static void disableCarrierAppsUntilPrivileged(String callingPackage,
-            IPackageManager packageManager, TelephonyManager telephonyManager,
-            ContentResolver contentResolver, int userId) {
+            IPackageManager packageManager, IPermissionManager permissionManager,
+            TelephonyManager telephonyManager, ContentResolver contentResolver, int userId) {
         if (DEBUG) {
             Slog.d(TAG, "disableCarrierAppsUntilPrivileged");
         }
@@ -81,8 +82,8 @@
                 config.getDisabledUntilUsedPreinstalledCarrierApps();
         ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed =
                 config.getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
-        disableCarrierAppsUntilPrivileged(callingPackage, packageManager, telephonyManager,
-                contentResolver, userId, systemCarrierAppsDisabledUntilUsed,
+        disableCarrierAppsUntilPrivileged(callingPackage, packageManager, permissionManager,
+                telephonyManager, contentResolver, userId, systemCarrierAppsDisabledUntilUsed,
                 systemCarrierAssociatedAppsDisabledUntilUsed);
     }
 
@@ -98,7 +99,8 @@
      * Manager can kill it, and this can lead to crashes as the app is in an unexpected state.
      */
     public synchronized static void disableCarrierAppsUntilPrivileged(String callingPackage,
-            IPackageManager packageManager, ContentResolver contentResolver, int userId) {
+            IPackageManager packageManager, IPermissionManager permissionManager,
+            ContentResolver contentResolver, int userId) {
         if (DEBUG) {
             Slog.d(TAG, "disableCarrierAppsUntilPrivileged");
         }
@@ -109,7 +111,7 @@
 
         ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed =
                 config.getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
-        disableCarrierAppsUntilPrivileged(callingPackage, packageManager,
+        disableCarrierAppsUntilPrivileged(callingPackage, packageManager, permissionManager,
                 null /* telephonyManager */, contentResolver, userId,
                 systemCarrierAppsDisabledUntilUsed, systemCarrierAssociatedAppsDisabledUntilUsed);
     }
@@ -117,7 +119,8 @@
     // Must be public b/c framework unit tests can't access package-private methods.
     @VisibleForTesting
     public static void disableCarrierAppsUntilPrivileged(String callingPackage,
-            IPackageManager packageManager, @Nullable TelephonyManager telephonyManager,
+            IPackageManager packageManager, IPermissionManager permissionManager,
+            @Nullable TelephonyManager telephonyManager,
             ContentResolver contentResolver, int userId,
             ArraySet<String> systemCarrierAppsDisabledUntilUsed,
             ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed) {
@@ -256,7 +259,7 @@
                 // apps.
                 String[] packageNames = new String[enabledCarrierPackages.size()];
                 enabledCarrierPackages.toArray(packageNames);
-                packageManager.grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId);
+                permissionManager.grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId);
             }
         } catch (RemoteException e) {
             Slog.w(TAG, "Could not reach PackageManager", e);
diff --git a/test-mock/src/android/test/mock/MockContentProvider.java b/test-mock/src/android/test/mock/MockContentProvider.java
index e9a5ff7..4d8c7d9 100644
--- a/test-mock/src/android/test/mock/MockContentProvider.java
+++ b/test-mock/src/android/test/mock/MockContentProvider.java
@@ -16,6 +16,7 @@
 
 package android.test.mock;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ContentProvider;
 import android.content.ContentProviderOperation;
@@ -23,6 +24,7 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.IContentProvider;
+import android.content.Intent;
 import android.content.OperationApplicationException;
 import android.content.pm.PathPermission;
 import android.content.pm.ProviderInfo;
@@ -154,6 +156,11 @@
                 ICancellationSignal cancellationSignal) throws RemoteException {
             return MockContentProvider.this.refresh(url, args);
         }
+
+        @Override
+        public int checkUriPermission(String callingPkg, Uri uri, int uid, int modeFlags) {
+            return MockContentProvider.this.checkUriPermission(uri, uid, modeFlags);
+        }
     }
     private final InversionIContentProvider mIContentProvider = new InversionIContentProvider();
 
@@ -266,6 +273,12 @@
         throw new UnsupportedOperationException("unimplemented mock method call");
     }
 
+    /** {@hide} */
+    @Override
+    public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags) {
+        throw new UnsupportedOperationException("unimplemented mock method call");
+    }
+
     /**
      * Returns IContentProvider which calls back same methods in this class.
      * By overriding this class, we avoid the mechanism hidden behind ContentProvider
diff --git a/test-mock/src/android/test/mock/MockIContentProvider.java b/test-mock/src/android/test/mock/MockIContentProvider.java
index fc2a464..b072d74 100644
--- a/test-mock/src/android/test/mock/MockIContentProvider.java
+++ b/test-mock/src/android/test/mock/MockIContentProvider.java
@@ -16,12 +16,14 @@
 
 package android.test.mock;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderResult;
 import android.content.ContentValues;
 import android.content.EntityIterator;
 import android.content.IContentProvider;
+import android.content.Intent;
 import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
 import android.net.Uri;
@@ -144,4 +146,10 @@
             ICancellationSignal cancellationSignal) throws RemoteException {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
+
+    /** {@hide} */
+    @Override
+    public int checkUriPermission(String callingPkg, Uri uri, int uid, int modeFlags) {
+        throw new UnsupportedOperationException("unimplemented mock method call");
+    }
 }
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rs b/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rscript
similarity index 100%
rename from tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rs
rename to tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rscript
diff --git a/tests/libs-permissions/Android.bp b/tests/libs-permissions/Android.bp
index c7c4b10..330bfc9 100644
--- a/tests/libs-permissions/Android.bp
+++ b/tests/libs-permissions/Android.bp
@@ -14,16 +14,16 @@
 }
 
 java_library {
-    name: "com.android.test.libs.product_services",
+    name: "com.android.test.libs.system_ext",
     installable: true,
-    product_services_specific: true,
-    srcs: ["product_services/java/**/*.java"],
-    required: ["com.android.test.libs.product_services.xml"],
+    system_ext_specific: true,
+    srcs: ["system_ext/java/**/*.java"],
+    required: ["com.android.test.libs.system_ext.xml"],
 }
 
 prebuilt_etc {
-    name: "com.android.test.libs.product_services.xml",
-    src: "product_services/com.android.test.libs.product_services.xml",
+    name: "com.android.test.libs.system_ext.xml",
+    src: "system_ext/com.android.test.libs.system_ext.xml",
     sub_dir: "permissions",
-    product_services_specific: true,
+    system_ext_specific: true,
 }
diff --git a/tests/libs-permissions/product_services/com.android.test.libs.product_services.xml b/tests/libs-permissions/system_ext/com.android.test.libs.system_ext.xml
similarity index 81%
rename from tests/libs-permissions/product_services/com.android.test.libs.product_services.xml
rename to tests/libs-permissions/system_ext/com.android.test.libs.system_ext.xml
index 082a9be..fa56004 100644
--- a/tests/libs-permissions/product_services/com.android.test.libs.product_services.xml
+++ b/tests/libs-permissions/system_ext/com.android.test.libs.system_ext.xml
@@ -15,6 +15,6 @@
 -->
 
 <permissions>
-    <library name="com.android.test.libs.product_services"
-            file="/product_services/framework/com.android.test.libs.product_services.jar" />
+    <library name="com.android.test.libs.system_ext"
+            file="/system_ext/framework/com.android.test.libs.system_ext.jar" />
 </permissions>
diff --git a/tests/libs-permissions/product_services/java/com/android/test/libs/product_services/LibsProductServicesTest.java b/tests/libs-permissions/system_ext/java/com/android/test/libs/system_ext/LibsSystemExtTest.java
similarity index 84%
rename from tests/libs-permissions/product_services/java/com/android/test/libs/product_services/LibsProductServicesTest.java
rename to tests/libs-permissions/system_ext/java/com/android/test/libs/system_ext/LibsSystemExtTest.java
index dcbdae8..9999aba 100644
--- a/tests/libs-permissions/product_services/java/com/android/test/libs/product_services/LibsProductServicesTest.java
+++ b/tests/libs-permissions/system_ext/java/com/android/test/libs/system_ext/LibsSystemExtTest.java
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.test.libs.product_services;
+package com.android.test.libs.system_ext;
 
 /**
- * Test class for product_services libs.
+ * Test class for system_ext libs.
  */
-public class LibsProductServicesTest {
+public class LibsSystemExtTest {
 
     /**
      * Dummy method for testing.
diff --git a/tests/privapp-permissions/Android.bp b/tests/privapp-permissions/Android.bp
index ca7864f..b661850 100644
--- a/tests/privapp-permissions/Android.bp
+++ b/tests/privapp-permissions/Android.bp
@@ -45,17 +45,17 @@
 }
 
 android_app {
-    name: "ProductServicesPrivAppPermissionTest",
+    name: "SystemExtPrivAppPermissionTest",
     sdk_version: "current",
     privileged: true,
-    manifest: "product_services/AndroidManifest.xml",
-    product_services_specific: true,
-    required: ["product_servicesprivapp-permissions-test.xml"],
+    manifest: "system_ext/AndroidManifest.xml",
+    system_ext_specific: true,
+    required: ["system_extprivapp-permissions-test.xml"],
 }
 
 prebuilt_etc {
-    name: "product_servicesprivapp-permissions-test.xml",
-    src: "product_services/privapp-permissions-test.xml",
+    name: "system_extprivapp-permissions-test.xml",
+    src: "system_ext/privapp-permissions-test.xml",
     sub_dir: "permissions",
-    product_services_specific: true,
+    system_ext_specific: true,
 }
diff --git a/tests/privapp-permissions/product_services/AndroidManifest.xml b/tests/privapp-permissions/system_ext/AndroidManifest.xml
similarity index 97%
rename from tests/privapp-permissions/product_services/AndroidManifest.xml
rename to tests/privapp-permissions/system_ext/AndroidManifest.xml
index 511ddee..4a0e82f 100644
--- a/tests/privapp-permissions/product_services/AndroidManifest.xml
+++ b/tests/privapp-permissions/system_ext/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.framework.permission.privapp.tests.product_services">
+          package="com.android.framework.permission.privapp.tests.system_ext">
 
     <!-- MANAGE_USB is signature|privileged -->
     <uses-permission android:name="android.permission.MANAGE_USB"/>
diff --git a/tests/privapp-permissions/product_services/privapp-permissions-test.xml b/tests/privapp-permissions/system_ext/privapp-permissions-test.xml
similarity index 85%
rename from tests/privapp-permissions/product_services/privapp-permissions-test.xml
rename to tests/privapp-permissions/system_ext/privapp-permissions-test.xml
index 43baebb..ad63e86 100644
--- a/tests/privapp-permissions/product_services/privapp-permissions-test.xml
+++ b/tests/privapp-permissions/system_ext/privapp-permissions-test.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <permissions>
-    <privapp-permissions package="com.android.framework.permission.privapp.tests.product_services">
+    <privapp-permissions package="com.android.framework.permission.privapp.tests.system_ext">
         <permission name="android.permission.MANAGE_USB"/>
     </privapp-permissions>
 </permissions>
diff --git a/tools/lock_agent/Android.bp b/tools/lock_agent/Android.bp
index 408946b..79dce4a 100644
--- a/tools/lock_agent/Android.bp
+++ b/tools/lock_agent/Android.bp
@@ -12,13 +12,9 @@
     ],
     sdk_version: "current",
     stl: "c++_static",
-    include_dirs: [
-        // NDK headers aren't available in platform NDK builds.
-        "libnativehelper/include_jni",
-        // Use ScopedUtfChars.
-        "libnativehelper/header_only_include",
-    ],
     header_libs: [
+        // Use ScopedUtfChars.
+        "libnativehelper_header_only",
         "libopenjdkjvmti_headers",
     ],
     compile_multilib: "both",
@@ -32,13 +28,9 @@
         "libz",
         "slicer",
     ],
-    include_dirs: [
-        // NDK headers aren't available in platform NDK builds.
-        "libnativehelper/include_jni",
-        // Use ScopedUtfChars.
-        "libnativehelper/header_only_include",
-    ],
     header_libs: [
+        // Use ScopedUtfChars.
+        "libnativehelper_header_only",
         "libopenjdkjvmti_headers",
     ],
 }
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index cd659e2..d37c4a2 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -190,7 +190,7 @@
      * has changed. One extra {@link #EXTRA_WIFI_P2P_INFO} provides the p2p connection info in
      * the form of a {@link WifiP2pInfo} object. Another extra {@link #EXTRA_NETWORK_INFO} provides
      * the network info in the form of a {@link android.net.NetworkInfo}. A third extra provides
-     * the details of the group.
+     * the details of the group and may contain a {@code null}.
      *
      * All of these permissions are required to receive this broadcast:
      * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and