Merge "Fix battery background color in QS"
diff --git a/Android.bp b/Android.bp
index 28e51e7..d0bee28 100644
--- a/Android.bp
+++ b/Android.bp
@@ -429,8 +429,6 @@
         "media/java/android/media/IMediaRouterService.aidl",
         "media/java/android/media/IMediaScannerListener.aidl",
         "media/java/android/media/IMediaScannerService.aidl",
-        "media/java/android/media/IMediaSession2.aidl",
-        "media/java/android/media/IMediaSession2Callback.aidl",
         "media/java/android/media/IPlaybackConfigDispatcher.aidl",
         "media/java/android/media/ISessionTokensListener.aidl",
         ":libaudioclient_aidl",
diff --git a/apct-tests/perftests/core/src/android/text/MeasuredTextMemoryUsageTest.java b/apct-tests/perftests/core/src/android/text/MeasuredTextMemoryUsageTest.java
new file mode 100644
index 0000000..fc6302e
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/text/MeasuredTextMemoryUsageTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+
+package android.text;
+
+import static android.text.TextDirectionHeuristics.LTR;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.test.InstrumentationRegistry;
+import android.content.res.ColorStateList;
+import android.graphics.Canvas;
+import android.graphics.Typeface;
+import android.text.Layout;
+import android.text.style.TextAppearanceSpan;
+import android.view.DisplayListCanvas;
+import android.view.RenderNode;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.CharBuffer;
+import java.util.Random;
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class MeasuredTextMemoryUsageTest {
+    private static final int WORD_LENGTH = 9;  // Random word has 9 characters.
+    private static final boolean NO_STYLE_TEXT = false;
+
+    private static TextPaint PAINT = new TextPaint();
+
+    private static int TRIAL_COUNT = 100;
+
+    public MeasuredTextMemoryUsageTest() {}
+
+    private TextPerfUtils mTextUtil = new TextPerfUtils();
+
+    @Before
+    public void setUp() {
+        mTextUtil.resetRandom(0 /* seed */);
+    }
+
+    private void reportMemoryUsage(int memoryUsage, String key) {
+        Bundle status = new Bundle();
+        status.putInt(key + "_median", memoryUsage);
+        InstrumentationRegistry.getInstrumentation().sendStatus(Activity.RESULT_OK, status);
+    }
+
+    private int median(int[] values) {
+        return values.length % 2 == 0 ?
+                (values[values.length / 2] + values[values.length / 2 - 1]) / 2:
+                values[values.length / 2];
+    }
+
+    @Test
+    public void testMemoryUsage_NoHyphenation() {
+        int[] memories = new int[TRIAL_COUNT];
+        // Report median of randomly generated MeasuredText.
+        for (int i = 0; i < TRIAL_COUNT; ++i) {
+            memories[i] = new MeasuredText.Builder(
+                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT)
+                .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
+                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
+                .build().getMemoryUsage();
+        }
+        reportMemoryUsage(median(memories), "MemoryUsage_NoHyphenation");
+    }
+
+    @Test
+    public void testMemoryUsage_Hyphenation() {
+        int[] memories = new int[TRIAL_COUNT];
+        // Report median of randomly generated MeasuredText.
+        for (int i = 0; i < TRIAL_COUNT; ++i) {
+            memories[i] = new MeasuredText.Builder(
+                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT)
+                .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
+                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
+                .build().getMemoryUsage();
+        }
+        reportMemoryUsage(median(memories), "MemoryUsage_Hyphenation");
+    }
+
+    @Test
+    public void testMemoryUsage_NoHyphenation_WidthOnly() {
+        int[] memories = new int[TRIAL_COUNT];
+        // Report median of randomly generated MeasuredText.
+        for (int i = 0; i < TRIAL_COUNT; ++i) {
+            memories[i] = new MeasuredText.Builder(
+                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT)
+                .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
+                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
+                .build(false /* width only */).getMemoryUsage();
+        }
+        reportMemoryUsage(median(memories), "MemoryUsage_NoHyphenation_WidthOnly");
+    }
+
+    @Test
+    public void testMemoryUsage_Hyphenatation_WidthOnly() {
+        int[] memories = new int[TRIAL_COUNT];
+        // Report median of randomly generated MeasuredText.
+        for (int i = 0; i < TRIAL_COUNT; ++i) {
+            memories[i] = new MeasuredText.Builder(
+                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT)
+                .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
+                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
+                .build(false /* width only */).getMemoryUsage();
+        }
+        reportMemoryUsage(median(memories), "MemoryUsage_Hyphenation_WidthOnly");
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/text/MeasuredTextPerfTest.java b/apct-tests/perftests/core/src/android/text/MeasuredTextPerfTest.java
new file mode 100644
index 0000000..98f2bd5
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/text/MeasuredTextPerfTest.java
@@ -0,0 +1,185 @@
+/*
+ * 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.
+ */
+
+package android.text;
+
+import static android.text.TextDirectionHeuristics.LTR;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import android.content.res.ColorStateList;
+import android.graphics.Canvas;
+import android.graphics.Typeface;
+import android.text.Layout;
+import android.text.style.TextAppearanceSpan;
+import android.view.DisplayListCanvas;
+import android.view.RenderNode;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.CharBuffer;
+import java.util.Random;
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class MeasuredTextPerfTest {
+    private static final int WORD_LENGTH = 9;  // Random word has 9 characters.
+    private static final int WORDS_IN_LINE = 8;  // Roughly, 8 words in a line.
+    private static final boolean NO_STYLE_TEXT = false;
+    private static final boolean STYLE_TEXT = true;
+
+    private static TextPaint PAINT = new TextPaint();
+    private static final int TEXT_WIDTH = WORDS_IN_LINE * WORD_LENGTH * (int) PAINT.getTextSize();
+
+    public MeasuredTextPerfTest() {}
+
+    @Rule
+    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private TextPerfUtils mTextUtil = new TextPerfUtils();
+
+    @Before
+    public void setUp() {
+        mTextUtil.resetRandom(0 /* seed */);
+    }
+
+    @Test
+    public void testCreate_NoStyled_Hyphenation() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            state.pauseTiming();
+            final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
+            state.resumeTiming();
+
+            new MeasuredText.Builder(text, PAINT)
+                    .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
+                    .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
+                    .build(true /* do full layout */);
+        }
+    }
+
+    @Test
+    public void testCreate_NoStyled_NoHyphenation() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            state.pauseTiming();
+            final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
+            state.resumeTiming();
+
+            new MeasuredText.Builder(text, PAINT)
+                    .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
+                    .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
+                    .build(true /* do full layout */);
+        }
+    }
+
+    @Test
+    public void testCreate_NoStyled_Hyphenation_WidthOnly() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            state.pauseTiming();
+            final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
+            state.resumeTiming();
+
+            new MeasuredText.Builder(text, PAINT)
+                    .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
+                    .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
+                    .build(false /* width only */);
+        }
+    }
+
+    @Test
+    public void testCreate_NoStyled_NoHyphenation_WidthOnly() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            state.pauseTiming();
+            final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
+            state.resumeTiming();
+
+            new MeasuredText.Builder(text, PAINT)
+                    .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
+                    .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
+                    .build(false /* width only */);
+        }
+    }
+
+    @Test
+    public void testCreate_Styled_Hyphenation() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            state.pauseTiming();
+            final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT);
+            state.resumeTiming();
+
+            new MeasuredText.Builder(text, PAINT)
+                    .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
+                    .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
+                    .build(true /* do full layout */);
+        }
+    }
+
+    @Test
+    public void testCreate_Styled_NoHyphenation() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            state.pauseTiming();
+            final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT);
+            state.resumeTiming();
+
+            new MeasuredText.Builder(text, PAINT)
+                    .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
+                    .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
+                    .build(true /* do full layout */);
+        }
+    }
+
+    @Test
+    public void testCreate_Styled_Hyphenation_WidthOnly() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            state.pauseTiming();
+            final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT);
+            state.resumeTiming();
+
+            new MeasuredText.Builder(text, PAINT)
+                    .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
+                    .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
+                    .build(false /* width only */);
+        }
+    }
+
+    @Test
+    public void testCreate_Styled_NoHyphenation_WidthOnly() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            state.pauseTiming();
+            final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT);
+            state.resumeTiming();
+
+            new MeasuredText.Builder(text, PAINT)
+                    .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
+                    .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
+                    .build(false /* width only */);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java b/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java
index 682885b..bab2a85 100644
--- a/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java
@@ -43,74 +43,30 @@
 @LargeTest
 @RunWith(AndroidJUnit4.class)
 public class StaticLayoutPerfTest {
+    private static final int WORD_LENGTH = 9;  // Random word has 9 characters.
+    private static final int WORDS_IN_LINE = 8;  // Roughly, 8 words in a line.
+    private static final boolean NO_STYLE_TEXT = false;
+    private static final boolean STYLE_TEXT = true;
+
+    private static TextPaint PAINT = new TextPaint();
+    private static final int TEXT_WIDTH = WORDS_IN_LINE * WORD_LENGTH * (int) PAINT.getTextSize();
 
     public StaticLayoutPerfTest() {}
 
     @Rule
     public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
 
-    private static final int WORD_LENGTH = 9;  // Random word has 9 characters.
-    private static final int WORDS_IN_LINE = 8;  // Roughly, 8 words in a line.
-    private static final int PARA_LENGTH = 500;  // Number of characters in a paragraph.
-
-    private static final boolean NO_STYLE_TEXT = false;
-    private static final boolean STYLE_TEXT = true;
-
-    private Random mRandom;
-
-    private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-    private static final int ALPHABET_LENGTH = ALPHABET.length();
-
-    private static final ColorStateList TEXT_COLOR = ColorStateList.valueOf(0x00000000);
-    private static final String[] FAMILIES = { "sans-serif", "serif", "monospace" };
-    private static final int[] STYLES = {
-            Typeface.NORMAL, Typeface.BOLD, Typeface.ITALIC, Typeface.BOLD_ITALIC
-    };
-
-    private final char[] mBuffer = new char[PARA_LENGTH];
-
-    private static TextPaint PAINT = new TextPaint();
-    private static final int TEXT_WIDTH = WORDS_IN_LINE * WORD_LENGTH * (int) PAINT.getTextSize();
-
-    private CharSequence generateRandomParagraph(int wordLen, boolean applyRandomStyle) {
-        for (int i = 0; i < PARA_LENGTH; i++) {
-            if (i % (wordLen + 1) == wordLen) {
-                mBuffer[i] = ' ';
-            } else {
-                mBuffer[i] = ALPHABET.charAt(mRandom.nextInt(ALPHABET_LENGTH));
-            }
-        }
-
-        CharSequence cs = CharBuffer.wrap(mBuffer);
-        if (!applyRandomStyle) {
-            return cs;
-        }
-
-        SpannableStringBuilder ssb = new SpannableStringBuilder(cs);
-        for (int i = 0; i < ssb.length(); i += WORD_LENGTH) {
-            final int spanStart = i;
-            final int spanEnd = (i + WORD_LENGTH) > ssb.length() ? ssb.length() : i + WORD_LENGTH;
-
-            final TextAppearanceSpan span = new TextAppearanceSpan(
-                  FAMILIES[mRandom.nextInt(FAMILIES.length)],
-                  STYLES[mRandom.nextInt(STYLES.length)],
-                  24 + mRandom.nextInt(32),  // text size. min 24 max 56
-                  TEXT_COLOR, TEXT_COLOR);
-
-            ssb.setSpan(span, spanStart, spanEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
-        }
-        return ssb;
-    }
+    private TextPerfUtils mTextUtil = new TextPerfUtils();
 
     @Before
     public void setUp() {
-        mRandom = new Random(0);
+        mTextUtil.resetRandom(0 /* seed */);
     }
 
     @Test
     public void testCreate_FixedText_NoStyle_Greedy_NoHyphenation() {
         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
-        final CharSequence text = generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
+        final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
         while (state.keepRunning()) {
             StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
                     .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
@@ -124,7 +80,7 @@
         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
         while (state.keepRunning()) {
             state.pauseTiming();
-            final CharSequence text = generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
+            final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
             state.resumeTiming();
 
             StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
@@ -139,7 +95,7 @@
         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
         while (state.keepRunning()) {
             state.pauseTiming();
-            final CharSequence text = generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
+            final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
             state.resumeTiming();
 
             StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
@@ -154,7 +110,7 @@
         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
         while (state.keepRunning()) {
             state.pauseTiming();
-            final CharSequence text = generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
+            final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
             state.resumeTiming();
 
             StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
@@ -169,7 +125,7 @@
         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
         while (state.keepRunning()) {
             state.pauseTiming();
-            final CharSequence text = generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
+            final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
             state.resumeTiming();
 
             StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
@@ -184,7 +140,7 @@
         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
         while (state.keepRunning()) {
             state.pauseTiming();
-            final CharSequence text = generateRandomParagraph(WORD_LENGTH, STYLE_TEXT);
+            final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT);
             state.resumeTiming();
 
             StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
@@ -200,7 +156,7 @@
         while (state.keepRunning()) {
             state.pauseTiming();
             final MeasuredText text = new MeasuredText.Builder(
-                    generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT)
+                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT)
                     .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
                     .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
                     .build();
@@ -219,7 +175,7 @@
         while (state.keepRunning()) {
             state.pauseTiming();
             final MeasuredText text = new MeasuredText.Builder(
-                    generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT)
+                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT)
                     .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
                     .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
                     .build();
@@ -238,7 +194,7 @@
         while (state.keepRunning()) {
             state.pauseTiming();
             final MeasuredText text = new MeasuredText.Builder(
-                    generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT)
+                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT)
                     .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
                     .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
                     .build();
@@ -257,7 +213,7 @@
         while (state.keepRunning()) {
             state.pauseTiming();
             final MeasuredText text = new MeasuredText.Builder(
-                    generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT)
+                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT)
                     .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
                     .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
                     .build();
@@ -276,7 +232,7 @@
         while (state.keepRunning()) {
             state.pauseTiming();
             final MeasuredText text = new MeasuredText.Builder(
-                    generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT)
+                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT)
                     .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
                     .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
                     .build();
@@ -292,7 +248,7 @@
     @Test
     public void testDraw_FixedText_NoStyled() {
         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
-        final CharSequence text = generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
+        final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
         final RenderNode node = RenderNode.create("benchmark", null);
         while (state.keepRunning()) {
             state.pauseTiming();
@@ -311,7 +267,7 @@
         final RenderNode node = RenderNode.create("benchmark", null);
         while (state.keepRunning()) {
             state.pauseTiming();
-            final CharSequence text = generateRandomParagraph(WORD_LENGTH, STYLE_TEXT);
+            final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT);
             final StaticLayout layout =
                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
             final DisplayListCanvas c = node.start(1200, 200);
@@ -327,7 +283,7 @@
         final RenderNode node = RenderNode.create("benchmark", null);
         while (state.keepRunning()) {
             state.pauseTiming();
-            final CharSequence text = generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
+            final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
             final StaticLayout layout =
                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
             final DisplayListCanvas c = node.start(1200, 200);
@@ -343,7 +299,7 @@
         final RenderNode node = RenderNode.create("benchmark", null);
         while (state.keepRunning()) {
             state.pauseTiming();
-            final CharSequence text = generateRandomParagraph(WORD_LENGTH, STYLE_TEXT);
+            final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT);
             final StaticLayout layout =
                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
             final DisplayListCanvas c = node.start(1200, 200);
@@ -360,7 +316,7 @@
         final RenderNode node = RenderNode.create("benchmark", null);
         while (state.keepRunning()) {
             state.pauseTiming();
-            final CharSequence text = generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
+            final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
             final StaticLayout layout =
                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
             final DisplayListCanvas c = node.start(1200, 200);
@@ -378,7 +334,7 @@
         while (state.keepRunning()) {
             state.pauseTiming();
             final MeasuredText text = new MeasuredText.Builder(
-                    generateRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT).build();
+                    mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT).build();
             final StaticLayout layout =
                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
             final DisplayListCanvas c = node.start(1200, 200);
@@ -395,7 +351,7 @@
         while (state.keepRunning()) {
             state.pauseTiming();
             final MeasuredText text = new MeasuredText.Builder(
-                    generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT).build();
+                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT).build();
             final StaticLayout layout =
                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
             final DisplayListCanvas c = node.start(1200, 200);
@@ -412,7 +368,7 @@
         while (state.keepRunning()) {
             state.pauseTiming();
             final MeasuredText text = new MeasuredText.Builder(
-                    generateRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT).build();
+                    mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT).build();
             final StaticLayout layout =
                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
             final DisplayListCanvas c = node.start(1200, 200);
@@ -430,7 +386,7 @@
         while (state.keepRunning()) {
             state.pauseTiming();
             final MeasuredText text = new MeasuredText.Builder(
-                    generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT).build();
+                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT).build();
             final StaticLayout layout =
                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
             final DisplayListCanvas c = node.start(1200, 200);
diff --git a/apct-tests/perftests/core/src/android/text/TextPerfUtils.java b/apct-tests/perftests/core/src/android/text/TextPerfUtils.java
new file mode 100644
index 0000000..dccb34b
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/text/TextPerfUtils.java
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+package android.text;
+
+import static android.text.TextDirectionHeuristics.LTR;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import android.content.res.ColorStateList;
+import android.graphics.Canvas;
+import android.graphics.Typeface;
+import android.text.Layout;
+import android.text.style.TextAppearanceSpan;
+import android.view.DisplayListCanvas;
+import android.view.RenderNode;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.CharBuffer;
+import java.util.Random;
+
+public class TextPerfUtils {
+
+    private static final int PARA_LENGTH = 500;  // Number of characters in a paragraph.
+
+    private Random mRandom = new Random(0);
+
+    private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+    private static final int ALPHABET_LENGTH = ALPHABET.length();
+
+    private static final ColorStateList TEXT_COLOR = ColorStateList.valueOf(0x00000000);
+    private static final String[] FAMILIES = { "sans-serif", "serif", "monospace" };
+    private static final int[] STYLES = {
+            Typeface.NORMAL, Typeface.BOLD, Typeface.ITALIC, Typeface.BOLD_ITALIC
+    };
+
+    private final char[] mBuffer = new char[PARA_LENGTH];
+
+    public void resetRandom(long seed) {
+        mRandom = new Random(seed);
+    }
+
+    public CharSequence nextRandomParagraph(int wordLen, boolean applyRandomStyle) {
+        for (int i = 0; i < PARA_LENGTH; i++) {
+            if (i % (wordLen + 1) == wordLen) {
+                mBuffer[i] = ' ';
+            } else {
+                mBuffer[i] = ALPHABET.charAt(mRandom.nextInt(ALPHABET_LENGTH));
+            }
+        }
+
+        CharSequence cs = CharBuffer.wrap(mBuffer);
+        if (!applyRandomStyle) {
+            return cs;
+        }
+
+        SpannableStringBuilder ssb = new SpannableStringBuilder(cs);
+        for (int i = 0; i < ssb.length(); i += wordLen) {
+            final int spanStart = i;
+            final int spanEnd = (i + wordLen) > ssb.length() ? ssb.length() : i + wordLen;
+
+            final TextAppearanceSpan span = new TextAppearanceSpan(
+                  FAMILIES[mRandom.nextInt(FAMILIES.length)],
+                  STYLES[mRandom.nextInt(STYLES.length)],
+                  24 + mRandom.nextInt(32),  // text size. min 24 max 56
+                  TEXT_COLOR, TEXT_COLOR);
+
+            ssb.setSpan(span, spanStart, spanEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+        }
+        return ssb;
+    }
+}
diff --git a/api/current.txt b/api/current.txt
index 292ef52..7185c99 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -94,6 +94,7 @@
     field public static final java.lang.String MOUNT_FORMAT_FILESYSTEMS = "android.permission.MOUNT_FORMAT_FILESYSTEMS";
     field public static final java.lang.String MOUNT_UNMOUNT_FILESYSTEMS = "android.permission.MOUNT_UNMOUNT_FILESYSTEMS";
     field public static final java.lang.String NFC = "android.permission.NFC";
+    field public static final java.lang.String NFC_TRANSACTION_EVENT = "android.permission.NFC_TRANSACTION_EVENT";
     field public static final java.lang.String PACKAGE_USAGE_STATS = "android.permission.PACKAGE_USAGE_STATS";
     field public static final deprecated java.lang.String PERSISTENT_ACTIVITY = "android.permission.PERSISTENT_ACTIVITY";
     field public static final java.lang.String PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS";
@@ -6390,7 +6391,7 @@
     method public void addPersistentPreferredActivity(android.content.ComponentName, android.content.IntentFilter, android.content.ComponentName);
     method public void addUserRestriction(android.content.ComponentName, java.lang.String);
     method public boolean bindDeviceAdminServiceAsUser(android.content.ComponentName, android.content.Intent, android.content.ServiceConnection, int, android.os.UserHandle);
-    method public boolean clearApplicationUserData(android.content.ComponentName, java.lang.String, java.util.concurrent.Executor, android.app.admin.DevicePolicyManager.OnClearApplicationUserDataListener);
+    method public void clearApplicationUserData(android.content.ComponentName, java.lang.String, java.util.concurrent.Executor, android.app.admin.DevicePolicyManager.OnClearApplicationUserDataListener);
     method public void clearCrossProfileIntentFilters(android.content.ComponentName);
     method public deprecated void clearDeviceOwnerApp(java.lang.String);
     method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
@@ -6723,20 +6724,46 @@
 
   public class SecurityLog {
     ctor public SecurityLog();
+    field public static final int LEVEL_ERROR = 3; // 0x3
+    field public static final int LEVEL_INFO = 1; // 0x1
+    field public static final int LEVEL_WARNING = 2; // 0x2
     field public static final int TAG_ADB_SHELL_CMD = 210002; // 0x33452
     field public static final int TAG_ADB_SHELL_INTERACTIVE = 210001; // 0x33451
     field public static final int TAG_APP_PROCESS_START = 210005; // 0x33455
+    field public static final int TAG_CERT_AUTHORITY_INSTALLED = 210029; // 0x3346d
+    field public static final int TAG_CERT_AUTHORITY_REMOVED = 210030; // 0x3346e
+    field public static final int TAG_KEYGUARD_DISABLED_FEATURES_SET = 210021; // 0x33465
     field public static final int TAG_KEYGUARD_DISMISSED = 210006; // 0x33456
     field public static final int TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT = 210007; // 0x33457
     field public static final int TAG_KEYGUARD_SECURED = 210008; // 0x33458
+    field public static final int TAG_KEY_DESTRUCTION = 210026; // 0x3346a
+    field public static final int TAG_KEY_GENERATED = 210024; // 0x33468
+    field public static final int TAG_KEY_IMPORT = 210025; // 0x33469
+    field public static final int TAG_LOGGING_STARTED = 210011; // 0x3345b
+    field public static final int TAG_LOGGING_STOPPED = 210012; // 0x3345c
+    field public static final int TAG_LOG_BUFFER_SIZE_CRITICAL = 210015; // 0x3345f
+    field public static final int TAG_MAX_PASSWORD_ATTEMPTS_SET = 210020; // 0x33464
+    field public static final int TAG_MAX_SCREEN_LOCK_TIMEOUT_SET = 210019; // 0x33463
+    field public static final int TAG_MEDIA_MOUNT = 210013; // 0x3345d
+    field public static final int TAG_MEDIA_UNMOUNT = 210014; // 0x3345e
+    field public static final int TAG_OS_SHUTDOWN = 210010; // 0x3345a
+    field public static final int TAG_OS_STARTUP = 210009; // 0x33459
+    field public static final int TAG_PASSWORD_COMPLEXITY_SET = 210017; // 0x33461
+    field public static final int TAG_PASSWORD_EXPIRATION_SET = 210016; // 0x33460
+    field public static final int TAG_PASSWORD_HISTORY_LENGTH_SET = 210018; // 0x33462
+    field public static final int TAG_REMOTE_LOCK = 210022; // 0x33466
     field public static final int TAG_SYNC_RECV_FILE = 210003; // 0x33453
     field public static final int TAG_SYNC_SEND_FILE = 210004; // 0x33454
+    field public static final int TAG_USER_RESTRICTION_ADDED = 210027; // 0x3346b
+    field public static final int TAG_USER_RESTRICTION_REMOVED = 210028; // 0x3346c
+    field public static final int TAG_WIPE_FAILURE = 210023; // 0x33467
   }
 
   public static final class SecurityLog.SecurityEvent implements android.os.Parcelable {
     method public int describeContents();
     method public java.lang.Object getData();
     method public long getId();
+    method public int getLogLevel();
     method public int getTag();
     method public long getTimeNanos();
     method public void writeToParcel(android.os.Parcel, int);
@@ -7134,6 +7161,7 @@
     method public android.net.Uri getUri();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.slice.Slice> CREATOR;
+    field public static final java.lang.String EXTRA_SLIDER_VALUE = "android.app.slice.extra.SLIDER_VALUE";
     field public static final java.lang.String EXTRA_TOGGLE_STATE = "android.app.slice.extra.TOGGLE_STATE";
     field public static final java.lang.String HINT_ACTIONS = "actions";
     field public static final java.lang.String HINT_CALLER_NEEDED = "caller_needed";
@@ -7141,7 +7169,6 @@
     field public static final java.lang.String HINT_LARGE = "large";
     field public static final java.lang.String HINT_LIST = "list";
     field public static final java.lang.String HINT_LIST_ITEM = "list_item";
-    field public static final java.lang.String HINT_MAX = "max";
     field public static final java.lang.String HINT_NO_TINT = "no_tint";
     field public static final java.lang.String HINT_PARTIAL = "partial";
     field public static final java.lang.String HINT_SEE_MORE = "see_more";
@@ -7151,11 +7178,13 @@
     field public static final java.lang.String HINT_TITLE = "title";
     field public static final java.lang.String SUBTYPE_COLOR = "color";
     field public static final java.lang.String SUBTYPE_CONTENT_DESCRIPTION = "content_description";
+    field public static final java.lang.String SUBTYPE_MAX = "max";
     field public static final java.lang.String SUBTYPE_MESSAGE = "message";
     field public static final java.lang.String SUBTYPE_PRIORITY = "priority";
     field public static final java.lang.String SUBTYPE_SLIDER = "slider";
     field public static final java.lang.String SUBTYPE_SOURCE = "source";
     field public static final java.lang.String SUBTYPE_TOGGLE = "toggle";
+    field public static final java.lang.String SUBTYPE_VALUE = "value";
   }
 
   public static class Slice.Builder {
@@ -10014,6 +10043,7 @@
     field public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432; // 0x2000000
     field public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576; // 0x100000
     field public static final int FLAG_ACTIVITY_LAUNCH_ADJACENT = 4096; // 0x1000
+    field public static final int FLAG_ACTIVITY_MATCH_EXTERNAL = 2048; // 0x800
     field public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 134217728; // 0x8000000
     field public static final int FLAG_ACTIVITY_NEW_DOCUMENT = 524288; // 0x80000
     field public static final int FLAG_ACTIVITY_NEW_TASK = 268435456; // 0x10000000
diff --git a/api/system-current.txt b/api/system-current.txt
index 7109b5d..ed3897c 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -310,8 +310,10 @@
     ctor public InstantAppResolverService();
     method public final void attachBaseContext(android.content.Context);
     method public final android.os.IBinder onBind(android.content.Intent);
-    method public void onGetInstantAppIntentFilter(int[], java.lang.String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
-    method public void onGetInstantAppResolveInfo(int[], java.lang.String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
+    method public deprecated void onGetInstantAppIntentFilter(int[], java.lang.String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
+    method public void onGetInstantAppIntentFilter(android.content.Intent, int[], java.lang.String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
+    method public deprecated void onGetInstantAppResolveInfo(int[], java.lang.String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
+    method public void onGetInstantAppResolveInfo(android.content.Intent, int[], java.lang.String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
   }
 
   public static final class InstantAppResolverService.InstantAppResolutionCallback {
@@ -820,12 +822,14 @@
     field public static final java.lang.String ACTION_VOICE_ASSIST = "android.intent.action.VOICE_ASSIST";
     field public static final java.lang.String CATEGORY_LEANBACK_SETTINGS = "android.intent.category.LEANBACK_SETTINGS";
     field public static final java.lang.String EXTRA_FORCE_FACTORY_RESET = "android.intent.extra.FORCE_FACTORY_RESET";
+    field public static final java.lang.String EXTRA_INSTANT_APP_BUNDLES = "android.intent.extra.INSTANT_APP_BUNDLES";
     field public static final java.lang.String EXTRA_ORIGINATING_UID = "android.intent.extra.ORIGINATING_UID";
     field public static final java.lang.String EXTRA_PACKAGES = "android.intent.extra.PACKAGES";
     field public static final java.lang.String EXTRA_PERMISSION_NAME = "android.intent.extra.PERMISSION_NAME";
     field public static final java.lang.String EXTRA_REASON = "android.intent.extra.REASON";
     field public static final java.lang.String EXTRA_REMOTE_CALLBACK = "android.intent.extra.REMOTE_CALLBACK";
     field public static final java.lang.String EXTRA_RESULT_NEEDED = "android.intent.extra.RESULT_NEEDED";
+    field public static final java.lang.String EXTRA_UNKNOWN_INSTANT_APP = "android.intent.extra.UNKNOWN_INSTANT_APP";
   }
 
   public class IntentFilter implements android.os.Parcelable {
@@ -868,6 +872,7 @@
     ctor public InstantAppResolveInfo(android.content.pm.InstantAppResolveInfo.InstantAppDigest, java.lang.String, java.util.List<android.content.pm.InstantAppIntentFilter>, int);
     ctor public InstantAppResolveInfo(android.content.pm.InstantAppResolveInfo.InstantAppDigest, java.lang.String, java.util.List<android.content.pm.InstantAppIntentFilter>, long, android.os.Bundle);
     ctor public InstantAppResolveInfo(java.lang.String, java.lang.String, java.util.List<android.content.pm.InstantAppIntentFilter>);
+    ctor public InstantAppResolveInfo(android.os.Bundle);
     method public int describeContents();
     method public byte[] getDigestBytes();
     method public int getDigestPrefix();
@@ -876,6 +881,7 @@
     method public long getLongVersionCode();
     method public java.lang.String getPackageName();
     method public deprecated int getVersionCode();
+    method public boolean shouldLetInstallerDecide();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.pm.InstantAppResolveInfo> CREATOR;
   }
@@ -887,6 +893,7 @@
     method public int[] getDigestPrefix();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.pm.InstantAppResolveInfo.InstantAppDigest> CREATOR;
+    field public static final android.content.pm.InstantAppResolveInfo.InstantAppDigest UNDEFINED;
   }
 
   public final class IntentFilterVerificationInfo implements android.os.Parcelable {
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index edc9f2c..3e71b53 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -196,6 +196,14 @@
     return it->second->byteSize();
 }
 
+void StatsLogProcessor::dumpStates(FILE* out, bool verbose) {
+    std::lock_guard<std::mutex> lock(mMetricsMutex);
+    fprintf(out, "MetricsManager count: %lu\n", (unsigned long)mMetricsManagers.size());
+    for (auto metricsManager : mMetricsManagers) {
+        metricsManager.second->dumpStates(out, verbose);
+    }
+}
+
 void StatsLogProcessor::onDumpReport(const ConfigKey& key, const uint64_t& dumpTimeStampNs,
                                      ConfigMetricsReportList* report) {
     std::lock_guard<std::mutex> lock(mMetricsMutex);
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index fb85aa8..c19ff63 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -61,6 +61,8 @@
         return mUidMap;
     }
 
+    void dumpStates(FILE* out, bool verbose);
+
 private:
     mutable mutex mMetricsMutex;
 
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 31994e1..f545bb0 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -175,8 +175,13 @@
         return NO_MEMORY;  // the fd is already open
     }
 
+    bool verbose = false;
+    if (args.size() > 0 && !args[0].compare(String16("-v"))) {
+        verbose = true;
+    }
+
     // TODO: Proto format for incident reports
-    dump_impl(out);
+    dump_impl(out, verbose);
 
     fclose(out);
     return NO_ERROR;
@@ -185,9 +190,9 @@
 /**
  * Write debugging data about statsd in text format.
  */
-void StatsService::dump_impl(FILE* out) {
-    mConfigManager->Dump(out);
+void StatsService::dump_impl(FILE* out, bool verbose) {
     StatsdStats::getInstance().dumpStats(out);
+    mProcessor->dumpStates(out, verbose);
 }
 
 /**
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index ba6bd24..be20893 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -140,7 +140,7 @@
     /**
      * Text output of dumpsys.
      */
-    void dump_impl(FILE* out);
+    void dump_impl(FILE* out, bool verbose);
 
     /**
      * Print usage information for the commands
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index 63bde7d..77f5456 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -45,6 +45,8 @@
 const int FIELD_ID_ATOM_STATS = 7;
 const int FIELD_ID_UIDMAP_STATS = 8;
 const int FIELD_ID_ANOMALY_ALARM_STATS = 9;
+const int FIELD_ID_PULLED_ATOM_STATS = 10;
+const int FIELD_ID_LOGGER_ERROR_STATS = 11;
 
 const int FIELD_ID_MATCHER_STATS_NAME = 1;
 const int FIELD_ID_MATCHER_STATS_COUNT = 2;
@@ -60,6 +62,9 @@
 
 const int FIELD_ID_ANOMALY_ALARMS_REGISTERED = 1;
 
+const int FIELD_ID_LOGGER_STATS_TIME = 1;
+const int FIELD_ID_LOGGER_STATS_ERROR_CODE = 2;
+
 std::map<int, long> StatsdStats::kPullerCooldownMap = {
         {android::util::KERNEL_WAKELOCK, 1},
         {android::util::WIFI_BYTES_TRANSFER, 1},
@@ -282,6 +287,15 @@
     mPushedAtomStats[atomId]++;
 }
 
+void StatsdStats::noteLoggerError(int error) {
+    lock_guard<std::mutex> lock(mLock);
+    // grows strictly one at a time. so it won't > kMaxLoggerErrors
+    if (mLoggerErrors.size() == kMaxLoggerErrors) {
+        mLoggerErrors.pop_front();
+    }
+    mLoggerErrors.push_back(std::make_pair(time(nullptr), error));
+}
+
 void StatsdStats::reset() {
     lock_guard<std::mutex> lock(mLock);
     resetInternalLocked();
@@ -297,6 +311,7 @@
     mAlertStats.clear();
     mAnomalyAlarmRegisteredStats = 0;
     mMatcherStats.clear();
+    mLoggerErrors.clear();
     for (auto& config : mConfigStats) {
         config.second.clear_broadcast_sent_time_sec();
         config.second.clear_data_drop_time_sec();
@@ -465,6 +480,14 @@
             "lost=%d\n",
             mUidMapStats.bytes_used(), mUidMapStats.snapshots(), mUidMapStats.changes(),
             mUidMapStats.dropped_snapshots(), mUidMapStats.dropped_changes());
+
+    for (const auto& error : mLoggerErrors) {
+        time_t error_time = error.first;
+        struct tm* error_tm = localtime(&error_time);
+        char buffer[80];
+        strftime(buffer, sizeof(buffer), "%Y-%m-%d %I:%M%p\n", error_tm);
+        fprintf(out, "Logger error %d at %s\n", error.second, buffer);
+    }
 }
 
 void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
@@ -526,6 +549,14 @@
     mUidMapStats.SerializeToArray(&buffer[0], numBytes);
     proto.write(FIELD_TYPE_MESSAGE | FIELD_ID_UIDMAP_STATS, &buffer[0], buffer.size());
 
+    for (const auto& error : mLoggerErrors) {
+        long long token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_LOGGER_ERROR_STATS |
+                                      FIELD_COUNT_REPEATED);
+        proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOGGER_STATS_TIME, error.first);
+        proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOGGER_STATS_ERROR_CODE, error.second);
+        proto.end(token);
+    }
+
     output->clear();
     size_t bufferSize = proto.size();
     output->resize(bufferSize);
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 7cb48ea..1f4bfa6 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -49,6 +49,8 @@
     // The max number of old config stats we keep.
     const static int kMaxIceBoxSize = 20;
 
+    const static int kMaxLoggerErrors = 10;
+
     const static int kMaxTimestampCount = 20;
 
     const static int kMaxLogSourceCount = 50;
@@ -185,6 +187,11 @@
     void notePullFromCache(int pullAtomId);
 
     /**
+     * Records statsd met an error while reading from logd.
+     */
+    void noteLoggerError(int error);
+
+    /**
      * Reset the historical stats. Including all stats in icebox, and the tracked stats about
      * metrics, matchers, and atoms. The active configs will be kept and StatsdStats will continue
      * to collect stats after reset() has been called.
@@ -246,6 +253,9 @@
     // Maps PullAtomId to its stats. The size is capped by the puller atom counts.
     std::map<int, PulledAtomStats> mPulledAtomStats;
 
+    // Logd errors. Size capped by kMaxLoggerErrors.
+    std::list<const std::pair<int, int>> mLoggerErrors;
+
     // Stores the number of times statsd modified the anomaly alarm registered with
     // StatsCompanionService.
     int mAnomalyAlarmRegisteredStats = 0;
diff --git a/cmds/statsd/src/logd/LogReader.cpp b/cmds/statsd/src/logd/LogReader.cpp
index 5d43ef3..0fe896b 100644
--- a/cmds/statsd/src/logd/LogReader.cpp
+++ b/cmds/statsd/src/logd/LogReader.cpp
@@ -16,10 +16,11 @@
 
 #include "logd/LogReader.h"
 
-#include <utils/Errors.h>
+#include "guardrail/StatsdStats.h"
 
 #include <time.h>
 #include <unistd.h>
+#include <utils/Errors.h>
 
 using namespace android;
 using namespace std;
@@ -92,16 +93,15 @@
 
     // Read forever
     if (eventLogger) {
-
+        log_msg msg;
         while (true) {
-            log_msg msg;
-
             // Read a message
             err = android_logger_list_read(loggers, &msg);
             // err = 0 - no content, unexpected connection drop or EOF.
             // err = +ive number - size of retrieved data from logger
             // err = -ive number, OS supplied error _except_ for -EAGAIN
             if (err <= 0) {
+                StatsdStats::getInstance().noteLoggerError(err);
                 fprintf(stderr, "logcat read failure: %s\n", strerror(err));
                 break;
             }
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index 16fc7ee..061b7a3 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -68,6 +68,8 @@
     // Internal function to calculate the current used bytes.
     size_t byteSizeLocked() const override;
 
+    void dumpStatesLocked(FILE* out, bool verbose) const override{};
+
     // Util function to flush the old packet.
     void flushIfNeededLocked(const uint64_t& newEventTime);
 
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index e26fe56..bfab9e6 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -233,6 +233,21 @@
     mCurrentBucketNum += numBucketsForward;
 }
 
+void DurationMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
+    if (mCurrentSlicedDuration.size() == 0) {
+        return;
+    }
+
+    fprintf(out, "DurationMetric %lld dimension size %lu\n", (long long)mMetricId,
+            (unsigned long)mCurrentSlicedDuration.size());
+    if (verbose) {
+        for (const auto& slice : mCurrentSlicedDuration) {
+            fprintf(out, "\t%s\n", slice.first.c_str());
+            slice.second->dumpStates(out, verbose);
+        }
+    }
+}
+
 bool DurationMetricProducer::hitGuardRailLocked(const HashableDimensionKey& newKey) {
     // the key is not new, we are good.
     if (mCurrentSlicedDuration.find(newKey) != mCurrentSlicedDuration.end()) {
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index e06b9a1..d8cab92 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -68,6 +68,8 @@
     // Internal function to calculate the current used bytes.
     size_t byteSizeLocked() const override;
 
+    void dumpStatesLocked(FILE* out, bool verbose) const override;
+
     // Util function to flush the old packet.
     void flushIfNeededLocked(const uint64_t& eventTime);
 
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.h b/cmds/statsd/src/metrics/EventMetricProducer.h
index a57b07d..9da0dd0 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.h
+++ b/cmds/statsd/src/metrics/EventMetricProducer.h
@@ -62,6 +62,8 @@
     // Internal function to calculate the current used bytes.
     size_t byteSizeLocked() const override;
 
+    void dumpStatesLocked(FILE* out, bool verbose) const override{};
+
     // Maps to a EventMetricDataWrapper. Storing atom events in ProtoOutputStream
     // is more space efficient than storing LogEvent.
     std::unique_ptr<android::util::ProtoOutputStream> mProto;
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index f267e98..1895edf 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -83,6 +83,8 @@
     // Internal function to calculate the current used bytes.
     size_t byteSizeLocked() const override;
 
+    void dumpStatesLocked(FILE* out, bool verbose) const override{};
+
     // Util function to flush the old packet.
     void flushIfNeededLocked(const uint64_t& eventTime);
 
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 3779c44..6f33073 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -96,6 +96,11 @@
         return onDumpReportLocked(dumpTimeNs, report);
     }
 
+    void dumpStates(FILE* out, bool verbose) const {
+        std::lock_guard<std::mutex> lock(mMutex);
+        dumpStatesLocked(out, verbose);
+    }
+
     // Returns the memory in bytes currently used to store this metric's data. Does not change
     // state.
     size_t byteSize() const {
@@ -128,6 +133,7 @@
                                     android::util::ProtoOutputStream* protoOutput) = 0;
     virtual void onDumpReportLocked(const uint64_t dumpTimeNs, StatsLogReport* report) = 0;
     virtual size_t byteSizeLocked() const = 0;
+    virtual void dumpStatesLocked(FILE* out, bool verbose) const = 0;
 
     const int64_t mMetricId;
 
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index f929517..d0737de 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -154,6 +154,20 @@
     }
 }
 
+void MetricsManager::dumpStates(FILE* out, bool verbose) {
+    fprintf(out, "ConfigKey %s, allowed source:", mConfigKey.ToString().c_str());
+    {
+        std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
+        for (const auto& source : mAllowedLogSources) {
+            fprintf(out, "%d ", source);
+        }
+    }
+    fprintf(out, "\n");
+    for (const auto& producer : mAllMetricProducers) {
+        producer->dumpStates(out, verbose);
+    }
+}
+
 void MetricsManager::onDumpReport(ProtoOutputStream* protoOutput) {
     VLOG("=========================Metric Reports Start==========================");
     uint64_t dumpTimeStampNs = time(nullptr) * NS_PER_SEC;
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index a0239fc..9cdbafc 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -61,6 +61,8 @@
         return !mAllowedPkg.empty();
     }
 
+    void dumpStates(FILE* out, bool verbose);
+
     // Config source owner can call onDumpReport() to get all the metrics collected.
     virtual void onDumpReport(android::util::ProtoOutputStream* protoOutput);
     virtual void onDumpReport(const uint64_t& dumpTimeStampNs, ConfigMetricsReport* report);
@@ -68,7 +70,6 @@
     // Computes the total byte size of all metrics managed by a single config source.
     // Does not change the state.
     virtual size_t byteSize();
-
 private:
     const ConfigKey mConfigKey;
 
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index 3e7032d..9f750cf 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -67,6 +67,8 @@
     // Internal function to calculate the current used bytes.
     size_t byteSizeLocked() const override;
 
+    void dumpStatesLocked(FILE* out, bool verbose) const override{};
+
     // Util function to flush the old packet.
     void flushIfNeededLocked(const uint64_t& eventTime);
 
diff --git a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
index 371460e..c2d2cea 100644
--- a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
@@ -97,6 +97,8 @@
     // Predict the anomaly timestamp given the current status.
     virtual int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
                                               const uint64_t currentTimestamp) const = 0;
+    // Dump internal states for debugging
+    virtual void dumpStates(FILE* out, bool verbose) const = 0;
 
 protected:
     // Starts the anomaly alarm.
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
index 0c99391..412a0c9 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
@@ -291,6 +291,11 @@
     return currentTimestamp;
 }
 
+void MaxDurationTracker::dumpStates(FILE* out, bool verbose) const {
+    fprintf(out, "\t\t sub-durations %lu\n", (unsigned long)mInfos.size());
+    fprintf(out, "\t\t current duration %lld\n", (long long)mDuration);
+}
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
index 5d3c158..e988ebc 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
@@ -48,6 +48,7 @@
 
     int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
                                       const uint64_t currentTimestamp) const override;
+    void dumpStates(FILE* out, bool verbose) const override;
 
 private:
     std::map<HashableDimensionKey, DurationInfo> mInfos;
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
index 6bf4228..75d7c08 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
@@ -314,6 +314,12 @@
     return eventTimestampNs + thresholdNs;
 }
 
+void OringDurationTracker::dumpStates(FILE* out, bool verbose) const {
+    fprintf(out, "\t\t started count %lu\n", (unsigned long)mStarted.size());
+    fprintf(out, "\t\t paused count %lu\n", (unsigned long)mPaused.size());
+    fprintf(out, "\t\t current duration %lld\n", (long long)mDuration);
+}
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
index 638b7ad..1b74ed1 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
@@ -48,6 +48,7 @@
 
     int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
                                       const uint64_t currentTimestamp) const override;
+    void dumpStates(FILE* out, bool verbose) const override;
 
 private:
     // We don't need to keep track of individual durations. The information that's needed is:
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index f73c4a5..a4ccbd4 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -262,4 +262,10 @@
     optional int64 min_pull_interval_sec = 4;
   }
   repeated PulledAtomStats pulled_atom_stats = 10;
+
+  message LoggerErrorStats {
+    optional int32 logger_disconnection_sec = 1;
+    optional int32 error_code = 2;
+  }
+  repeated LoggerErrorStats logger_error_stats = 11;
 }
\ No newline at end of file
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b58c523..fd7ad88 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -7118,7 +7118,7 @@
         boolean isAppDebuggable =
                 (mApplication.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
 
-        // This property is set for all builds except final release
+        // This property is set for all non-user builds except final release
         boolean isDlwarningEnabled = SystemProperties.getInt("ro.bionic.ld.warning", 0) == 1;
 
         if (isAppDebuggable || isDlwarningEnabled) {
@@ -7141,8 +7141,8 @@
             }
         }
 
-        // We might disable this for final builds.
-        boolean isApiWarningEnabled = true;
+        // This property is set for all non-user builds except final release
+        boolean isApiWarningEnabled = SystemProperties.getInt("ro.art.hiddenapi.warning", 0) == 1;
 
         if (isAppDebuggable || isApiWarningEnabled) {
             if (VMRuntime.getRuntime().hasUsedHiddenApi()) {
diff --git a/core/java/android/app/EphemeralResolverService.java b/core/java/android/app/EphemeralResolverService.java
index 427a0386..d1c2441 100644
--- a/core/java/android/app/EphemeralResolverService.java
+++ b/core/java/android/app/EphemeralResolverService.java
@@ -17,20 +17,10 @@
 package android.app;
 
 import android.annotation.SystemApi;
-import android.app.Service;
-import android.app.InstantAppResolverService.InstantAppResolutionCallback;
-import android.content.Context;
-import android.content.Intent;
 import android.content.pm.EphemeralResolveInfo;
 import android.content.pm.InstantAppResolveInfo;
 import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IRemoteCallback;
 import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -85,7 +75,6 @@
         return super.getLooper();
     }
 
-    @Override
     void _onGetInstantAppResolveInfo(int[] digestPrefix, String token,
             InstantAppResolutionCallback callback) {
         if (DEBUG_EPHEMERAL) {
@@ -101,7 +90,6 @@
         callback.onInstantAppResolveInfo(resultList);
     }
 
-    @Override
     void _onGetInstantAppIntentFilter(int[] digestPrefix, String token,
             String hostName, InstantAppResolutionCallback callback) {
         if (DEBUG_EPHEMERAL) {
diff --git a/core/java/android/app/IInstantAppResolver.aidl b/core/java/android/app/IInstantAppResolver.aidl
index 805d8c0..ae20057 100644
--- a/core/java/android/app/IInstantAppResolver.aidl
+++ b/core/java/android/app/IInstantAppResolver.aidl
@@ -16,13 +16,15 @@
 
 package android.app;
 
+import android.content.Intent;
 import android.os.IRemoteCallback;
 
 /** @hide */
 oneway interface IInstantAppResolver {
-    void getInstantAppResolveInfoList(in int[] digestPrefix,
+    void getInstantAppResolveInfoList(in Intent sanitizedIntent, in int[] hostDigestPrefix,
             String token, int sequence, IRemoteCallback callback);
 
-    void getInstantAppIntentFilterList(in int[] digestPrefix,
-            String token, String hostName, IRemoteCallback callback);
+    void getInstantAppIntentFilterList(in Intent sanitizedIntent, in int[] hostDigestPrefix,
+            String token, IRemoteCallback callback);
+
 }
diff --git a/core/java/android/app/InstantAppResolverService.java b/core/java/android/app/InstantAppResolverService.java
index c5dc86c..89aff36 100644
--- a/core/java/android/app/InstantAppResolverService.java
+++ b/core/java/android/app/InstantAppResolverService.java
@@ -17,7 +17,6 @@
 package android.app;
 
 import android.annotation.SystemApi;
-import android.app.Service;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.InstantAppResolveInfo;
@@ -35,6 +34,7 @@
 import com.android.internal.os.SomeArgs;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -53,23 +53,65 @@
     Handler mHandler;
 
     /**
-     * Called to retrieve resolve info for instant applications.
+     * Called to retrieve resolve info for instant applications immediately.
      *
      * @param digestPrefix The hash prefix of the instant app's domain.
+     * @deprecated should implement {@link #onGetInstantAppResolveInfo(Intent, int[], String,
+     *             InstantAppResolutionCallback)}
      */
+    @Deprecated
     public void onGetInstantAppResolveInfo(
             int digestPrefix[], String token, InstantAppResolutionCallback callback) {
         throw new IllegalStateException("Must define");
     }
 
     /**
-     * Called to retrieve intent filters for instant applications.
+     * Called to retrieve intent filters for instant applications from potentially expensive
+     * sources.
      *
      * @param digestPrefix The hash prefix of the instant app's domain.
+     * @deprecated should implement {@link #onGetInstantAppIntentFilter(Intent, int[], String,
+     *             InstantAppResolutionCallback)}
      */
+    @Deprecated
     public void onGetInstantAppIntentFilter(
             int digestPrefix[], String token, InstantAppResolutionCallback callback) {
-        throw new IllegalStateException("Must define");
+        throw new IllegalStateException("Must define onGetInstantAppIntentFilter");
+    }
+
+    /**
+     * Called to retrieve resolve info for instant applications immediately.
+     *
+     * @param sanitizedIntent The sanitized {@link Intent} used for resolution.
+     * @param hostDigestPrefix The hash prefix of the instant app's domain.
+     */
+    public void onGetInstantAppResolveInfo(Intent sanitizedIntent, int[] hostDigestPrefix,
+            String token, InstantAppResolutionCallback callback) {
+        // if not overridden, forward to old methods and filter out non-web intents
+        if (sanitizedIntent.isBrowsableWebIntent()) {
+            onGetInstantAppResolveInfo(hostDigestPrefix, token, callback);
+        } else {
+            callback.onInstantAppResolveInfo(Collections.emptyList());
+        }
+    }
+
+    /**
+     * Called to retrieve intent filters for instant applications from potentially expensive
+     * sources.
+     *
+     * @param sanitizedIntent The sanitized {@link Intent} used for resolution.
+     * @param hostDigestPrefix The hash prefix of the instant app's domain or null if no host is
+     *                         defined.
+     */
+    public void onGetInstantAppIntentFilter(Intent sanitizedIntent, int[] hostDigestPrefix,
+            String token, InstantAppResolutionCallback callback) {
+        Log.e(TAG, "New onGetInstantAppIntentFilter is not overridden");
+        // if not overridden, forward to old methods and filter out non-web intents
+        if (sanitizedIntent.isBrowsableWebIntent()) {
+            onGetInstantAppIntentFilter(hostDigestPrefix, token, callback);
+        } else {
+            callback.onInstantAppResolveInfo(Collections.emptyList());
+        }
     }
 
     /**
@@ -89,8 +131,8 @@
     public final IBinder onBind(Intent intent) {
         return new IInstantAppResolver.Stub() {
             @Override
-            public void getInstantAppResolveInfoList(
-                    int digestPrefix[], String token, int sequence, IRemoteCallback callback) {
+            public void getInstantAppResolveInfoList(Intent sanitizedIntent, int[] digestPrefix,
+                    String token, int sequence, IRemoteCallback callback) {
                 if (DEBUG_EPHEMERAL) {
                     Slog.v(TAG, "[" + token + "] Phase1 called; posting");
                 }
@@ -98,14 +140,14 @@
                 args.arg1 = callback;
                 args.arg2 = digestPrefix;
                 args.arg3 = token;
-                mHandler.obtainMessage(
-                                ServiceHandler.MSG_GET_INSTANT_APP_RESOLVE_INFO, sequence, 0, args)
-                        .sendToTarget();
+                args.arg4 = sanitizedIntent;
+                mHandler.obtainMessage(ServiceHandler.MSG_GET_INSTANT_APP_RESOLVE_INFO,
+                        sequence, 0, args).sendToTarget();
             }
 
             @Override
-            public void getInstantAppIntentFilterList(
-                    int digestPrefix[], String token, String hostName, IRemoteCallback callback) {
+            public void getInstantAppIntentFilterList(Intent sanitizedIntent,
+                    int[] digestPrefix, String token, IRemoteCallback callback) {
                 if (DEBUG_EPHEMERAL) {
                     Slog.v(TAG, "[" + token + "] Phase2 called; posting");
                 }
@@ -113,9 +155,9 @@
                 args.arg1 = callback;
                 args.arg2 = digestPrefix;
                 args.arg3 = token;
-                args.arg4 = hostName;
-                mHandler.obtainMessage(
-                        ServiceHandler.MSG_GET_INSTANT_APP_INTENT_FILTER, callback).sendToTarget();
+                args.arg4 = sanitizedIntent;
+                mHandler.obtainMessage(ServiceHandler.MSG_GET_INSTANT_APP_INTENT_FILTER,
+                        callback).sendToTarget();
             }
         };
     }
@@ -142,29 +184,9 @@
         }
     }
 
-    @Deprecated
-    void _onGetInstantAppResolveInfo(int[] digestPrefix, String token,
-            InstantAppResolutionCallback callback) {
-        if (DEBUG_EPHEMERAL) {
-            Slog.d(TAG, "[" + token + "] Phase1 request;"
-                    + " prefix: " + Arrays.toString(digestPrefix));
-        }
-        onGetInstantAppResolveInfo(digestPrefix, token, callback);
-    }
-    @Deprecated
-    void _onGetInstantAppIntentFilter(int digestPrefix[], String token, String hostName,
-            InstantAppResolutionCallback callback) {
-        if (DEBUG_EPHEMERAL) {
-            Slog.d(TAG, "[" + token + "] Phase2 request;"
-                    + " prefix: " + Arrays.toString(digestPrefix));
-        }
-        onGetInstantAppIntentFilter(digestPrefix, token, callback);
-    }
-
     private final class ServiceHandler extends Handler {
         public static final int MSG_GET_INSTANT_APP_RESOLVE_INFO = 1;
         public static final int MSG_GET_INSTANT_APP_INTENT_FILTER = 2;
-
         public ServiceHandler(Looper looper) {
             super(looper, null /*callback*/, true /*async*/);
         }
@@ -179,9 +201,13 @@
                     final IRemoteCallback callback = (IRemoteCallback) args.arg1;
                     final int[] digestPrefix = (int[]) args.arg2;
                     final String token = (String) args.arg3;
+                    final Intent intent = (Intent) args.arg4;
                     final int sequence = message.arg1;
-                    _onGetInstantAppResolveInfo(
-                            digestPrefix, token,
+                    if (DEBUG_EPHEMERAL) {
+                        Slog.d(TAG, "[" + token + "] Phase1 request;"
+                                + " prefix: " + Arrays.toString(digestPrefix));
+                    }
+                    onGetInstantAppResolveInfo(intent, digestPrefix, token,
                             new InstantAppResolutionCallback(sequence, callback));
                 } break;
 
@@ -190,9 +216,12 @@
                     final IRemoteCallback callback = (IRemoteCallback) args.arg1;
                     final int[] digestPrefix = (int[]) args.arg2;
                     final String token = (String) args.arg3;
-                    final String hostName = (String) args.arg4;
-                    _onGetInstantAppIntentFilter(
-                            digestPrefix, token, hostName,
+                    final Intent intent = (Intent) args.arg4;
+                    if (DEBUG_EPHEMERAL) {
+                        Slog.d(TAG, "[" + token + "] Phase2 request;"
+                                + " prefix: " + Arrays.toString(digestPrefix));
+                    }
+                    onGetInstantAppIntentFilter(intent, digestPrefix, token,
                             new InstantAppResolutionCallback(-1 /*sequence*/, callback));
                 } break;
 
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 0b5b363..6e40986 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -493,7 +493,7 @@
      * </ul>
      * <p>
      * Since hardware varies, you are not guaranteed that any of the values
-     * you pass are honored exactly.  Use the system defaults (TODO) if possible
+     * you pass are honored exactly.  Use the system defaults if possible
      * because they will be set to values that work on any given hardware.
      * <p>
      * The alpha channel must be set for forward compatibility.
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 33028e3..3b4511e 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -9078,15 +9078,15 @@
      * @param executor The executor through which the listener should be invoked.
      * @param listener A callback object that will inform the caller when the clearing is done.
      * @throws SecurityException if the caller is not the device owner/profile owner.
-     * @return whether the clearing succeeded.
      */
-    public boolean clearApplicationUserData(@NonNull ComponentName admin,
+    public void clearApplicationUserData(@NonNull ComponentName admin,
             @NonNull String packageName, @NonNull @CallbackExecutor Executor executor,
             @NonNull OnClearApplicationUserDataListener listener) {
         throwIfParentInstance("clearAppData");
         Preconditions.checkNotNull(executor);
+        Preconditions.checkNotNull(listener);
         try {
-            return mService.clearApplicationUserData(admin, packageName,
+            mService.clearApplicationUserData(admin, packageName,
                     new IPackageDataObserver.Stub() {
                         public void onRemoveCompleted(String pkg, boolean succeeded) {
                             executor.execute(() ->
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 2afaaa7..7fc31b1 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -386,7 +386,7 @@
     boolean isCurrentInputMethodSetByOwner();
     StringParceledListSlice getOwnerInstalledCaCerts(in UserHandle user);
 
-    boolean clearApplicationUserData(in ComponentName admin, in String packageName, in IPackageDataObserver callback);
+    void clearApplicationUserData(in ComponentName admin, in String packageName, in IPackageDataObserver callback);
 
     void setLogoutEnabled(in ComponentName admin, boolean enabled);
     boolean isLogoutEnabled();
diff --git a/core/java/android/app/admin/SecurityLog.java b/core/java/android/app/admin/SecurityLog.java
index d3b66d0..08effd9 100644
--- a/core/java/android/app/admin/SecurityLog.java
+++ b/core/java/android/app/admin/SecurityLog.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.TestApi;
+import android.content.ComponentName;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemProperties;
@@ -53,64 +54,367 @@
             TAG_APP_PROCESS_START,
             TAG_KEYGUARD_DISMISSED,
             TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT,
-            TAG_KEYGUARD_SECURED
+            TAG_KEYGUARD_SECURED,
+            TAG_OS_STARTUP,
+            TAG_OS_SHUTDOWN,
+            TAG_LOGGING_STARTED,
+            TAG_LOGGING_STOPPED,
+            TAG_MEDIA_MOUNT,
+            TAG_MEDIA_UNMOUNT,
+            TAG_LOG_BUFFER_SIZE_CRITICAL,
+            TAG_PASSWORD_EXPIRATION_SET,
+            TAG_PASSWORD_COMPLEXITY_SET,
+            TAG_PASSWORD_HISTORY_LENGTH_SET,
+            TAG_MAX_SCREEN_LOCK_TIMEOUT_SET,
+            TAG_MAX_PASSWORD_ATTEMPTS_SET,
+            TAG_KEYGUARD_DISABLED_FEATURES_SET,
+            TAG_REMOTE_LOCK,
+            TAG_USER_RESTRICTION_ADDED,
+            TAG_USER_RESTRICTION_REMOVED,
+            TAG_WIPE_FAILURE,
+            TAG_KEY_GENERATED,
+            TAG_KEY_IMPORT,
+            TAG_KEY_DESTRUCTION,
+            TAG_CERT_AUTHORITY_INSTALLED,
+            TAG_CERT_AUTHORITY_REMOVED,
     })
     public @interface SecurityLogTag {}
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "LEVEL_" }, value = {
+            LEVEL_INFO,
+            LEVEL_WARNING,
+            LEVEL_ERROR
+    })
+    public @interface SecurityLogLevel {}
+
     /**
-     * Indicate that an ADB interactive shell was opened via "adb shell".
+     * Indicates that an ADB interactive shell was opened via "adb shell".
      * There is no extra payload in the log event.
      */
     public static final int TAG_ADB_SHELL_INTERACTIVE =
             SecurityLogTags.SECURITY_ADB_SHELL_INTERACTIVE;
+
     /**
-     * Indicate that an shell command was issued over ADB via "adb shell command"
-     * The log entry contains a string data of the shell command, accessible via
-     * {@link SecurityEvent#getData()}
+     * Indicates that a shell command was issued over ADB via {@code adb shell <command>}
+     * The log entry contains a {@code String} payload containing the shell command, accessible
+     * via {@link SecurityEvent#getData()}.
      */
     public static final int TAG_ADB_SHELL_CMD = SecurityLogTags.SECURITY_ADB_SHELL_COMMAND;
+
     /**
-     * Indicate that a file was pulled from the device via the adb daemon, for example via
-     * "adb pull". The log entry contains a string data of the path of the pulled file,
-     * accessible via {@link SecurityEvent#getData()}
+     * Indicates that a file was pulled from the device via the adb daemon, for example via
+     * {@code adb pull}. The log entry contains a {@code String} payload containing the path of the
+     * pulled file on the device, accessible via {@link SecurityEvent#getData()}.
      */
     public static final int TAG_SYNC_RECV_FILE = SecurityLogTags.SECURITY_ADB_SYNC_RECV;
+
     /**
-     * Indicate that a file was pushed to the device via the adb daemon, for example via
-     * "adb push". The log entry contains a string data of the destination path of the
-     * pushed file, accessible via {@link SecurityEvent#getData()}
+     * Indicates that a file was pushed to the device via the adb daemon, for example via
+     * {@code adb push}. The log entry contains a {@code String} payload containing the destination
+     * path of the pushed file, accessible via {@link SecurityEvent#getData()}.
      */
     public static final int TAG_SYNC_SEND_FILE = SecurityLogTags.SECURITY_ADB_SYNC_SEND;
+
     /**
-     * Indicate that an app process was started. The log entry contains the following
+     * Indicates that an app process was started. The log entry contains the following
      * information about the process encapsulated in an {@link Object} array, accessible via
      * {@link SecurityEvent#getData()}:
-     * process name (String), exact start time (long), app Uid (integer), app Pid (integer),
-     * seinfo tag (String), SHA-256 hash of the base APK in hexadecimal (String)
+     * <li> [0] process name ({@code String})
+     * <li> [1] exact start time in milliseconds according to {@code System.currentTimeMillis()}
+     *      ({@code Long})
+     * <li> [2] app uid ({@code Integer})
+     * <li> [3] app pid ({@code Integer})
+     * <li> [4] seinfo tag ({@code String})
+     * <li> [5] SHA-256 hash of the base APK in hexadecimal ({@code String})
      */
     public static final int TAG_APP_PROCESS_START = SecurityLogTags.SECURITY_APP_PROCESS_START;
+
     /**
-     * Indicate that keyguard is being dismissed.
+     * Indicates that keyguard has been dismissed.
      * There is no extra payload in the log event.
      */
-    public static final int TAG_KEYGUARD_DISMISSED =
-            SecurityLogTags.SECURITY_KEYGUARD_DISMISSED;
+    public static final int TAG_KEYGUARD_DISMISSED = SecurityLogTags.SECURITY_KEYGUARD_DISMISSED;
+
     /**
-     * Indicate that there has been an authentication attempt to dismiss the keyguard. The log entry
-     * contains the following information about the attempt encapsulated in an {@link Object} array,
-     * accessible via {@link SecurityEvent#getData()}:
-     * attempt result (integer, 1 for successful, 0 for unsuccessful), strength of auth method
-     * (integer, 1 if strong auth method was used, 0 otherwise)
+     * Indicates that there has been an authentication attempt to dismiss the keyguard. The log
+     * entry contains the following information about the attempt encapsulated in an {@link Object}
+     * array, accessible via {@link SecurityEvent#getData()}:
+     * <li> [0] attempt result ({@code Integer}, 1 for successful, 0 for unsuccessful)
+     * <li> [1] strength of authentication method ({@code Integer}, 1 if strong authentication
+     *      method was used, 0 otherwise)
      */
     public static final int TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT =
             SecurityLogTags.SECURITY_KEYGUARD_DISMISS_AUTH_ATTEMPT;
+
     /**
-     * Indicate that the device has been locked, either by user or by timeout.
-     * There is no extra payload in the log event.
+     * Indicates that the device has been locked, either by the user or by a timeout. There is no
+     * extra payload in the log event.
      */
     public static final int TAG_KEYGUARD_SECURED = SecurityLogTags.SECURITY_KEYGUARD_SECURED;
 
     /**
+     * Indicates that the Android OS has started. The log entry contains the following information
+     * about the startup time software integrity check encapsulated in an {@link Object} array,
+     * accessible via {@link SecurityEvent#getData()}:
+     * <li> [0] Verified Boot state ({@code String})
+     * <li> [1] dm-verity mode ({@code String}).
+     * <p>Verified Boot state can be one of the following:
+     * <li> {@code green} indicates that there is a full chain of trust extending from the
+     * bootloader to verified partitions including the bootloader, boot partition, and all verified
+     * partitions.
+     * <li> {@code yellow} indicates that the boot partition has been verified using the embedded
+     * certificate and the signature is valid.
+     * <li> {@code orange} indicates that the device may be freely modified. Device integrity is
+     * left to the user to verify out-of-band.
+     * <p>dm-verity mode can be one of the following:
+     * <li> {@code enforcing} indicates that the device will be restarted when corruption is
+     * detected.
+     * <li> {@code eio} indicates that an I/O error will be returned for an attempt to read
+     * corrupted data blocks.
+     * For details see Verified Boot documentation.
+     */
+    public static final int TAG_OS_STARTUP = SecurityLogTags.SECURITY_OS_STARTUP;
+
+    /**
+     * Indicates that the Android OS has shutdown. There is no extra payload in the log event.
+     */
+    public static final int TAG_OS_SHUTDOWN = SecurityLogTags.SECURITY_OS_SHUTDOWN;
+
+    /**
+     * Indicates start-up of audit logging. There is no extra payload in the log event.
+     */
+    public static final int TAG_LOGGING_STARTED = SecurityLogTags.SECURITY_LOGGING_STARTED;
+
+    /**
+     * Indicates shutdown of audit logging. There is no extra payload in the log event.
+     */
+    public static final int TAG_LOGGING_STOPPED = SecurityLogTags.SECURITY_LOGGING_STOPPED;
+
+    /**
+     * Indicates that removable media has been mounted on the device. The log entry contains the
+     * following information about the event, encapsulated in an {@link Object} array and
+     * accessible via {@link SecurityEvent#getData()}:
+     * <li> [0] mount point ({@code String})
+     * <li> [1] volume label ({@code String}).
+     */
+    public static final int TAG_MEDIA_MOUNT = SecurityLogTags.SECURITY_MEDIA_MOUNTED;
+
+    /**
+     * Indicates that removable media was unmounted from the device. The log entry contains the
+     * following information about the event, encapsulated in an {@link Object} array and
+     * accessible via {@link SecurityEvent#getData()}:
+     * <li> [0] mount point ({@code String})
+     * <li> [1] volume label ({@code String}).
+     */
+    public static final int TAG_MEDIA_UNMOUNT = SecurityLogTags.SECURITY_MEDIA_UNMOUNTED;
+
+    /**
+     * Indicates that the audit log buffer has reached 90% of its capacity. There is no extra
+     * payload in the log event.
+     */
+    public static final int TAG_LOG_BUFFER_SIZE_CRITICAL =
+            SecurityLogTags.SECURITY_LOG_BUFFER_SIZE_CRITICAL;
+
+    /**
+     * Indicates that an admin has set a password expiration timeout. The log entry contains the
+     * following information about the event, encapsulated in an {@link Object} array and accessible
+     * via {@link SecurityEvent#getData()}:
+     * <li> [0] admin package name ({@code String})
+     * <li> [1] admin user ID ({@code Integer})
+     * <li> [2] target user ID ({@code Integer})
+     * <li> [3] new password expiration timeout in milliseconds ({@code Long}).
+     * @see DevicePolicyManager#setPasswordExpirationTimeout(ComponentName, long)
+     */
+    public static final int TAG_PASSWORD_EXPIRATION_SET =
+            SecurityLogTags.SECURITY_PASSWORD_EXPIRATION_SET;
+
+    /**
+     * Indicates that an admin has set a requirement for password complexity. The log entry contains
+     * the following information about the event, encapsulated in an {@link Object} array and
+     * accessible via {@link SecurityEvent#getData()}:
+     * <li> [0] admin package name ({@code String})
+     * <li> [1] admin user ID ({@code Integer})
+     * <li> [2] target user ID ({@code Integer})
+     * <li> [3] minimum password length ({@code Integer})
+     * <li> [4] password quality constraint ({@code Integer})
+     * <li> [5] minimum number of letters ({@code Integer})
+     * <li> [6] minimum number of non-letters ({@code Integer})
+     * <li> [7] minimum number of digits ({@code Integer})
+     * <li> [8] minimum number of uppercase letters ({@code Integer})
+     * <li> [9] minimum number of lowercase letters ({@code Integer})
+     * <li> [10] minimum number of symbols ({@code Integer})
+     *
+     * @see DevicePolicyManager#setPasswordMinimumLength(ComponentName, int)
+     * @see DevicePolicyManager#setPasswordQuality(ComponentName, int)
+     * @see DevicePolicyManager#setPasswordMinimumLetters(ComponentName, int)
+     * @see DevicePolicyManager#setPasswordMinimumNonLetter(ComponentName, int)
+     * @see DevicePolicyManager#setPasswordMinimumLowerCase(ComponentName, int)
+     * @see DevicePolicyManager#setPasswordMinimumUpperCase(ComponentName, int)
+     * @see DevicePolicyManager#setPasswordMinimumNumeric(ComponentName, int)
+     * @see DevicePolicyManager#setPasswordMinimumSymbols(ComponentName, int)
+     */
+    public static final int TAG_PASSWORD_COMPLEXITY_SET =
+            SecurityLogTags.SECURITY_PASSWORD_COMPLEXITY_SET;
+
+    /**
+     * Indicates that an admin has set a password history length. The log entry contains the
+     * following information about the event encapsulated in an {@link Object} array, accessible
+     * via {@link SecurityEvent#getData()}:
+     * <li> [0] admin package name ({@code String})
+     * <li> [1] admin user ID ({@code Integer})
+     * <li> [2] target user ID ({@code Integer})
+     * <li> [3] new password history length value ({@code Integer})
+     * @see DevicePolicyManager#setPasswordHistoryLength(ComponentName, int)
+     */
+    public static final int TAG_PASSWORD_HISTORY_LENGTH_SET =
+            SecurityLogTags.SECURITY_PASSWORD_HISTORY_LENGTH_SET;
+
+    /**
+     * Indicates that an admin has set a maximum screen lock timeout. The log entry contains the
+     * following information about the event encapsulated in an {@link Object} array, accessible
+     * via {@link SecurityEvent#getData()}:
+     * <li> [0] admin package name ({@code String})
+     * <li> [1] admin user ID ({@code Integer})
+     * <li> [2] target user ID ({@code Integer})
+     * <li> [3] new screen lock timeout in milliseconds ({@code Long})
+     * @see DevicePolicyManager#setMaximumTimeToLock(ComponentName, long)
+     */
+    public static final int TAG_MAX_SCREEN_LOCK_TIMEOUT_SET =
+            SecurityLogTags.SECURITY_MAX_SCREEN_LOCK_TIMEOUT_SET;
+
+    /**
+     * Indicates that an admin has set a maximum number of failed password attempts before wiping
+     * data. The log entry contains the following information about the event encapsulated in an
+     * {@link Object} array, accessible via {@link SecurityEvent#getData()}:
+     * <li> [0] admin package name ({@code String})
+     * <li> [1] admin user ID ({@code Integer})
+     * <li> [2] target user ID ({@code Integer})
+     * <li> [3] new maximum number of failed password attempts ({@code Integer})
+     * @see DevicePolicyManager#setMaximumTimeToLock(ComponentName, long)
+     */
+    public static final int TAG_MAX_PASSWORD_ATTEMPTS_SET =
+            SecurityLogTags.SECURITY_MAX_PASSWORD_ATTEMPTS_SET;
+
+    /**
+     * Indicates that an admin has set disabled keyguard features. The log entry contains the
+     * following information about the event encapsulated in an {@link Object} array, accessible via
+     * {@link SecurityEvent#getData()}:
+     * <li> [0] admin package name ({@code String})
+     * <li> [1] admin user ID ({@code Integer})
+     * <li> [2] target user ID ({@code Integer})
+     * <li> [3] disabled keyguard feature mask ({@code Integer}).
+     * @see DevicePolicyManager#setKeyguardDisabledFeatures(ComponentName, int)
+     */
+    public static final int TAG_KEYGUARD_DISABLED_FEATURES_SET =
+            SecurityLogTags.SECURITY_KEYGUARD_DISABLED_FEATURES_SET;
+
+    /**
+     * Indicates that an admin remotely locked the device or profile. The log entry contains the
+     * following information about the event encapsulated in an {@link Object} array, accessible via
+     * {@link SecurityEvent#getData()}:
+     * <li> [0] admin package name ({@code String}),
+     * <li> [1] admin user ID ({@code Integer}).
+     */
+    public static final int TAG_REMOTE_LOCK = SecurityLogTags.SECURITY_REMOTE_LOCK;
+
+    /**
+     * Indicates a failure to wipe device or user data. There is no extra payload in the log event.
+     */
+    public static final int TAG_WIPE_FAILURE = SecurityLogTags.SECURITY_WIPE_FAILED;
+
+    /**
+     * Indicates that an authentication key was generated. The log entry contains the following
+     * information about the event, encapsulated in an {@link Object} array and accessible via
+     * {@link SecurityEvent#getData()}:
+     * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
+     * <li> [1] alias of the key ({@code String})
+     * <li> [2] requesting process uid ({@code Integer}).
+     */
+    public static final int TAG_KEY_GENERATED =
+            SecurityLogTags.SECURITY_KEY_GENERATED;
+
+    /**
+     * Indicates that a cryptographic key was imported. The log entry contains the following
+     * information about the event, encapsulated in an {@link Object} array and accessible via
+     * {@link SecurityEvent#getData()}:
+     * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
+     * <li> [1] alias of the key ({@code String})
+     * <li> [2] requesting process uid ({@code Integer}).
+     */
+    public static final int TAG_KEY_IMPORT = SecurityLogTags.SECURITY_KEY_IMPORTED;
+
+    /**
+     * Indicates that a cryptographic key was destroyed. The log entry contains the following
+     * information about the event, encapsulated in an {@link Object} array and accessible via
+     * {@link SecurityEvent#getData()}:
+     * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
+     * <li> [1] alias of the key ({@code String})
+     * <li> [2] requesting process uid ({@code Integer}).
+     */
+    public static final int TAG_KEY_DESTRUCTION = SecurityLogTags.SECURITY_KEY_DESTROYED;
+
+    /**
+     * Indicates that a new root certificate has been installed into system's trusted credential
+     * storage. The log entry contains the following information about the event, encapsulated in an
+     * {@link Object} array and accessible via {@link SecurityEvent#getData()}:
+     * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
+     * <li> [1] subject of the certificate ({@code String}).
+     */
+    public static final int TAG_CERT_AUTHORITY_INSTALLED =
+            SecurityLogTags.SECURITY_CERT_AUTHORITY_INSTALLED;
+
+    /**
+     * Indicates that a new oot certificate has been removed from system's trusted credential
+     * storage. The log entry contains the following information about the event, encapsulated in an
+     * {@link Object} array and accessible via {@link SecurityEvent#getData()}:
+     * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
+     * <li> [1] subject of the certificate ({@code String}).
+     */
+    public static final int TAG_CERT_AUTHORITY_REMOVED =
+            SecurityLogTags.SECURITY_CERT_AUTHORITY_REMOVED;
+
+    /**
+     * Indicates that an admin has set a user restriction. The log entry contains the following
+     * information about the event, encapsulated in an {@link Object} array and accessible via
+     * {@link SecurityEvent#getData()}:
+     * <li> [0] admin package name ({@code String})
+     * <li> [1] admin user ID ({@code Integer})
+     * <li> [2] user restriction ({@code String})
+     * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
+     */
+    public static final int TAG_USER_RESTRICTION_ADDED =
+            SecurityLogTags.SECURITY_USER_RESTRICTION_ADDED;
+
+    /**
+     * Indicates that an admin has removed a user restriction. The log entry contains the following
+     * information about the event, encapsulated in an {@link Object} array and accessible via
+     * {@link SecurityEvent#getData()}:
+     * <li> [0] admin package name ({@code String})
+     * <li> [1] admin user ID ({@code Integer})
+     * <li> [2] user restriction ({@code String})
+     * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
+     */
+    public static final int TAG_USER_RESTRICTION_REMOVED =
+            SecurityLogTags.SECURITY_USER_RESTRICTION_REMOVED;
+
+    /**
+     * Event severity level indicating that the event corresponds to normal workflow.
+     */
+    public static final int LEVEL_INFO = 1;
+
+    /**
+     * Event severity level indicating that the event may require admin attention.
+     */
+    public static final int LEVEL_WARNING = 2;
+
+    /**
+     * Event severity level indicating that the event requires urgent admin action.
+     */
+    public static final int LEVEL_ERROR = 3;
+
+    /**
      * Returns if security logging is enabled. Log producers should only write new logs if this is
      * true. Under the hood this is the logical AND of whether device owner exists and whether
      * it enables logging by setting the system property {@link #PROPERTY_LOGGING_ENABLED}.
@@ -198,6 +502,60 @@
             return mId;
         }
 
+        /**
+         * Returns severity level for the event.
+         */
+        public @SecurityLogLevel int getLogLevel() {
+            switch (mEvent.getTag()) {
+                case TAG_ADB_SHELL_INTERACTIVE:
+                case TAG_ADB_SHELL_CMD:
+                case TAG_SYNC_RECV_FILE:
+                case TAG_SYNC_SEND_FILE:
+                case TAG_APP_PROCESS_START:
+                case TAG_KEYGUARD_DISMISSED:
+                case TAG_KEYGUARD_SECURED:
+                case TAG_OS_STARTUP:
+                case TAG_OS_SHUTDOWN:
+                case TAG_LOGGING_STARTED:
+                case TAG_LOGGING_STOPPED:
+                case TAG_MEDIA_MOUNT:
+                case TAG_MEDIA_UNMOUNT:
+                case TAG_PASSWORD_EXPIRATION_SET:
+                case TAG_PASSWORD_COMPLEXITY_SET:
+                case TAG_PASSWORD_HISTORY_LENGTH_SET:
+                case TAG_MAX_SCREEN_LOCK_TIMEOUT_SET:
+                case TAG_MAX_PASSWORD_ATTEMPTS_SET:
+                case TAG_USER_RESTRICTION_ADDED:
+                case TAG_USER_RESTRICTION_REMOVED:
+                    return LEVEL_INFO;
+                case TAG_CERT_AUTHORITY_REMOVED:
+                    return getSuccess() ? LEVEL_INFO : LEVEL_ERROR;
+                case TAG_CERT_AUTHORITY_INSTALLED:
+                case TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT:
+                case TAG_KEY_IMPORT:
+                case TAG_KEY_DESTRUCTION:
+                case TAG_KEY_GENERATED:
+                    return getSuccess() ? LEVEL_INFO : LEVEL_WARNING;
+                case TAG_LOG_BUFFER_SIZE_CRITICAL:
+                case TAG_WIPE_FAILURE:
+                    return LEVEL_ERROR;
+                default:
+                    return LEVEL_INFO;
+            }
+        }
+
+        // Success/failure if present is encoded as an integer in the first (0th) element of data.
+        private boolean getSuccess() {
+            final Object data = getData();
+            if (data == null || !(data instanceof Object[])) {
+                return false;
+            }
+
+            final Object[] array = (Object[]) data;
+            return array.length >= 1 && array[0] instanceof Integer && (Integer) array[0] != 0;
+        }
+
+
         @Override
         public int describeContents() {
             return 0;
@@ -263,8 +621,8 @@
             throws IOException;
 
     /**
-     * Retrieve all security logs whose timestamp (in nanosceonds) is equal to or greater than the
-     * given timestamp. This method will block until either the last log earlier than the given
+     * Retrieve all security logs whose timestamp is equal to or greater than the given timestamp in
+     * nanoseconds. This method will block until either the last log earlier than the given
      * timestamp is about to be pruned, or after a 2-hour timeout has passed.
      * @hide
      */
diff --git a/core/java/android/app/admin/SecurityLogTags.logtags b/core/java/android/app/admin/SecurityLogTags.logtags
index 39371c7..be62678 100644
--- a/core/java/android/app/admin/SecurityLogTags.logtags
+++ b/core/java/android/app/admin/SecurityLogTags.logtags
@@ -10,3 +10,28 @@
 210006 security_keyguard_dismissed
 210007 security_keyguard_dismiss_auth_attempt   (success|1),(method_strength|1)
 210008 security_keyguard_secured
+
+# Additional event types for NIAP MDFPP 3.1 compliant audit logging.
+
+210009 security_os_startup                      (boot_state|3),(verity_mode|3)
+210010 security_os_shutdown
+210011 security_logging_started
+210012 security_logging_stopped
+210013 security_media_mounted                   (path|3),(label|3)
+210014 security_media_unmounted                 (path|3),(label|3)
+210015 security_log_buffer_size_critical
+210016 security_password_expiration_set         (package|3),(admin_user|1),(target_user|1),(timeout|2|3)
+210017 security_password_complexity_set         (package|3),(admin_user|1),(target_user|1),(length|1),(quality|1),(num_letters|1),(num_non_letters|1),(num_numeric|1),(num_uppercase|1),(num_lowercase|1),(num_symbols|1)
+210018 security_password_history_length_set     (package|3),(admin_user|1),(target_user|1),(length|1)
+210019 security_max_screen_lock_timeout_set     (package|3),(admin_user|1),(target_user|1),(timeout|2|3)
+210020 security_max_password_attempts_set       (package|3),(admin_user|1),(target_user|1),(num_failures|1)
+210021 security_keyguard_disabled_features_set  (package|3),(admin_user|1),(target_user|1),(features|1)
+210022 security_remote_lock                     (package|3),(admin_user|1),(target_user|1)
+210023 security_wipe_failed                     (package|3),(admin_user|1)
+210024 security_key_generated                   (success|1),(key_id|3),(uid|1)
+210025 security_key_imported                    (success|1),(key_id|3),(uid|1)
+210026 security_key_destroyed                   (success|1),(key_id|3),(uid|1)
+210027 security_user_restriction_added          (package|3),(admin_user|1),(restriction|3)
+210028 security_user_restriction_removed        (package|3),(admin_user|1),(restriction|3)
+210029 security_cert_authority_installed        (success|1),(subject|3)
+210030 security_cert_authority_removed          (success|1),(subject|3)
\ No newline at end of file
diff --git a/core/java/android/app/slice/Slice.java b/core/java/android/app/slice/Slice.java
index 5808f8b..4c24a2d 100644
--- a/core/java/android/app/slice/Slice.java
+++ b/core/java/android/app/slice/Slice.java
@@ -146,11 +146,6 @@
      */
     public static final String HINT_PARTIAL     = "partial";
     /**
-     * A hint representing that this item is the max value possible for the slice containing this.
-     * Used to indicate the maximum integer value for a {@link #SUBTYPE_SLIDER}.
-     */
-    public static final String HINT_MAX = "max";
-    /**
      * A hint representing that this item should be used to indicate that there's more
      * content associated with this slice.
      */
@@ -168,6 +163,10 @@
      */
     public static final String EXTRA_TOGGLE_STATE = "android.app.slice.extra.TOGGLE_STATE";
     /**
+     * Key to retrieve an extra added to an intent when the value of a slider is changed.
+     */
+    public static final String EXTRA_SLIDER_VALUE = "android.app.slice.extra.SLIDER_VALUE";
+    /**
      * Subtype to indicate that this is a message as part of a communication
      * sequence in this slice.
      */
@@ -181,10 +180,18 @@
      */
     public static final String SUBTYPE_COLOR = "color";
     /**
-     * Subtype to tag an item represents a slider.
+     * Subtype to tag an item as representing a slider.
      */
     public static final String SUBTYPE_SLIDER = "slider";
     /**
+     * Subtype to tag an item as representing the max int value for a {@link #SUBTYPE_SLIDER}.
+     */
+    public static final String SUBTYPE_MAX = "max";
+    /**
+     * Subtype to tag an item as representing the current int value for a {@link #SUBTYPE_SLIDER}.
+     */
+    public static final String SUBTYPE_VALUE = "value";
+    /**
      * Subtype to indicate that this content has a toggle action associated with it. To indicate
      * that the toggle is on, use {@link #HINT_SELECTED}. When the toggle state changes, the
      * intent associated with it will be sent along with an extra {@link #EXTRA_TOGGLE_STATE}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 4923171..7b27fc0 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -50,6 +50,7 @@
 import android.provider.DocumentsProvider;
 import android.provider.MediaStore;
 import android.provider.OpenableColumns;
+import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -4472,7 +4473,15 @@
     public static final String EXTRA_INSTANT_APP_ACTION = "android.intent.extra.INSTANT_APP_ACTION";
 
     /**
-     * A {@link Bundle} of metadata that describes the instanta application that needs to be
+     * An array of {@link Bundle}s containing details about resolved instant apps..
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_INSTANT_APP_BUNDLES =
+            "android.intent.extra.INSTANT_APP_BUNDLES";
+
+    /**
+     * A {@link Bundle} of metadata that describes the instant application that needs to be
      * installed. This data is populated from the response to
      * {@link android.content.pm.InstantAppResolveInfo#getExtras()} as provided by the registered
      * instant application resolver.
@@ -4482,6 +4491,16 @@
             "android.intent.extra.INSTANT_APP_EXTRAS";
 
     /**
+     * A boolean value indicating that the instant app resolver was unable to state with certainty
+     * that it did or did not have an app for the sanitized {@link Intent} defined at
+     * {@link #EXTRA_INTENT}.
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_UNKNOWN_INSTANT_APP =
+            "android.intent.extra.UNKNOWN_INSTANT_APP";
+
+    /**
      * The version code of the app to install components from.
      * @deprecated Use {@link #EXTRA_LONG_VERSION_CODE).
      * @hide
@@ -5029,6 +5048,7 @@
             FLAG_GRANT_PREFIX_URI_PERMISSION,
             FLAG_DEBUG_TRIAGED_MISSING,
             FLAG_IGNORE_EPHEMERAL,
+            FLAG_ACTIVITY_MATCH_EXTERNAL,
             FLAG_ACTIVITY_NO_HISTORY,
             FLAG_ACTIVITY_SINGLE_TOP,
             FLAG_ACTIVITY_NEW_TASK,
@@ -5072,6 +5092,7 @@
             FLAG_INCLUDE_STOPPED_PACKAGES,
             FLAG_DEBUG_TRIAGED_MISSING,
             FLAG_IGNORE_EPHEMERAL,
+            FLAG_ACTIVITY_MATCH_EXTERNAL,
             FLAG_ACTIVITY_NO_HISTORY,
             FLAG_ACTIVITY_SINGLE_TOP,
             FLAG_ACTIVITY_NEW_TASK,
@@ -5475,6 +5496,14 @@
      */
     public static final int FLAG_ACTIVITY_LAUNCH_ADJACENT = 0x00001000;
 
+
+    /**
+     * If set, resolution of this intent may take place via an instant app not
+     * yet on the device if there does not yet exist an app on device to
+     * resolve it.
+     */
+    public static final int FLAG_ACTIVITY_MATCH_EXTERNAL = 0x00000800;
+
     /**
      * If set, when sending a broadcast only registered receivers will be
      * called -- no BroadcastReceiver components will be launched.
@@ -10024,6 +10053,25 @@
         }
     }
 
+    /** @hide */
+    public boolean hasWebURI() {
+        if (getData() == null) {
+            return false;
+        }
+        final String scheme = getScheme();
+        if (TextUtils.isEmpty(scheme)) {
+            return false;
+        }
+        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
+    }
+
+    /** @hide */
+    public boolean isBrowsableWebIntent() {
+        return ACTION_VIEW.equals(mAction)
+                && hasCategory(CATEGORY_BROWSABLE)
+                && hasWebURI();
+    }
+
     /**
      * @hide
      */
diff --git a/core/java/android/content/pm/AuxiliaryResolveInfo.java b/core/java/android/content/pm/AuxiliaryResolveInfo.java
index 6bdcefb..202df50 100644
--- a/core/java/android/content/pm/AuxiliaryResolveInfo.java
+++ b/core/java/android/content/pm/AuxiliaryResolveInfo.java
@@ -21,6 +21,10 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.os.Bundle;
+
+import java.util.Collections;
+import java.util.List;
 
 /**
  * Auxiliary application resolution response.
@@ -31,56 +35,95 @@
  * hasn't been installed.
  * @hide
  */
-public final class AuxiliaryResolveInfo extends IntentFilter {
-    /** Resolved information returned from the external instant resolver */
-    public final InstantAppResolveInfo resolveInfo;
-    /** The resolved package. Copied from {@link #resolveInfo}. */
-    public final String packageName;
+public final class AuxiliaryResolveInfo {
     /** The activity to launch if there's an installation failure. */
     public final ComponentName installFailureActivity;
-    /** The resolve split. Copied from the matched filter in {@link #resolveInfo}. */
-    public final String splitName;
     /** Whether or not instant resolution needs the second phase */
     public final boolean needsPhaseTwo;
     /** Opaque token to track the instant application resolution */
     public final String token;
-    /** The version code of the package */
-    public final long versionCode;
     /** An intent to start upon failure to install */
     public final Intent failureIntent;
+    /** The matching filters for this resolve info. */
+    public final List<AuxiliaryFilter> filters;
 
     /** Create a response for installing an instant application. */
-    public AuxiliaryResolveInfo(@NonNull InstantAppResolveInfo resolveInfo,
-            @NonNull IntentFilter orig,
-            @Nullable String splitName,
-            @NonNull String token,
+    public AuxiliaryResolveInfo(@NonNull String token,
             boolean needsPhase2,
-            @Nullable Intent failureIntent) {
-        super(orig);
-        this.resolveInfo = resolveInfo;
-        this.packageName = resolveInfo.getPackageName();
-        this.splitName = splitName;
+            @Nullable Intent failureIntent,
+            @Nullable List<AuxiliaryFilter> filters) {
         this.token = token;
         this.needsPhaseTwo = needsPhase2;
-        this.versionCode = resolveInfo.getVersionCode();
         this.failureIntent = failureIntent;
+        this.filters = filters;
         this.installFailureActivity = null;
     }
 
     /** Create a response for installing a split on demand. */
-    public AuxiliaryResolveInfo(@NonNull String packageName,
-            @Nullable String splitName,
-            @Nullable ComponentName failureActivity,
-            long versionCode,
-            @Nullable Intent failureIntent) {
+    public AuxiliaryResolveInfo(@Nullable ComponentName failureActivity,
+            @Nullable Intent failureIntent,
+            @Nullable List<AuxiliaryFilter> filters) {
         super();
-        this.packageName = packageName;
         this.installFailureActivity = failureActivity;
-        this.splitName = splitName;
-        this.versionCode = versionCode;
-        this.resolveInfo = null;
+        this.filters = filters;
         this.token = null;
         this.needsPhaseTwo = false;
         this.failureIntent = failureIntent;
     }
+
+    /** Create a response for installing a split on demand. */
+    public AuxiliaryResolveInfo(@Nullable ComponentName failureActivity,
+            String packageName, long versionCode, String splitName) {
+        this(failureActivity, null, Collections.singletonList(
+                new AuxiliaryResolveInfo.AuxiliaryFilter(packageName, versionCode, splitName)));
+    }
+
+    /** @hide */
+    public static final class AuxiliaryFilter extends IntentFilter {
+        /** Resolved information returned from the external instant resolver */
+        public final InstantAppResolveInfo resolveInfo;
+        /** The resolved package. Copied from {@link #resolveInfo}. */
+        public final String packageName;
+        /** The version code of the package */
+        public final long versionCode;
+        /** The resolve split. Copied from the matched filter in {@link #resolveInfo}. */
+        public final String splitName;
+        /** The extras to pass on to the installer for this filter. */
+        public final Bundle extras;
+
+        public AuxiliaryFilter(IntentFilter orig, InstantAppResolveInfo resolveInfo,
+                String splitName, Bundle extras) {
+            super(orig);
+            this.resolveInfo = resolveInfo;
+            this.packageName = resolveInfo.getPackageName();
+            this.versionCode = resolveInfo.getLongVersionCode();
+            this.splitName = splitName;
+            this.extras = extras;
+        }
+
+        public AuxiliaryFilter(InstantAppResolveInfo resolveInfo,
+                String splitName, Bundle extras) {
+            this.resolveInfo = resolveInfo;
+            this.packageName = resolveInfo.getPackageName();
+            this.versionCode = resolveInfo.getLongVersionCode();
+            this.splitName = splitName;
+            this.extras = extras;
+        }
+
+        public AuxiliaryFilter(String packageName, long versionCode, String splitName) {
+            this.resolveInfo = null;
+            this.packageName = packageName;
+            this.versionCode = versionCode;
+            this.splitName = splitName;
+            this.extras = null;
+        }
+
+        @Override
+        public String toString() {
+            return "AuxiliaryFilter{"
+                    + "packageName='" + packageName + '\''
+                    + ", versionCode=" + versionCode
+                    + ", splitName='" + splitName + '\'' + '}';
+        }
+    }
 }
\ No newline at end of file
diff --git a/core/java/android/content/pm/InstantAppResolveInfo.java b/core/java/android/content/pm/InstantAppResolveInfo.java
index 19cb932..112c5da 100644
--- a/core/java/android/content/pm/InstantAppResolveInfo.java
+++ b/core/java/android/content/pm/InstantAppResolveInfo.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.content.Intent;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -26,11 +27,35 @@
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
 
 /**
- * Information about an instant application.
+ * Describes an externally resolvable instant application. There are three states that this class
+ * can represent: <p/>
+ * <ul>
+ *     <li>
+ *         The first, usable only for non http/s intents, implies that the resolver cannot
+ *         immediately resolve this intent and would prefer that resolution be deferred to the
+ *         instant app installer. Represent this state with {@link #InstantAppResolveInfo(Bundle)}.
+ *         If the {@link android.content.Intent} has the scheme set to http/s and a set of digest
+ *         prefixes were passed into one of the resolve methods in
+ *         {@link android.app.InstantAppResolverService}, this state cannot be used.
+ *     </li>
+ *     <li>
+ *         The second represents a partial match and is constructed with any of the other
+ *         constructors. By setting one or more of the {@link Nullable}arguments to null, you
+ *         communicate to the resolver in response to
+ *         {@link android.app.InstantAppResolverService#onGetInstantAppResolveInfo(Intent, int[],
+ *                String, InstantAppResolverService.InstantAppResolutionCallback)}
+ *         that you need a 2nd round of resolution to complete the request.
+ *     </li>
+ *     <li>
+ *         The third represents a complete match and is constructed with all @Nullable parameters
+ *         populated.
+ *     </li>
+ * </ul>
  * @hide
  */
 @SystemApi
@@ -38,6 +63,8 @@
     /** Algorithm that will be used to generate the domain digest */
     private static final String SHA_ALGORITHM = "SHA-256";
 
+    private static final byte[] EMPTY_DIGEST = new byte[0];
+
     private final InstantAppDigest mDigest;
     private final String mPackageName;
     /** The filters used to match domain */
@@ -46,15 +73,30 @@
     private final long mVersionCode;
     /** Data about the app that should be passed along to the Instant App installer on resolve */
     private final Bundle mExtras;
+    /**
+     * A flag that indicates that the resolver is aware that an app may match, but would prefer
+     * that the installer get the sanitized intent to decide. This should not be used for
+     * resolutions that include a host and will be ignored in such cases.
+     */
+    private final boolean mShouldLetInstallerDecide;
 
+    /** Constructor for intent-based InstantApp resolution results. */
     public InstantAppResolveInfo(@NonNull InstantAppDigest digest, @Nullable String packageName,
             @Nullable List<InstantAppIntentFilter> filters, int versionCode) {
         this(digest, packageName, filters, (long) versionCode, null /* extras */);
     }
 
+    /** Constructor for intent-based InstantApp resolution results with extras. */
     public InstantAppResolveInfo(@NonNull InstantAppDigest digest, @Nullable String packageName,
             @Nullable List<InstantAppIntentFilter> filters, long versionCode,
             @Nullable Bundle extras) {
+        this(digest, packageName, filters, versionCode, extras, false);
+    }
+
+    /** Constructor for intent-based InstantApp resolution results with extras. */
+    private InstantAppResolveInfo(@NonNull InstantAppDigest digest, @Nullable String packageName,
+            @Nullable List<InstantAppIntentFilter> filters, long versionCode,
+            @Nullable Bundle extras, boolean shouldLetInstallerDecide) {
         // validate arguments
         if ((packageName == null && (filters != null && filters.size() != 0))
                 || (packageName != null && (filters == null || filters.size() == 0))) {
@@ -62,7 +104,7 @@
         }
         mDigest = digest;
         if (filters != null) {
-            mFilters = new ArrayList<InstantAppIntentFilter>(filters.size());
+            mFilters = new ArrayList<>(filters.size());
             mFilters.addAll(filters);
         } else {
             mFilters = null;
@@ -70,25 +112,48 @@
         mPackageName = packageName;
         mVersionCode = versionCode;
         mExtras = extras;
+        mShouldLetInstallerDecide = shouldLetInstallerDecide;
     }
 
+    /** Constructor for intent-based InstantApp resolution results by hostname. */
     public InstantAppResolveInfo(@NonNull String hostName, @Nullable String packageName,
             @Nullable List<InstantAppIntentFilter> filters) {
         this(new InstantAppDigest(hostName), packageName, filters, -1 /*versionCode*/,
                 null /* extras */);
     }
 
+    /**
+     * Constructor that creates a "let the installer decide" response with optional included
+     * extras.
+     */
+    public InstantAppResolveInfo(@Nullable Bundle extras) {
+        this(InstantAppDigest.UNDEFINED, null, null, -1, extras, true);
+    }
+
     InstantAppResolveInfo(Parcel in) {
-        mDigest = in.readParcelable(null /*loader*/);
-        mPackageName = in.readString();
-        mFilters = new ArrayList<InstantAppIntentFilter>();
-        in.readList(mFilters, null /*loader*/);
-        mVersionCode = in.readLong();
+        mShouldLetInstallerDecide = in.readBoolean();
         mExtras = in.readBundle();
+        if (mShouldLetInstallerDecide) {
+            mDigest = InstantAppDigest.UNDEFINED;
+            mPackageName = null;
+            mFilters = Collections.emptyList();
+            mVersionCode = -1;
+        } else {
+            mDigest = in.readParcelable(null /*loader*/);
+            mPackageName = in.readString();
+            mFilters = new ArrayList<>();
+            in.readList(mFilters, null /*loader*/);
+            mVersionCode = in.readLong();
+        }
+    }
+
+    /** Returns true if the installer should be notified that it should query for packages. */
+    public boolean shouldLetInstallerDecide() {
+        return mShouldLetInstallerDecide;
     }
 
     public byte[] getDigestBytes() {
-        return mDigest.getDigestBytes()[0];
+        return mDigest.mDigestBytes.length > 0 ? mDigest.getDigestBytes()[0] : EMPTY_DIGEST;
     }
 
     public int getDigestPrefix() {
@@ -127,11 +192,15 @@
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
+        out.writeBoolean(mShouldLetInstallerDecide);
+        out.writeBundle(mExtras);
+        if (mShouldLetInstallerDecide) {
+            return;
+        }
         out.writeParcelable(mDigest, flags);
         out.writeString(mPackageName);
         out.writeList(mFilters);
         out.writeLong(mVersionCode);
-        out.writeBundle(mExtras);
     }
 
     public static final Parcelable.Creator<InstantAppResolveInfo> CREATOR
@@ -159,7 +228,9 @@
     @SystemApi
     public static final class InstantAppDigest implements Parcelable {
         private static final int DIGEST_MASK = 0xfffff000;
-        private static final int DIGEST_PREFIX_COUNT = 5;
+
+        public static final InstantAppDigest UNDEFINED =
+                new InstantAppDigest(new byte[][]{}, new int[]{});
         /** Full digest of the domain hashes */
         private final byte[][] mDigestBytes;
         /** The first 4 bytes of the domain hashes */
@@ -186,6 +257,11 @@
             }
         }
 
+        private InstantAppDigest(byte[][] digestBytes, int[] prefix) {
+            this.mDigestPrefix = prefix;
+            this.mDigestBytes = digestBytes;
+        }
+
         private static byte[][] generateDigest(String hostName, int maxDigests) {
             ArrayList<byte[]> digests = new ArrayList<>();
             try {
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index f84ec65..a748f4d 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -28,6 +28,7 @@
 import android.util.LongSparseArray;
 import android.util.SparseIntArray;
 
+import dalvik.annotation.optimization.FastNative;
 import dalvik.system.CloseGuard;
 
 /**
@@ -62,28 +63,43 @@
     private static native void nativeDispose(long windowPtr);
     private static native void nativeWriteToParcel(long windowPtr, Parcel parcel);
 
-    private static native void nativeClear(long windowPtr);
-
-    private static native int nativeGetNumRows(long windowPtr);
-    private static native boolean nativeSetNumColumns(long windowPtr, int columnNum);
-    private static native boolean nativeAllocRow(long windowPtr);
-    private static native void nativeFreeLastRow(long windowPtr);
-
-    private static native int nativeGetType(long windowPtr, int row, int column);
+    private static native String nativeGetName(long windowPtr);
     private static native byte[] nativeGetBlob(long windowPtr, int row, int column);
     private static native String nativeGetString(long windowPtr, int row, int column);
-    private static native long nativeGetLong(long windowPtr, int row, int column);
-    private static native double nativeGetDouble(long windowPtr, int row, int column);
     private static native void nativeCopyStringToBuffer(long windowPtr, int row, int column,
             CharArrayBuffer buffer);
-
     private static native boolean nativePutBlob(long windowPtr, byte[] value, int row, int column);
-    private static native boolean nativePutString(long windowPtr, String value, int row, int column);
+    private static native boolean nativePutString(long windowPtr, String value,
+            int row, int column);
+
+    // Below native methods don't do unconstrained work, so are FastNative for performance
+
+    @FastNative
+    private static native void nativeClear(long windowPtr);
+
+    @FastNative
+    private static native int nativeGetNumRows(long windowPtr);
+    @FastNative
+    private static native boolean nativeSetNumColumns(long windowPtr, int columnNum);
+    @FastNative
+    private static native boolean nativeAllocRow(long windowPtr);
+    @FastNative
+    private static native void nativeFreeLastRow(long windowPtr);
+
+    @FastNative
+    private static native int nativeGetType(long windowPtr, int row, int column);
+    @FastNative
+    private static native long nativeGetLong(long windowPtr, int row, int column);
+    @FastNative
+    private static native double nativeGetDouble(long windowPtr, int row, int column);
+
+    @FastNative
     private static native boolean nativePutLong(long windowPtr, long value, int row, int column);
+    @FastNative
     private static native boolean nativePutDouble(long windowPtr, double value, int row, int column);
+    @FastNative
     private static native boolean nativePutNull(long windowPtr, int row, int column);
 
-    private static native String nativeGetName(long windowPtr);
 
     /**
      * Creates a new empty cursor window and gives it a name.
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index 7fb0c89..7297426 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -22,7 +22,9 @@
 
 /**
  * Class representing a sensor. Use {@link SensorManager#getSensorList} to get
- * the list of available Sensors.
+ * the list of available sensors. For more information about Android sensors,
+ * read the
+ * <a href="/guide/topics/sensors/sensors_motion.html">Motion Sensors guide</a>.</p>
  *
  * @see SensorManager
  * @see SensorEventListener
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index 13b9206..2306e5f 100644
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -61,6 +61,7 @@
  * @attr ref android.R.styleable#KeyboardView_keyBackground
  * @attr ref android.R.styleable#KeyboardView_keyPreviewLayout
  * @attr ref android.R.styleable#KeyboardView_keyPreviewOffset
+ * @attr ref android.R.styleable#KeyboardView_keyPreviewHeight
  * @attr ref android.R.styleable#KeyboardView_labelTextSize
  * @attr ref android.R.styleable#KeyboardView_keyTextSize
  * @attr ref android.R.styleable#KeyboardView_keyTextColor
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index f83bda0..e606964 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -116,6 +116,8 @@
         /** The proportional set size that is swappable for dalvik heap. */
         /** @hide We may want to expose this, eventually. */
         public int dalvikSwappablePss;
+        /** @hide The resident set size for dalvik heap.  (Without other Dalvik overhead.) */
+        public int dalvikRss;
         /** The private dirty pages used by dalvik heap. */
         public int dalvikPrivateDirty;
         /** The shared dirty pages used by dalvik heap. */
@@ -138,6 +140,8 @@
         /** The proportional set size that is swappable for the native heap. */
         /** @hide We may want to expose this, eventually. */
         public int nativeSwappablePss;
+        /** @hide The resident set size for the native heap. */
+        public int nativeRss;
         /** The private dirty pages used by the native heap. */
         public int nativePrivateDirty;
         /** The shared dirty pages used by the native heap. */
@@ -160,6 +164,8 @@
         /** The proportional set size that is swappable for everything else. */
         /** @hide We may want to expose this, eventually. */
         public int otherSwappablePss;
+        /** @hide The resident set size for everything else. */
+        public int otherRss;
         /** The private dirty pages used by everything else. */
         public int otherPrivateDirty;
         /** The shared dirty pages used by everything else. */
@@ -288,24 +294,26 @@
         public static final int NUM_DVK_STATS = 14;
 
         /** @hide */
-        public static final int NUM_CATEGORIES = 8;
+        public static final int NUM_CATEGORIES = 9;
 
         /** @hide */
-        public static final int offsetPss = 0;
+        public static final int OFFSET_PSS = 0;
         /** @hide */
-        public static final int offsetSwappablePss = 1;
+        public static final int OFFSET_SWAPPABLE_PSS = 1;
         /** @hide */
-        public static final int offsetPrivateDirty = 2;
+        public static final int OFFSET_RSS = 2;
         /** @hide */
-        public static final int offsetSharedDirty = 3;
+        public static final int OFFSET_PRIVATE_DIRTY = 3;
         /** @hide */
-        public static final int offsetPrivateClean = 4;
+        public static final int OFFSET_SHARED_DIRTY = 4;
         /** @hide */
-        public static final int offsetSharedClean = 5;
+        public static final int OFFSET_PRIVATE_CLEAN = 5;
         /** @hide */
-        public static final int offsetSwappedOut = 6;
+        public static final int OFFSET_SHARED_CLEAN = 6;
         /** @hide */
-        public static final int offsetSwappedOutPss = 7;
+        public static final int OFFSET_SWAPPED_OUT = 7;
+        /** @hide */
+        public static final int OFFSET_SWAPPED_OUT_PSS = 8;
 
         private int[] otherStats = new int[(NUM_OTHER_STATS+NUM_DVK_STATS)*NUM_CATEGORIES];
 
@@ -337,6 +345,13 @@
         }
 
         /**
+         * @hide Return total RSS memory usage in kB.
+         */
+        public int getTotalRss() {
+            return dalvikRss + nativeRss + otherRss;
+        }
+
+        /**
          * Return total private dirty memory usage in kB.
          */
         public int getTotalPrivateDirty() {
@@ -382,29 +397,32 @@
 
         /** @hide */
         public int getOtherPss(int which) {
-            return otherStats[which*NUM_CATEGORIES + offsetPss];
+            return otherStats[which * NUM_CATEGORIES + OFFSET_PSS];
         }
 
-
         /** @hide */
         public int getOtherSwappablePss(int which) {
-            return otherStats[which*NUM_CATEGORIES + offsetSwappablePss];
+            return otherStats[which * NUM_CATEGORIES + OFFSET_SWAPPABLE_PSS];
         }
 
+        /** @hide */
+        public int getOtherRss(int which) {
+            return otherStats[which * NUM_CATEGORIES + OFFSET_RSS];
+        }
 
         /** @hide */
         public int getOtherPrivateDirty(int which) {
-            return otherStats[which*NUM_CATEGORIES + offsetPrivateDirty];
+            return otherStats[which * NUM_CATEGORIES + OFFSET_PRIVATE_DIRTY];
         }
 
         /** @hide */
         public int getOtherSharedDirty(int which) {
-            return otherStats[which*NUM_CATEGORIES + offsetSharedDirty];
+            return otherStats[which * NUM_CATEGORIES + OFFSET_SHARED_DIRTY];
         }
 
         /** @hide */
         public int getOtherPrivateClean(int which) {
-            return otherStats[which*NUM_CATEGORIES + offsetPrivateClean];
+            return otherStats[which * NUM_CATEGORIES + OFFSET_PRIVATE_CLEAN];
         }
 
         /** @hide */
@@ -414,17 +432,17 @@
 
         /** @hide */
         public int getOtherSharedClean(int which) {
-            return otherStats[which*NUM_CATEGORIES + offsetSharedClean];
+            return otherStats[which * NUM_CATEGORIES + OFFSET_SHARED_CLEAN];
         }
 
         /** @hide */
         public int getOtherSwappedOut(int which) {
-            return otherStats[which*NUM_CATEGORIES + offsetSwappedOut];
+            return otherStats[which * NUM_CATEGORIES + OFFSET_SWAPPED_OUT];
         }
 
         /** @hide */
         public int getOtherSwappedOutPss(int which) {
-            return otherStats[which*NUM_CATEGORIES + offsetSwappedOutPss];
+            return otherStats[which * NUM_CATEGORIES + OFFSET_SWAPPED_OUT_PSS];
         }
 
         /** @hide */
@@ -741,6 +759,7 @@
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeInt(dalvikPss);
             dest.writeInt(dalvikSwappablePss);
+            dest.writeInt(dalvikRss);
             dest.writeInt(dalvikPrivateDirty);
             dest.writeInt(dalvikSharedDirty);
             dest.writeInt(dalvikPrivateClean);
@@ -749,6 +768,7 @@
             dest.writeInt(dalvikSwappedOutPss);
             dest.writeInt(nativePss);
             dest.writeInt(nativeSwappablePss);
+            dest.writeInt(nativeRss);
             dest.writeInt(nativePrivateDirty);
             dest.writeInt(nativeSharedDirty);
             dest.writeInt(nativePrivateClean);
@@ -757,6 +777,7 @@
             dest.writeInt(nativeSwappedOutPss);
             dest.writeInt(otherPss);
             dest.writeInt(otherSwappablePss);
+            dest.writeInt(otherRss);
             dest.writeInt(otherPrivateDirty);
             dest.writeInt(otherSharedDirty);
             dest.writeInt(otherPrivateClean);
@@ -770,6 +791,7 @@
         public void readFromParcel(Parcel source) {
             dalvikPss = source.readInt();
             dalvikSwappablePss = source.readInt();
+            dalvikRss = source.readInt();
             dalvikPrivateDirty = source.readInt();
             dalvikSharedDirty = source.readInt();
             dalvikPrivateClean = source.readInt();
@@ -778,6 +800,7 @@
             dalvikSwappedOutPss = source.readInt();
             nativePss = source.readInt();
             nativeSwappablePss = source.readInt();
+            nativeRss = source.readInt();
             nativePrivateDirty = source.readInt();
             nativeSharedDirty = source.readInt();
             nativePrivateClean = source.readInt();
@@ -786,6 +809,7 @@
             nativeSwappedOutPss = source.readInt();
             otherPss = source.readInt();
             otherSwappablePss = source.readInt();
+            otherRss = source.readInt();
             otherPrivateDirty = source.readInt();
             otherSharedDirty = source.readInt();
             otherPrivateClean = source.readInt();
diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java
index 3d2e1d1..d774281 100644
--- a/core/java/android/preference/SeekBarVolumizer.java
+++ b/core/java/android/preference/SeekBarVolumizer.java
@@ -34,6 +34,7 @@
 import android.provider.Settings;
 import android.provider.Settings.Global;
 import android.provider.Settings.System;
+import android.service.notification.ZenModeConfig;
 import android.util.Log;
 import android.widget.SeekBar;
 import android.widget.SeekBar.OnSeekBarChangeListener;
@@ -87,10 +88,22 @@
     private static final int MSG_INIT_SAMPLE = 3;
     private static final int CHECK_RINGTONE_PLAYBACK_DELAY_MS = 1000;
 
+    private NotificationManager.Policy mNotificationPolicy;
+    private boolean mAllowAlarms;
+    private boolean mAllowMediaSystem;
+    private boolean mAllowRinger;
+
     public SeekBarVolumizer(Context context, int streamType, Uri defaultUri, Callback callback) {
         mContext = context;
         mAudioManager = context.getSystemService(AudioManager.class);
         mNotificationManager = context.getSystemService(NotificationManager.class);
+        mNotificationPolicy = mNotificationManager.getNotificationPolicy();
+        mAllowAlarms = (mNotificationPolicy.priorityCategories & NotificationManager.Policy
+                .PRIORITY_CATEGORY_ALARMS) != 0;
+        mAllowMediaSystem = (mNotificationPolicy.priorityCategories & NotificationManager.Policy
+                .PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER) != 0;
+        mAllowRinger = !ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(
+                mNotificationPolicy);
         mStreamType = streamType;
         mAffectedByRingerMode = mAudioManager.isStreamAffectedByRingerMode(mStreamType);
         mNotificationOrRing = isNotificationOrRing(mStreamType);
@@ -122,6 +135,14 @@
         return stream == AudioManager.STREAM_RING || stream == AudioManager.STREAM_NOTIFICATION;
     }
 
+    private static boolean isAlarmsStream(int stream) {
+        return stream == AudioManager.STREAM_ALARM;
+    }
+
+    private static boolean isMediaOrSystemStream(int stream) {
+        return stream == AudioManager.STREAM_MUSIC || stream == AudioManager.STREAM_SYSTEM;
+    }
+
     public void setSeekBar(SeekBar seekBar) {
         if (mSeekBar != null) {
             mSeekBar.setOnSeekBarChangeListener(null);
@@ -135,7 +156,11 @@
 
     private boolean isZenMuted() {
         return mNotificationOrRing && mZenMode == Global.ZEN_MODE_ALARMS
-                || mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
+                || mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS
+                || (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
+                    && ((!mAllowAlarms && isAlarmsStream(mStreamType))
+                        || (!mAllowMediaSystem && isMediaOrSystemStream(mStreamType))
+                        || (!mAllowRinger && isNotificationOrRing(mStreamType))));
     }
 
     protected void updateSeekBar() {
@@ -396,6 +421,7 @@
                 final IntentFilter filter = new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION);
                 filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
                 filter.addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED);
+                filter.addAction(NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED);
                 filter.addAction(AudioManager.STREAM_DEVICES_CHANGED_ACTION);
                 mContext.registerReceiver(this, filter);
             } else {
@@ -424,6 +450,15 @@
             } else if (NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED.equals(action)) {
                 mZenMode = mNotificationManager.getZenMode();
                 updateSlider();
+            } else if (NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED.equals(action)) {
+                mNotificationPolicy = mNotificationManager.getNotificationPolicy();
+                mAllowAlarms = (mNotificationPolicy.priorityCategories & NotificationManager.Policy
+                        .PRIORITY_CATEGORY_ALARMS) != 0;
+                mAllowMediaSystem = (mNotificationPolicy.priorityCategories
+                        & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER) != 0;
+                mAllowRinger = !ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(
+                        mNotificationPolicy);
+                updateSlider();
             }
         }
 
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index bb88e1a..23ae4b9 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -17,6 +17,7 @@
 package android.service.notification;
 
 import android.app.ActivityManager;
+import android.app.NotificationManager;
 import android.app.NotificationManager.Policy;
 import android.content.ComponentName;
 import android.content.Context;
@@ -1410,4 +1411,38 @@
         }
     }
 
+    /**
+     * Determines whether dnd behavior should mute all notification sounds
+     */
+    public static boolean areAllPriorityOnlyNotificationZenSoundsMuted(NotificationManager.Policy
+            policy) {
+        boolean allowReminders = (policy.priorityCategories
+                & NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS) != 0;
+        boolean allowCalls = (policy.priorityCategories
+                & NotificationManager.Policy.PRIORITY_CATEGORY_CALLS) != 0;
+        boolean allowMessages = (policy.priorityCategories
+                & NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES) != 0;
+        boolean allowEvents = (policy.priorityCategories
+                & NotificationManager.Policy.PRIORITY_CATEGORY_EVENTS) != 0;
+        boolean allowRepeatCallers = (policy.priorityCategories
+                & NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS) != 0;
+        return !allowReminders && !allowCalls && !allowMessages && !allowEvents
+                && !allowRepeatCallers;
+    }
+
+    /**
+     * Determines whether dnd behavior should mute all notification sounds
+     */
+    public static boolean areAllPriorityOnlyNotificationZenSoundsMuted(ZenModeConfig config) {
+        return !config.allowReminders && !config.allowCalls && !config.allowMessages
+                && !config.allowEvents && !config.allowRepeatCallers;
+    }
+
+    /**
+     * Determines whether all dnd mutes all sounds
+     */
+    public static boolean areAllZenBehaviorSoundsMuted(ZenModeConfig config) {
+        return !config.allowAlarms  && !config.allowMediaSystemOther
+                && areAllPriorityOnlyNotificationZenSoundsMuted(config);
+    }
 }
diff --git a/core/java/android/text/MeasuredParagraph.java b/core/java/android/text/MeasuredParagraph.java
index 45fbf6f..aafcf44 100644
--- a/core/java/android/text/MeasuredParagraph.java
+++ b/core/java/android/text/MeasuredParagraph.java
@@ -672,6 +672,13 @@
         return width;
     }
 
+    /**
+     * This only works if the MeasuredParagraph is computed with buildForStaticLayout.
+     */
+    @IntRange(from = 0) int getMemoryUsage() {
+        return nGetMemoryUsage(mNativePtr);
+    }
+
     private static native /* Non Zero */ long nInitBuilder();
 
     /**
@@ -718,4 +725,7 @@
 
     @CriticalNative
     private static native /* Non Zero */ long nGetReleaseFunc();
+
+    @CriticalNative
+    private static native int nGetMemoryUsage(/* Non Zero */ long nativePtr);
 }
diff --git a/core/java/android/text/MeasuredText.java b/core/java/android/text/MeasuredText.java
index ff23395..bb7a9e0 100644
--- a/core/java/android/text/MeasuredText.java
+++ b/core/java/android/text/MeasuredText.java
@@ -333,6 +333,20 @@
         return getMeasuredParagraph(paraIndex).getWidth(start - paraStart, end - paraStart);
     }
 
+    /**
+     * Returns the size of native MeasuredText memory usage
+     *
+     * Note that this may not be aculate. Must be used only for testing purposes.
+     * @hide
+     */
+    public int getMemoryUsage() {
+        int r = 0;
+        for (int i = 0; i < getParagraphCount(); ++i) {
+            r += getMeasuredParagraph(i).getMemoryUsage();
+        }
+        return r;
+    }
+
     ///////////////////////////////////////////////////////////////////////////////////////////////
     // Spanned overrides
     //
diff --git a/core/java/android/util/AtomicFile.java b/core/java/android/util/AtomicFile.java
index 6342c8b..cf7ed9b 100644
--- a/core/java/android/util/AtomicFile.java
+++ b/core/java/android/util/AtomicFile.java
@@ -17,6 +17,7 @@
 package android.util;
 
 import android.os.FileUtils;
+import android.os.SystemClock;
 
 import libcore.io.IoUtils;
 
@@ -47,14 +48,25 @@
 public class AtomicFile {
     private final File mBaseName;
     private final File mBackupName;
+    private final String mCommitTag;
+    private long mStartTime;
 
     /**
      * Create a new AtomicFile for a file located at the given File path.
      * The secondary backup file will be the same file path with ".bak" appended.
      */
     public AtomicFile(File baseName) {
+        this(baseName, null);
+    }
+
+    /**
+     * @hide Internal constructor that also allows you to have the class
+     * automatically log commit events.
+     */
+    public AtomicFile(File baseName, String commitTag) {
         mBaseName = baseName;
         mBackupName = new File(baseName.getPath() + ".bak");
+        mCommitTag = commitTag;
     }
 
     /**
@@ -88,6 +100,18 @@
      * access to AtomicFile.
      */
     public FileOutputStream startWrite() throws IOException {
+        return startWrite(mCommitTag != null ? SystemClock.uptimeMillis() : 0);
+    }
+
+    /**
+     * @hide Internal version of {@link #startWrite()} that allows you to specify an earlier
+     * start time of the operation to adjust how the commit is logged.
+     * @param startTime The effective start time of the operation, in the time
+     * base of {@link SystemClock#uptimeMillis()}.
+     */
+    public FileOutputStream startWrite(long startTime) throws IOException {
+        mStartTime = startTime;
+
         // Rename the current file so it may be used as a backup during the next read
         if (mBaseName.exists()) {
             if (!mBackupName.exists()) {
@@ -135,6 +159,10 @@
             } catch (IOException e) {
                 Log.w("AtomicFile", "finishWrite: Got exception:", e);
             }
+            if (mCommitTag != null) {
+                com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
+                        mCommitTag, SystemClock.uptimeMillis() - mStartTime);
+            }
         }
     }
 
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index 2ab2d20..1dfff5e 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -103,11 +103,14 @@
         List<ResolverActivity.ResolvedComponentInfo> resolvedComponents = null;
         for (int i = 0, N = intents.size(); i < N; i++) {
             final Intent intent = intents.get(i);
-            final List<ResolveInfo> infos = mpm.queryIntentActivities(intent,
-                    PackageManager.MATCH_DEFAULT_ONLY
-                            | (shouldGetResolvedFilter ? PackageManager.GET_RESOLVED_FILTER : 0)
-                            | (shouldGetActivityMetadata ? PackageManager.GET_META_DATA : 0)
-                            | PackageManager.MATCH_INSTANT);
+            int flags = PackageManager.MATCH_DEFAULT_ONLY
+                    | (shouldGetResolvedFilter ? PackageManager.GET_RESOLVED_FILTER : 0)
+                    | (shouldGetActivityMetadata ? PackageManager.GET_META_DATA : 0);
+            if (intent.isBrowsableWebIntent()
+                        || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) {
+                flags |= PackageManager.MATCH_INSTANT;
+            }
+            final List<ResolveInfo> infos = mpm.queryIntentActivities(intent, flags);
             // Remove any activities that are not exported.
             int totalSize = infos.size();
             for (int j = totalSize - 1; j >= 0 ; j--) {
diff --git a/core/java/com/android/internal/app/procstats/ProcessState.java b/core/java/com/android/internal/app/procstats/ProcessState.java
index e0effb1..65bd48f 100644
--- a/core/java/com/android/internal/app/procstats/ProcessState.java
+++ b/core/java/com/android/internal/app/procstats/ProcessState.java
@@ -17,25 +17,18 @@
 package com.android.internal.app.procstats;
 
 import android.os.Parcel;
-import android.os.Parcelable;
 import android.os.SystemClock;
-import android.os.SystemProperties;
 import android.os.UserHandle;
-import android.service.pm.PackageProto;
 import android.service.procstats.ProcessStatsProto;
-import android.text.format.DateFormat;
 import android.util.ArrayMap;
-import android.util.ArraySet;
 import android.util.DebugUtils;
 import android.util.Log;
 import android.util.LongSparseArray;
 import android.util.Slog;
-import android.util.SparseArray;
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
 import android.util.proto.ProtoUtils;
 
-import com.android.internal.app.procstats.ProcessStats;
 import com.android.internal.app.procstats.ProcessStats.PackageState;
 import com.android.internal.app.procstats.ProcessStats.ProcessStateHolder;
 import com.android.internal.app.procstats.ProcessStats.TotalMemoryUseCollection;
@@ -43,6 +36,9 @@
 import static com.android.internal.app.procstats.ProcessStats.PSS_MINIMUM;
 import static com.android.internal.app.procstats.ProcessStats.PSS_AVERAGE;
 import static com.android.internal.app.procstats.ProcessStats.PSS_MAXIMUM;
+import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_MINIMUM;
+import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_AVERAGE;
+import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_MAXIMUM;
 import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MINIMUM;
 import static com.android.internal.app.procstats.ProcessStats.PSS_USS_AVERAGE;
 import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MAXIMUM;
@@ -64,20 +60,10 @@
 import static com.android.internal.app.procstats.ProcessStats.STATE_CACHED_EMPTY;
 import static com.android.internal.app.procstats.ProcessStats.STATE_COUNT;
 
-import dalvik.system.VMRuntime;
-import libcore.util.EmptyArray;
-
-import java.io.IOException;
-import java.io.InputStream;
 import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 
 public final class ProcessState {
     private static final String TAG = "ProcessStats";
@@ -469,13 +455,21 @@
         }
     }
 
-    public void addPss(long pss, long uss, boolean always, int type, long duration,
+    public void addPss(long pss, long uss, long rss, boolean always, int type, long duration,
             ArrayMap<String, ProcessStateHolder> pkgList) {
         ensureNotDead();
         switch (type) {
-            case ProcessStats.ADD_PSS_INTERNAL:
-                mStats.mInternalPssCount++;
-                mStats.mInternalPssTime += duration;
+            case ProcessStats.ADD_PSS_INTERNAL_SINGLE:
+                mStats.mInternalSinglePssCount++;
+                mStats.mInternalSinglePssTime += duration;
+                break;
+            case ProcessStats.ADD_PSS_INTERNAL_ALL_MEM:
+                mStats.mInternalAllMemPssCount++;
+                mStats.mInternalAllMemPssTime += duration;
+                break;
+            case ProcessStats.ADD_PSS_INTERNAL_ALL_POLL:
+                mStats.mInternalAllPollPssCount++;
+                mStats.mInternalAllPollPssTime += duration;
                 break;
             case ProcessStats.ADD_PSS_EXTERNAL:
                 mStats.mExternalPssCount++;
@@ -496,7 +490,8 @@
         mLastPssTime = SystemClock.uptimeMillis();
         if (mCurState != STATE_NOTHING) {
             // First update the common process.
-            mCommonProcess.mPssTable.mergeStats(mCurState, 1, pss, pss, pss, uss, uss, uss);
+            mCommonProcess.mPssTable.mergeStats(mCurState, 1, pss, pss, pss, uss, uss, uss,
+                    rss, rss, rss);
 
             // If the common process is not multi-package, there is nothing else to do.
             if (!mCommonProcess.mMultiPackage) {
@@ -506,7 +501,7 @@
             if (pkgList != null) {
                 for (int ip=pkgList.size()-1; ip>=0; ip--) {
                     pullFixedProc(pkgList, ip).mPssTable.mergeStats(mCurState, 1,
-                            pss, pss, pss, uss, uss, uss);
+                            pss, pss, pss, uss, uss, uss, rss, rss, rss);
                 }
             }
         }
@@ -658,6 +653,18 @@
         return mPssTable.getValueForId((byte)state, PSS_USS_MAXIMUM);
     }
 
+    public long getPssRssMinimum(int state) {
+        return mPssTable.getValueForId((byte)state, PSS_RSS_MINIMUM);
+    }
+
+    public long getPssRssAverage(int state) {
+        return mPssTable.getValueForId((byte)state, PSS_RSS_AVERAGE);
+    }
+
+    public long getPssRssMaximum(int state) {
+        return mPssTable.getValueForId((byte)state, PSS_RSS_MAXIMUM);
+    }
+
     /**
      * Sums up the PSS data and adds it to 'data'.
      * 
@@ -793,6 +800,8 @@
                 new int[] {STATE_SERVICE_RESTARTING}, now, totalTime, true);
         dumpProcessSummaryDetails(pw, prefix, "      Receiver: ", screenStates, memStates,
                 new int[] {STATE_RECEIVER}, now, totalTime, true);
+        dumpProcessSummaryDetails(pw, prefix, "         Heavy: ", screenStates, memStates,
+                new int[] {STATE_HOME}, now, totalTime, true);
         dumpProcessSummaryDetails(pw, prefix, "        (Home): ", screenStates, memStates,
                 new int[] {STATE_HOME}, now, totalTime, true);
         dumpProcessSummaryDetails(pw, prefix, "    (Last Act): ", screenStates, memStates,
@@ -897,6 +906,12 @@
                         DebugUtils.printSizeValue(pw, getPssUssAverage(bucket) * 1024);
                         pw.print(" ");
                         DebugUtils.printSizeValue(pw, getPssUssMaximum(bucket) * 1024);
+                        pw.print(" / ");
+                        DebugUtils.printSizeValue(pw, getPssRssMinimum(bucket) * 1024);
+                        pw.print(" ");
+                        DebugUtils.printSizeValue(pw, getPssRssAverage(bucket) * 1024);
+                        pw.print(" ");
+                        DebugUtils.printSizeValue(pw, getPssRssMaximum(bucket) * 1024);
                         pw.println();
                     }
                 }
@@ -969,7 +984,8 @@
     public void computeProcessData(ProcessStats.ProcessDataCollection data, long now) {
         data.totalTime = 0;
         data.numPss = data.minPss = data.avgPss = data.maxPss =
-                data.minUss = data.avgUss = data.maxUss = 0;
+                data.minUss = data.avgUss = data.maxUss =
+                data.minRss = data.avgRss = data.maxRss = 0;
         for (int is=0; is<data.screenStates.length; is++) {
             for (int im=0; im<data.memStates.length; im++) {
                 for (int ip=0; ip<data.procStates.length; ip++) {
@@ -984,6 +1000,9 @@
                         long minUss = getPssUssMinimum(bucket);
                         long avgUss = getPssUssAverage(bucket);
                         long maxUss = getPssUssMaximum(bucket);
+                        long minRss = getPssRssMinimum(bucket);
+                        long avgRss = getPssRssAverage(bucket);
+                        long maxRss = getPssRssMaximum(bucket);
                         if (data.numPss == 0) {
                             data.minPss = minPss;
                             data.avgPss = avgPss;
@@ -991,6 +1010,9 @@
                             data.minUss = minUss;
                             data.avgUss = avgUss;
                             data.maxUss = maxUss;
+                            data.minRss = minRss;
+                            data.avgRss = avgRss;
+                            data.maxRss = maxRss;
                         } else {
                             if (minPss < data.minPss) {
                                 data.minPss = minPss;
@@ -1008,6 +1030,14 @@
                             if (maxUss > data.maxUss) {
                                 data.maxUss = maxUss;
                             }
+                            if (minRss < data.minRss) {
+                                data.minRss = minRss;
+                            }
+                            data.avgRss = (long)( ((data.avgRss*(double)data.numPss)
+                                    + (avgRss*(double)samples)) / (data.numPss+samples) );
+                            if (maxRss > data.maxRss) {
+                                data.maxRss = maxRss;
+                            }
                         }
                         data.numPss += samples;
                     }
@@ -1176,6 +1206,12 @@
             pw.print(mPssTable.getValue(key, PSS_USS_AVERAGE));
             pw.print(':');
             pw.print(mPssTable.getValue(key, PSS_USS_MAXIMUM));
+            pw.print(':');
+            pw.print(mPssTable.getValue(key, PSS_RSS_MINIMUM));
+            pw.print(':');
+            pw.print(mPssTable.getValue(key, PSS_RSS_AVERAGE));
+            pw.print(':');
+            pw.print(mPssTable.getValue(key, PSS_RSS_MAXIMUM));
         }
     }
 
@@ -1249,6 +1285,10 @@
                     mPssTable.getValue(key, PSS_USS_MINIMUM),
                     mPssTable.getValue(key, PSS_USS_AVERAGE),
                     mPssTable.getValue(key, PSS_USS_MAXIMUM));
+            ProtoUtils.toAggStatsProto(proto, ProcessStatsProto.State.RSS,
+                    mPssTable.getValue(key, PSS_RSS_MINIMUM),
+                    mPssTable.getValue(key, PSS_RSS_AVERAGE),
+                    mPssTable.getValue(key, PSS_RSS_MAXIMUM));
 
             proto.end(stateToken);
         }
diff --git a/core/java/com/android/internal/app/procstats/ProcessStats.java b/core/java/com/android/internal/app/procstats/ProcessStats.java
index 591a587..d35bddd 100644
--- a/core/java/com/android/internal/app/procstats/ProcessStats.java
+++ b/core/java/com/android/internal/app/procstats/ProcessStats.java
@@ -27,7 +27,6 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.DebugUtils;
-import android.util.Log;
 import android.util.LongSparseArray;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -35,16 +34,8 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.app.ProcessMap;
-import com.android.internal.app.procstats.DurationsTable;
-import com.android.internal.app.procstats.ProcessState;
-import com.android.internal.app.procstats.PssTable;
-import com.android.internal.app.procstats.ServiceState;
-import com.android.internal.app.procstats.SparseMappingTable;
-import com.android.internal.app.procstats.SysMemUsageTable;
-import com.android.internal.app.procstats.DumpUtils.*;
 
 import dalvik.system.VMRuntime;
-import libcore.util.EmptyArray;
 
 import java.io.BufferedReader;
 import java.io.FileReader;
@@ -54,7 +45,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.Objects;
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
@@ -99,7 +89,10 @@
     public static final int PSS_USS_MINIMUM = 4;
     public static final int PSS_USS_AVERAGE = 5;
     public static final int PSS_USS_MAXIMUM = 6;
-    public static final int PSS_COUNT = PSS_USS_MAXIMUM+1;
+    public static final int PSS_RSS_MINIMUM = 7;
+    public static final int PSS_RSS_AVERAGE = 8;
+    public static final int PSS_RSS_MAXIMUM = 9;
+    public static final int PSS_COUNT = PSS_RSS_MAXIMUM+1;
 
     public static final int SYS_MEM_USAGE_SAMPLE_COUNT = 0;
     public static final int SYS_MEM_USAGE_CACHED_MINIMUM = 1;
@@ -134,9 +127,11 @@
     public static final int FLAG_SHUTDOWN = 1<<1;
     public static final int FLAG_SYSPROPS = 1<<2;
 
-    public static final int ADD_PSS_INTERNAL = 0;
-    public static final int ADD_PSS_EXTERNAL = 1;
-    public static final int ADD_PSS_EXTERNAL_SLOW = 2;
+    public static final int ADD_PSS_INTERNAL_SINGLE = 0;
+    public static final int ADD_PSS_INTERNAL_ALL_MEM = 1;
+    public static final int ADD_PSS_INTERNAL_ALL_POLL = 2;
+    public static final int ADD_PSS_EXTERNAL = 3;
+    public static final int ADD_PSS_EXTERNAL_SLOW = 4;
 
     public static final int[] ALL_MEM_ADJ = new int[] { ADJ_MEM_FACTOR_NORMAL,
             ADJ_MEM_FACTOR_MODERATE, ADJ_MEM_FACTOR_LOW, ADJ_MEM_FACTOR_CRITICAL };
@@ -162,7 +157,7 @@
     };
 
     // Current version of the parcel format.
-    private static final int PARCEL_VERSION = 24;
+    private static final int PARCEL_VERSION = 27;
     // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
     private static final int MAGIC = 0x50535454;
 
@@ -187,9 +182,17 @@
 
     boolean mHasSwappedOutPss;
 
-    // Count and total time expended doing "quick" pss computations for internal use.
-    public long mInternalPssCount;
-    public long mInternalPssTime;
+    // Count and total time expended doing "quick" single pss computations for internal use.
+    public long mInternalSinglePssCount;
+    public long mInternalSinglePssTime;
+
+    // Count and total time expended doing "quick" all mem pss computations for internal use.
+    public long mInternalAllMemPssCount;
+    public long mInternalAllMemPssTime;
+
+    // Count and total time expended doing "quick" all poll pss computations for internal use.
+    public long mInternalAllPollPssCount;
+    public long mInternalAllPollPssTime;
 
     // Count and total time expended doing "quick" pss computations due to external requests.
     public long mExternalPssCount;
@@ -318,8 +321,12 @@
         mTimePeriodEndRealtime += other.mTimePeriodEndRealtime - other.mTimePeriodStartRealtime;
         mTimePeriodEndUptime += other.mTimePeriodEndUptime - other.mTimePeriodStartUptime;
 
-        mInternalPssCount += other.mInternalPssCount;
-        mInternalPssTime += other.mInternalPssTime;
+        mInternalSinglePssCount += other.mInternalSinglePssCount;
+        mInternalSinglePssTime += other.mInternalSinglePssTime;
+        mInternalAllMemPssCount += other.mInternalAllMemPssCount;
+        mInternalAllMemPssTime += other.mInternalAllMemPssTime;
+        mInternalAllPollPssCount += other.mInternalAllPollPssCount;
+        mInternalAllPollPssTime += other.mInternalAllPollPssTime;
         mExternalPssCount += other.mExternalPssCount;
         mExternalPssTime += other.mExternalPssTime;
         mExternalSlowPssCount += other.mExternalSlowPssCount;
@@ -523,8 +530,12 @@
         buildTimePeriodStartClockStr();
         mTimePeriodStartRealtime = mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
         mTimePeriodStartUptime = mTimePeriodEndUptime = SystemClock.uptimeMillis();
-        mInternalPssCount = 0;
-        mInternalPssTime = 0;
+        mInternalSinglePssCount = 0;
+        mInternalSinglePssTime = 0;
+        mInternalAllMemPssCount = 0;
+        mInternalAllMemPssTime = 0;
+        mInternalAllPollPssCount = 0;
+        mInternalAllPollPssTime = 0;
         mExternalPssCount = 0;
         mExternalPssTime = 0;
         mExternalSlowPssCount = 0;
@@ -789,8 +800,12 @@
         out.writeLong(mTimePeriodEndRealtime);
         out.writeLong(mTimePeriodStartUptime);
         out.writeLong(mTimePeriodEndUptime);
-        out.writeLong(mInternalPssCount);
-        out.writeLong(mInternalPssTime);
+        out.writeLong(mInternalSinglePssCount);
+        out.writeLong(mInternalSinglePssTime);
+        out.writeLong(mInternalAllMemPssCount);
+        out.writeLong(mInternalAllMemPssTime);
+        out.writeLong(mInternalAllPollPssCount);
+        out.writeLong(mInternalAllPollPssTime);
         out.writeLong(mExternalPssCount);
         out.writeLong(mExternalPssTime);
         out.writeLong(mExternalSlowPssCount);
@@ -963,8 +978,12 @@
         mTimePeriodEndRealtime = in.readLong();
         mTimePeriodStartUptime = in.readLong();
         mTimePeriodEndUptime = in.readLong();
-        mInternalPssCount = in.readLong();
-        mInternalPssTime = in.readLong();
+        mInternalSinglePssCount = in.readLong();
+        mInternalSinglePssTime = in.readLong();
+        mInternalAllMemPssCount = in.readLong();
+        mInternalAllMemPssTime = in.readLong();
+        mInternalAllPollPssCount = in.readLong();
+        mInternalAllPollPssTime = in.readLong();
         mExternalPssCount = in.readLong();
         mExternalPssTime = in.readLong();
         mExternalSlowPssCount = in.readLong();
@@ -1526,10 +1545,20 @@
                 totalMem.processStateSamples[STATE_SERVICE_RESTARTING]);
         pw.println();
         pw.println("PSS collection stats:");
-        pw.print("  Internal: ");
-        pw.print(mInternalPssCount);
+        pw.print("  Internal Single: ");
+        pw.print(mInternalSinglePssCount);
         pw.print("x over ");
-        TimeUtils.formatDuration(mInternalPssTime, pw);
+        TimeUtils.formatDuration(mInternalSinglePssTime, pw);
+        pw.println();
+        pw.print("  Internal All Procs (Memory Change): ");
+        pw.print(mInternalAllMemPssCount);
+        pw.print("x over ");
+        TimeUtils.formatDuration(mInternalAllMemPssTime, pw);
+        pw.println();
+        pw.print("  Internal All Procs (Polling): ");
+        pw.print(mInternalAllPollPssCount);
+        pw.print("x over ");
+        TimeUtils.formatDuration(mInternalAllPollPssTime, pw);
         pw.println();
         pw.print("  External: ");
         pw.print(mExternalPssCount);
@@ -1854,6 +1883,9 @@
         public long minUss;
         public long avgUss;
         public long maxUss;
+        public long minRss;
+        public long avgRss;
+        public long maxRss;
 
         public ProcessDataCollection(int[] _screenStates, int[] _memStates, int[] _procStates) {
             screenStates = _screenStates;
@@ -1879,6 +1911,12 @@
                 DebugUtils.printSizeValue(pw, avgUss * 1024);
                 pw.print("-");
                 DebugUtils.printSizeValue(pw, maxUss * 1024);
+                pw.print("/");
+                DebugUtils.printSizeValue(pw, minRss * 1024);
+                pw.print("-");
+                DebugUtils.printSizeValue(pw, avgRss * 1024);
+                pw.print("-");
+                DebugUtils.printSizeValue(pw, maxRss * 1024);
                 if (full) {
                     pw.print(" over ");
                     pw.print(numPss);
diff --git a/core/java/com/android/internal/app/procstats/PssTable.java b/core/java/com/android/internal/app/procstats/PssTable.java
index de5f673..1e7c566 100644
--- a/core/java/com/android/internal/app/procstats/PssTable.java
+++ b/core/java/com/android/internal/app/procstats/PssTable.java
@@ -16,6 +16,9 @@
 
 package com.android.internal.app.procstats;
 
+import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_AVERAGE;
+import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_MAXIMUM;
+import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_MINIMUM;
 import static com.android.internal.app.procstats.ProcessStats.PSS_SAMPLE_COUNT;
 import static com.android.internal.app.procstats.ProcessStats.PSS_MINIMUM;
 import static com.android.internal.app.procstats.ProcessStats.PSS_AVERAGE;
@@ -51,7 +54,10 @@
                     that.getValue(key, PSS_MAXIMUM),
                     that.getValue(key, PSS_USS_MINIMUM),
                     that.getValue(key, PSS_USS_AVERAGE),
-                    that.getValue(key, PSS_USS_MAXIMUM));
+                    that.getValue(key, PSS_USS_MAXIMUM),
+                    that.getValue(key, PSS_RSS_MINIMUM),
+                    that.getValue(key, PSS_RSS_AVERAGE),
+                    that.getValue(key, PSS_RSS_MAXIMUM));
         }
     }
 
@@ -60,7 +66,7 @@
      * one and the new one, the average will now incorporate the new average, etc.
      */
     public void mergeStats(int state, int inCount, long minPss, long avgPss, long maxPss,
-            long minUss, long avgUss, long maxUss) {
+            long minUss, long avgUss, long maxUss, long minRss, long avgRss, long maxRss) {
         final int key = getOrAddKey((byte)state, PSS_COUNT);
         final long count = getValue(key, PSS_SAMPLE_COUNT);
         if (count == 0) {
@@ -71,6 +77,9 @@
             setValue(key, PSS_USS_MINIMUM, minUss);
             setValue(key, PSS_USS_AVERAGE, avgUss);
             setValue(key, PSS_USS_MAXIMUM, maxUss);
+            setValue(key, PSS_RSS_MINIMUM, minRss);
+            setValue(key, PSS_RSS_AVERAGE, avgRss);
+            setValue(key, PSS_RSS_MAXIMUM, maxRss);
         } else {
             setValue(key, PSS_SAMPLE_COUNT, count + inCount);
 
@@ -103,6 +112,20 @@
             if (val < maxUss) {
                 setValue(key, PSS_USS_MAXIMUM, maxUss);
             }
+
+            val = getValue(key, PSS_RSS_MINIMUM);
+            if (val > minUss) {
+                setValue(key, PSS_RSS_MINIMUM, minUss);
+            }
+
+            val = getValue(key, PSS_RSS_AVERAGE);
+            setValue(key, PSS_RSS_AVERAGE,
+                    (long)(((val*(double)count)+(avgUss*(double)inCount)) / (count+inCount)));
+
+            val = getValue(key, PSS_RSS_MAXIMUM);
+            if (val < maxUss) {
+                setValue(key, PSS_RSS_MAXIMUM, maxUss);
+            }
         }
     }
 }
diff --git a/core/java/com/android/internal/logging/EventLogTags.logtags b/core/java/com/android/internal/logging/EventLogTags.logtags
index a440ee4..693bd16 100644
--- a/core/java/com/android/internal/logging/EventLogTags.logtags
+++ b/core/java/com/android/internal/logging/EventLogTags.logtags
@@ -13,3 +13,6 @@
 # LatencyTracker.java
 # ---------------------------
 36070 sysui_latency (action|1|6),(latency|1|3)
+
+# Generic event for logging when we write system files.
+525000 commit_sys_config_file (name|3),(time|2|3)
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index fd5fe10..e91b67a 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -10169,6 +10169,7 @@
         updateDailyDeadlineLocked();
 
         if (hasData) {
+            final long startTime = SystemClock.uptimeMillis();
             mDailyItems.add(item);
             while (mDailyItems.size() > MAX_DAILY_ITEMS) {
                 mDailyItems.remove(0);
@@ -10178,10 +10179,12 @@
                 XmlSerializer out = new FastXmlSerializer();
                 out.setOutput(memStream, StandardCharsets.UTF_8.name());
                 writeDailyItemsLocked(out);
+                final long initialTime = SystemClock.uptimeMillis() - startTime;
                 BackgroundThread.getHandler().post(new Runnable() {
                     @Override
                     public void run() {
                         synchronized (mCheckinFile) {
+                            final long startTime2 = SystemClock.uptimeMillis();
                             FileOutputStream stream = null;
                             try {
                                 stream = mDailyFile.startWrite();
@@ -10190,6 +10193,9 @@
                                 FileUtils.sync(stream);
                                 stream.close();
                                 mDailyFile.finishWrite(stream);
+                                com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
+                                        "batterystats-daily",
+                                        initialTime + SystemClock.uptimeMillis() - startTime2);
                             } catch (IOException e) {
                                 Slog.w("BatteryStats",
                                         "Error writing battery daily items", e);
@@ -12106,11 +12112,14 @@
                 // stats to be reported in the next checkin.  Only do this if we have
                 // a sufficient amount of data to make it interesting.
                 if (getLowDischargeAmountSinceCharge() >= 20) {
+                    final long startTime = SystemClock.uptimeMillis();
                     final Parcel parcel = Parcel.obtain();
                     writeSummaryToParcel(parcel, true);
+                    final long initialTime = SystemClock.uptimeMillis() - startTime;
                     BackgroundThread.getHandler().post(new Runnable() {
                         @Override public void run() {
                             synchronized (mCheckinFile) {
+                                final long startTime2 = SystemClock.uptimeMillis();
                                 FileOutputStream stream = null;
                                 try {
                                     stream = mCheckinFile.startWrite();
@@ -12119,6 +12128,9 @@
                                     FileUtils.sync(stream);
                                     stream.close();
                                     mCheckinFile.finishWrite(stream);
+                                    com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
+                                            "batterystats-checkin",
+                                            initialTime + SystemClock.uptimeMillis() - startTime2);
                                 } catch (IOException e) {
                                     Slog.w("BatteryStats",
                                             "Error writing checkin battery statistics", e);
@@ -13121,12 +13133,15 @@
 
         mWriteLock.lock();
         try {
+            final long startTime = SystemClock.uptimeMillis();
             FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
             stream.write(next.marshall());
             stream.flush();
             FileUtils.sync(stream);
             stream.close();
             mFile.commit();
+            com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
+                    "batterystats", SystemClock.uptimeMillis() - startTime);
         } catch (IOException e) {
             Slog.w("BatteryStats", "Error writing battery statistics", e);
             mFile.rollback();
diff --git a/core/java/com/android/server/BootReceiver.java b/core/java/com/android/server/BootReceiver.java
index 8848e393..e3436e8 100644
--- a/core/java/com/android/server/BootReceiver.java
+++ b/core/java/com/android/server/BootReceiver.java
@@ -85,7 +85,7 @@
 
     private static final String LOG_FILES_FILE = "log-files.xml";
     private static final AtomicFile sFile = new AtomicFile(new File(
-            Environment.getDataSystemDirectory(), LOG_FILES_FILE));
+            Environment.getDataSystemDirectory(), LOG_FILES_FILE), "log-files");
     private static final String LAST_HEADER_FILE = "last-header.txt";
     private static final File lastHeaderFile = new File(
             Environment.getDataSystemDirectory(), LAST_HEADER_FILE);
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 49cbb54..115d0d5 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -24,6 +24,7 @@
 #include "core_jni_helpers.h"
 #include <nativehelper/ScopedStringChars.h>
 #include <nativehelper/ScopedUtfChars.h>
+#include <nativehelper/ScopedPrimitiveArray.h>
 
 #include "SkBlurDrawLooper.h"
 #include "SkColorFilter.h"
@@ -515,11 +516,10 @@
             jint start, jint end, jint contextStart, jint contextEnd, jboolean isRtl, jint offset) {
         const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
         const Typeface* typeface = paint->getAndroidTypeface();
-        jchar* textArray = (jchar*) env->GetPrimitiveArrayCritical(text, nullptr);
-        jfloat result = doRunAdvance(paint, typeface, textArray + contextStart,
+        ScopedCharArrayRO textArray(env, text);
+        jfloat result = doRunAdvance(paint, typeface, textArray.get() + contextStart,
                 start - contextStart, end - start, contextEnd - contextStart, isRtl,
                 offset - contextStart);
-        env->ReleasePrimitiveArrayCritical(text, textArray, JNI_ABORT);
         return result;
     }
 
@@ -537,11 +537,10 @@
             jboolean isRtl, jfloat advance) {
         const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
         const Typeface* typeface = paint->getAndroidTypeface();
-        jchar* textArray = (jchar*) env->GetPrimitiveArrayCritical(text, nullptr);
-        jint result = doOffsetForAdvance(paint, typeface, textArray + contextStart,
+        ScopedCharArrayRO textArray(env, text);
+        jint result = doOffsetForAdvance(paint, typeface, textArray.get() + contextStart,
                 start - contextStart, end - start, contextEnd - contextStart, isRtl, advance);
         result += contextStart;
-        env->ReleasePrimitiveArrayCritical(text, textArray, JNI_ABORT);
         return result;
     }
 
diff --git a/core/jni/android_database_CursorWindow.cpp b/core/jni/android_database_CursorWindow.cpp
index 0d09b56..86cda44 100644
--- a/core/jni/android_database_CursorWindow.cpp
+++ b/core/jni/android_database_CursorWindow.cpp
@@ -519,8 +519,21 @@
             (void*)nativeDispose },
     { "nativeWriteToParcel", "(JLandroid/os/Parcel;)V",
             (void*)nativeWriteToParcel },
+
     { "nativeGetName", "(J)Ljava/lang/String;",
             (void*)nativeGetName },
+    { "nativeGetBlob", "(JII)[B",
+            (void*)nativeGetBlob },
+    { "nativeGetString", "(JII)Ljava/lang/String;",
+            (void*)nativeGetString },
+    { "nativeCopyStringToBuffer", "(JIILandroid/database/CharArrayBuffer;)V",
+            (void*)nativeCopyStringToBuffer },
+    { "nativePutBlob", "(J[BII)Z",
+            (void*)nativePutBlob },
+    { "nativePutString", "(JLjava/lang/String;II)Z",
+            (void*)nativePutString },
+
+    // ------- @FastNative below here ----------------------
     { "nativeClear", "(J)V",
             (void*)nativeClear },
     { "nativeGetNumRows", "(J)I",
@@ -533,20 +546,11 @@
             (void*)nativeFreeLastRow },
     { "nativeGetType", "(JII)I",
             (void*)nativeGetType },
-    { "nativeGetBlob", "(JII)[B",
-            (void*)nativeGetBlob },
-    { "nativeGetString", "(JII)Ljava/lang/String;",
-            (void*)nativeGetString },
     { "nativeGetLong", "(JII)J",
             (void*)nativeGetLong },
     { "nativeGetDouble", "(JII)D",
             (void*)nativeGetDouble },
-    { "nativeCopyStringToBuffer", "(JIILandroid/database/CharArrayBuffer;)V",
-            (void*)nativeCopyStringToBuffer },
-    { "nativePutBlob", "(J[BII)Z",
-            (void*)nativePutBlob },
-    { "nativePutString", "(JLjava/lang/String;II)Z",
-            (void*)nativePutString },
+
     { "nativePutLong", "(JJII)Z",
             (void*)nativePutLong },
     { "nativePutDouble", "(JDII)Z",
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index b9ff0a7..bf183cc 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -107,6 +107,7 @@
 struct stat_fields {
     jfieldID pss_field;
     jfieldID pssSwappable_field;
+    jfieldID rss_field;
     jfieldID privateDirty_field;
     jfieldID sharedDirty_field;
     jfieldID privateClean_field;
@@ -118,6 +119,7 @@
 struct stat_field_names {
     const char* pss_name;
     const char* pssSwappable_name;
+    const char* rss_name;
     const char* privateDirty_name;
     const char* sharedDirty_name;
     const char* privateClean_name;
@@ -129,11 +131,11 @@
 static stat_fields stat_fields[_NUM_CORE_HEAP];
 
 static stat_field_names stat_field_names[_NUM_CORE_HEAP] = {
-    { "otherPss", "otherSwappablePss", "otherPrivateDirty", "otherSharedDirty",
+    { "otherPss", "otherSwappablePss", "otherRss", "otherPrivateDirty", "otherSharedDirty",
         "otherPrivateClean", "otherSharedClean", "otherSwappedOut", "otherSwappedOutPss" },
-    { "dalvikPss", "dalvikSwappablePss", "dalvikPrivateDirty", "dalvikSharedDirty",
+    { "dalvikPss", "dalvikSwappablePss", "dalvikRss", "dalvikPrivateDirty", "dalvikSharedDirty",
         "dalvikPrivateClean", "dalvikSharedClean", "dalvikSwappedOut", "dalvikSwappedOutPss" },
-    { "nativePss", "nativeSwappablePss", "nativePrivateDirty", "nativeSharedDirty",
+    { "nativePss", "nativeSwappablePss", "nativeRss", "nativePrivateDirty", "nativeSharedDirty",
         "nativePrivateClean", "nativeSharedClean", "nativeSwappedOut", "nativeSwappedOutPss" }
 };
 
@@ -143,6 +145,7 @@
 struct stats_t {
     int pss;
     int swappablePss;
+    int rss;
     int privateDirty;
     int sharedDirty;
     int privateClean;
@@ -246,7 +249,7 @@
     int len, nameLen;
     bool skip, done = false;
 
-    unsigned pss = 0, swappable_pss = 0;
+    unsigned pss = 0, swappable_pss = 0, rss = 0;
     float sharing_proportion = 0.0;
     unsigned shared_clean = 0, shared_dirty = 0;
     unsigned private_clean = 0, private_dirty = 0;
@@ -412,7 +415,7 @@
             if (line[0] == 'S' && sscanf(line, "Size: %d kB", &temp) == 1) {
                 /* size = temp; */
             } else if (line[0] == 'R' && sscanf(line, "Rss: %d kB", &temp) == 1) {
-                /* resident = temp; */
+                rss = temp;
             } else if (line[0] == 'P' && sscanf(line, "Pss: %d kB", &temp) == 1) {
                 pss = temp;
             } else if (line[0] == 'S' && sscanf(line, "Shared_Clean: %d kB", &temp) == 1) {
@@ -450,6 +453,7 @@
 
             stats[whichHeap].pss += pss;
             stats[whichHeap].swappablePss += swappable_pss;
+            stats[whichHeap].rss += rss;
             stats[whichHeap].privateDirty += private_dirty;
             stats[whichHeap].sharedDirty += shared_dirty;
             stats[whichHeap].privateClean += private_clean;
@@ -460,6 +464,7 @@
                     whichHeap == HEAP_DEX || whichHeap == HEAP_ART) {
                 stats[subHeap].pss += pss;
                 stats[subHeap].swappablePss += swappable_pss;
+                stats[subHeap].rss += rss;
                 stats[subHeap].privateDirty += private_dirty;
                 stats[subHeap].sharedDirty += shared_dirty;
                 stats[subHeap].privateClean += private_clean;
@@ -495,15 +500,19 @@
     if (read_memtrack_memory(pid, &graphics_mem) == 0) {
         stats[HEAP_GRAPHICS].pss = graphics_mem.graphics;
         stats[HEAP_GRAPHICS].privateDirty = graphics_mem.graphics;
+        stats[HEAP_GRAPHICS].rss = graphics_mem.graphics;
         stats[HEAP_GL].pss = graphics_mem.gl;
         stats[HEAP_GL].privateDirty = graphics_mem.gl;
+        stats[HEAP_GL].rss = graphics_mem.gl;
         stats[HEAP_OTHER_MEMTRACK].pss = graphics_mem.other;
         stats[HEAP_OTHER_MEMTRACK].privateDirty = graphics_mem.other;
+        stats[HEAP_OTHER_MEMTRACK].rss = graphics_mem.other;
     }
 
     for (int i=_NUM_CORE_HEAP; i<_NUM_EXCLUSIVE_HEAP; i++) {
         stats[HEAP_UNKNOWN].pss += stats[i].pss;
         stats[HEAP_UNKNOWN].swappablePss += stats[i].swappablePss;
+        stats[HEAP_UNKNOWN].rss += stats[i].rss;
         stats[HEAP_UNKNOWN].privateDirty += stats[i].privateDirty;
         stats[HEAP_UNKNOWN].sharedDirty += stats[i].sharedDirty;
         stats[HEAP_UNKNOWN].privateClean += stats[i].privateClean;
@@ -515,6 +524,7 @@
     for (int i=0; i<_NUM_CORE_HEAP; i++) {
         env->SetIntField(object, stat_fields[i].pss_field, stats[i].pss);
         env->SetIntField(object, stat_fields[i].pssSwappable_field, stats[i].swappablePss);
+        env->SetIntField(object, stat_fields[i].rss_field, stats[i].rss);
         env->SetIntField(object, stat_fields[i].privateDirty_field, stats[i].privateDirty);
         env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty);
         env->SetIntField(object, stat_fields[i].privateClean_field, stats[i].privateClean);
@@ -536,6 +546,7 @@
     for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) {
         otherArray[j++] = stats[i].pss;
         otherArray[j++] = stats[i].swappablePss;
+        otherArray[j++] = stats[i].rss;
         otherArray[j++] = stats[i].privateDirty;
         otherArray[j++] = stats[i].sharedDirty;
         otherArray[j++] = stats[i].privateClean;
@@ -580,10 +591,11 @@
 }
 
 static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid,
-        jlongArray outUssSwapPss, jlongArray outMemtrack)
+        jlongArray outUssSwapPssRss, jlongArray outMemtrack)
 {
-    char line[1024];
+    char lineBuffer[1024];
     jlong pss = 0;
+    jlong rss = 0;
     jlong swapPss = 0;
     jlong uss = 0;
     jlong memtrack = 0;
@@ -597,50 +609,70 @@
         UniqueFile fp = OpenSmapsOrRollup(pid);
 
         if (fp != nullptr) {
+            char* line;
+
             while (true) {
-                if (fgets(line, sizeof (line), fp.get()) == NULL) {
+                if (fgets(lineBuffer, sizeof (lineBuffer), fp.get()) == NULL) {
                     break;
                 }
+                line = lineBuffer;
 
-                if (line[0] == 'P') {
-                    if (strncmp(line, "Pss:", 4) == 0) {
-                        char* c = line + 4;
-                        while (*c != 0 && (*c < '0' || *c > '9')) {
-                            c++;
+                switch (line[0]) {
+                    case 'P':
+                        if (strncmp(line, "Pss:", 4) == 0) {
+                            char* c = line + 4;
+                            while (*c != 0 && (*c < '0' || *c > '9')) {
+                                c++;
+                            }
+                            pss += atoi(c);
+                        } else if (strncmp(line, "Private_Clean:", 14) == 0
+                                    || strncmp(line, "Private_Dirty:", 14) == 0) {
+                            char* c = line + 14;
+                            while (*c != 0 && (*c < '0' || *c > '9')) {
+                                c++;
+                            }
+                            uss += atoi(c);
                         }
-                        pss += atoi(c);
-                    } else if (strncmp(line, "Private_Clean:", 14) == 0
-                                || strncmp(line, "Private_Dirty:", 14) == 0) {
-                        char* c = line + 14;
-                        while (*c != 0 && (*c < '0' || *c > '9')) {
-                            c++;
+                        break;
+                    case 'R':
+                        if (strncmp(line, "Rss:", 4) == 0) {
+                            char* c = line + 4;
+                            while (*c != 0 && (*c < '0' || *c > '9')) {
+                                c++;
+                            }
+                            rss += atoi(c);
                         }
-                        uss += atoi(c);
-                    }
-                } else if (line[0] == 'S' && strncmp(line, "SwapPss:", 8) == 0) {
-                    char* c = line + 8;
-                    jlong lSwapPss;
-                    while (*c != 0 && (*c < '0' || *c > '9')) {
-                        c++;
-                    }
-                    lSwapPss = atoi(c);
-                    swapPss += lSwapPss;
-                    pss += lSwapPss; // Also in swap, those pages would be accounted as Pss without SWAP
+                        break;
+                    case 'S':
+                        if (strncmp(line, "SwapPss:", 8) == 0) {
+                            char* c = line + 8;
+                            jlong lSwapPss;
+                            while (*c != 0 && (*c < '0' || *c > '9')) {
+                                c++;
+                            }
+                            lSwapPss = atoi(c);
+                            swapPss += lSwapPss;
+                            pss += lSwapPss; // Also in swap, those pages would be accounted as Pss without SWAP
+                        }
+                        break;
                 }
             }
         }
     }
 
-    if (outUssSwapPss != NULL) {
-        if (env->GetArrayLength(outUssSwapPss) >= 1) {
-            jlong* outUssSwapPssArray = env->GetLongArrayElements(outUssSwapPss, 0);
-            if (outUssSwapPssArray != NULL) {
-                outUssSwapPssArray[0] = uss;
-                if (env->GetArrayLength(outUssSwapPss) >= 2) {
-                    outUssSwapPssArray[1] = swapPss;
+    if (outUssSwapPssRss != NULL) {
+        if (env->GetArrayLength(outUssSwapPssRss) >= 1) {
+            jlong* outUssSwapPssRssArray = env->GetLongArrayElements(outUssSwapPssRss, 0);
+            if (outUssSwapPssRssArray != NULL) {
+                outUssSwapPssRssArray[0] = uss;
+                if (env->GetArrayLength(outUssSwapPssRss) >= 2) {
+                    outUssSwapPssRssArray[1] = swapPss;
+                }
+                if (env->GetArrayLength(outUssSwapPssRss) >= 3) {
+                    outUssSwapPssRssArray[2] = rss;
                 }
             }
-            env->ReleaseLongArrayElements(outUssSwapPss, outUssSwapPssArray, 0);
+            env->ReleaseLongArrayElements(outUssSwapPssRss, outUssSwapPssRssArray, 0);
         }
     }
 
@@ -1209,6 +1241,8 @@
                 env->GetFieldID(clazz, stat_field_names[i].pss_name, "I");
         stat_fields[i].pssSwappable_field =
                 env->GetFieldID(clazz, stat_field_names[i].pssSwappable_name, "I");
+        stat_fields[i].rss_field =
+                env->GetFieldID(clazz, stat_field_names[i].rss_name, "I");
         stat_fields[i].privateDirty_field =
                 env->GetFieldID(clazz, stat_field_names[i].privateDirty_name, "I");
         stat_fields[i].sharedDirty_field =
diff --git a/core/jni/android_text_MeasuredParagraph.cpp b/core/jni/android_text_MeasuredParagraph.cpp
index f0e449d..dddddbb 100644
--- a/core/jni/android_text_MeasuredParagraph.cpp
+++ b/core/jni/android_text_MeasuredParagraph.cpp
@@ -115,6 +115,10 @@
     return toJLong(&releaseMeasuredParagraph);
 }
 
+static jint nGetMemoryUsage(jlong ptr) {
+    return static_cast<jint>(toMeasuredParagraph(ptr)->getMemoryUsage());
+}
+
 static const JNINativeMethod gMethods[] = {
     // MeasuredParagraphBuilder native functions.
     {"nInitBuilder", "()J", (void*) nInitBuilder},
@@ -126,6 +130,7 @@
     // MeasuredParagraph native functions.
     {"nGetWidth", "(JII)F", (void*) nGetWidth},  // Critical Natives
     {"nGetReleaseFunc", "()J", (void*) nGetReleaseFunc},  // Critical Natives
+    {"nGetMemoryUsage", "(J)I", (void*) nGetMemoryUsage},  // Critical Native
 };
 
 int register_android_text_MeasuredParagraph(JNIEnv* env) {
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index dec6c02..62aa1f38 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -610,7 +610,7 @@
         return -1;
     }
 
-    char buffer[256];
+    char buffer[2048];
     const int len = read(fd, buffer, sizeof(buffer)-1);
     close(fd);
 
@@ -719,7 +719,7 @@
     int fd = open(file.string(), O_RDONLY | O_CLOEXEC);
 
     if (fd >= 0) {
-        const size_t BUFFER_SIZE = 2048;
+        const size_t BUFFER_SIZE = 4096;
         char* buffer = (char*)malloc(BUFFER_SIZE);
         int len = read(fd, buffer, BUFFER_SIZE-1);
         close(fd);
diff --git a/core/proto/android/service/procstats.proto b/core/proto/android/service/procstats.proto
index 4c11f1e..15ede0c 100644
--- a/core/proto/android/service/procstats.proto
+++ b/core/proto/android/service/procstats.proto
@@ -169,6 +169,9 @@
 
         // USS is memory shared between processes, divided evenly for accounting
         optional android.util.AggStats uss = 7;
+
+        // RSS is memory resident for this process
+        optional android.util.AggStats rss = 8;
     }
     repeated State states = 5;
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 2779cd6..36082ca 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1457,6 +1457,12 @@
         android:label="@string/permlab_nfc"
         android:protectionLevel="normal" />
 
+    <!-- Allows applications to receive NFC transaction events.
+         <p>Protection level: normal
+    -->
+    <permission android:name="android.permission.NFC_TRANSACTION_EVENT"
+        android:protectionLevel="normal" />
+
     <!-- @SystemApi Allows an internal user to use privileged ConnectivityManager APIs.
          @hide -->
     <permission android:name="android.permission.CONNECTIVITY_INTERNAL"
diff --git a/core/res/res/xml/default_zen_mode_config.xml b/core/res/res/xml/default_zen_mode_config.xml
index 1e4c03e..a446088 100644
--- a/core/res/res/xml/default_zen_mode_config.xml
+++ b/core/res/res/xml/default_zen_mode_config.xml
@@ -19,5 +19,6 @@
 
 <!-- Default configuration for zen mode.  See android.service.notification.ZenModeConfig. -->
 <zen version="2">
-    <allow alarms="true" media_system_other="true" calls="false" messages="false" reminders="false" events="false" />
+    <allow alarms="true" media_system_other="true" calls="false" messages="false" reminders="false"
+           events="false" />
 </zen>
diff --git a/media/java/android/media/IMediaSession2.aidl b/media/java/android/media/IMediaSession2.aidl
deleted file mode 100644
index 9474154..0000000
--- a/media/java/android/media/IMediaSession2.aidl
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.media;
-
-import android.media.IMediaSession2Callback;
-import android.os.Bundle;
-
-/**
- * Interface to MediaSession2. Framework MUST only call oneway APIs.
- *
- * @hide
- */
-oneway interface IMediaSession2 {
-    // TODO(jaewan): add onCommand() to send private command
-    // TODO(jaewan): Due to the nature of oneway calls, APIs can be called in out of order
-    //               Add id for individual calls to address this.
-
-    // TODO(jaewan): We may consider to add another binder just for the connection
-    //               not to expose other methods to the controller whose connection wasn't accepted.
-    //               But this would be enough for now because it's the same as existing
-    //               MediaBrowser and MediaBrowserService.
-    void connect(String callingPackage, IMediaSession2Callback callback);
-    void release(IMediaSession2Callback caller);
-
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    // send command
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    void sendCommand(IMediaSession2Callback caller, in Bundle command, in Bundle args);
-    void sendTransportControlCommand(IMediaSession2Callback caller,
-            int commandCode, in Bundle args);
-
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    // Get library service specific
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    void getBrowserRoot(IMediaSession2Callback callback, in Bundle rootHints);
-}
diff --git a/media/java/android/media/IMediaSession2Callback.aidl b/media/java/android/media/IMediaSession2Callback.aidl
deleted file mode 100644
index 45d40e6..0000000
--- a/media/java/android/media/IMediaSession2Callback.aidl
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.media;
-
-import android.os.Bundle;
-import android.media.session.PlaybackState;
-import android.media.IMediaSession2;
-
-/**
- * Interface from MediaSession2 to MediaSession2Record.
- * <p>
- * Keep this interface oneway. Otherwise a malicious app may implement fake version of this,
- * and holds calls from session to make session owner(s) frozen.
- *
- * @hide
- */
-oneway interface IMediaSession2Callback {
-    void onPlaybackStateChanged(in Bundle state);
-    void onPlaylistParamsChanged(in Bundle params);
-
-    /**
-     * Called only when the controller is created with service's token.
-     *
-     * @param sessionBinder {@code null} if the connect is rejected or is disconnected. a session
-     *     binder if the connect is accepted.
-     * @param commands initially allowed commands.
-     */
-    // TODO(jaewan): Also need to pass flags for allowed actions for permission check.
-    //               For example, a media can allow setRating only for whitelisted apps
-    //               it's better for controller to know such information in advance.
-    //               Follow-up TODO: Add similar functions to the session.
-    // TODO(jaewan): Is term 'accepted/rejected' correct? For permission, 'grant' is used.
-    void onConnectionChanged(IMediaSession2 sessionBinder, in Bundle commandGroup);
-
-    void onCustomLayoutChanged(in List<Bundle> commandButtonlist);
-
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    // Browser sepcific
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    void onGetRootResult(in Bundle rootHints, String rootMediaId, in Bundle rootExtra);
-}
diff --git a/media/java/android/media/MediaController2.java b/media/java/android/media/MediaController2.java
index c60a689..3d27a48 100644
--- a/media/java/android/media/MediaController2.java
+++ b/media/java/android/media/MediaController2.java
@@ -126,11 +126,9 @@
         /**
          * Called when the playlist is changed.
          *
-         * @param list
-         * @param param
+         * @param playlist A new playlist set by the session.
          */
-        public void onPlaylistChanged(
-                @NonNull List<MediaItem2> list, @NonNull PlaylistParams param) { }
+        public void onPlaylistChanged(@NonNull List<MediaItem2> playlist) { }
 
         /**
          * Called when the playback state is changed, or connection success.
diff --git a/media/java/android/media/MediaItem2.java b/media/java/android/media/MediaItem2.java
index f9711aa..2e9894b 100644
--- a/media/java/android/media/MediaItem2.java
+++ b/media/java/android/media/MediaItem2.java
@@ -20,6 +20,9 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.content.Context;
+import android.media.update.ApiLoader;
+import android.media.update.MediaItem2Provider;
 import android.os.Bundle;
 import android.text.TextUtils;
 
@@ -36,10 +39,6 @@
  * @hide
  */
 public class MediaItem2 {
-    private final int mFlags;
-    private MediaMetadata2 mMetadata;
-    private DataSourceDesc mDataSourceDesc;
-
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(flag=true, value = { FLAG_BROWSABLE, FLAG_PLAYABLE })
@@ -58,17 +57,29 @@
      */
     public static final int FLAG_PLAYABLE = 1 << 1;
 
+    private final MediaItem2Provider mProvider;
+
     /**
      * Create a new media item.
      *
+     * @param mediaId id of this item. It must be unique whithin this app
      * @param metadata metadata with the media id.
      * @param flags The flags for this item.
      */
-    public MediaItem2(@Nullable MediaMetadata2 metadata,
-            @Nullable DataSourceDesc data, @Flags int flags) {
-        mFlags = flags;
-        mDataSourceDesc = data;
-        setMetadata(metadata);
+    public MediaItem2(@NonNull Context context, @NonNull String mediaId,
+            @NonNull DataSourceDesc dsd, @Nullable MediaMetadata2 metadata,
+            @Flags int flags) {
+        mProvider = ApiLoader.getProvider(context).createMediaItem2Provider(
+                context, this, mediaId, dsd, metadata, flags);
+    }
+
+    /**
+     * Create a new media item
+     * @hide
+     */
+    @SystemApi
+    public MediaItem2(MediaItem2Provider provider) {
+        mProvider = provider;
     }
 
     /**
@@ -78,22 +89,22 @@
      */
     public Bundle toBundle() {
         // TODO(jaewan): Fill here when we rebase.
-        return new Bundle();
+        return mProvider.toBundle_impl();
+    }
+
+    public static MediaItem2 fromBundle(Context context, Bundle bundle) {
+        return ApiLoader.getProvider(context).fromBundle_MediaItem2(context, bundle);
     }
 
     public String toString() {
-        final StringBuilder sb = new StringBuilder("MediaItem2{");
-        sb.append("mFlags=").append(mFlags);
-        sb.append(", mMetadata=").append(mMetadata);
-        sb.append('}');
-        return sb.toString();
+        return mProvider.toString_impl();
     }
 
     /**
      * Gets the flags of the item.
      */
     public @Flags int getFlags() {
-        return mFlags;
+        return mProvider.getFlags_impl();
     }
 
     /**
@@ -101,7 +112,7 @@
      * @see #FLAG_BROWSABLE
      */
     public boolean isBrowsable() {
-        return (mFlags & FLAG_BROWSABLE) != 0;
+        return mProvider.isBrowsable_impl();
     }
 
     /**
@@ -109,29 +120,24 @@
      * @see #FLAG_PLAYABLE
      */
     public boolean isPlayable() {
-        return (mFlags & FLAG_PLAYABLE) != 0;
+        return mProvider.isPlayable_impl();
     }
 
     /**
-     * Set a metadata. Metadata shouldn't be null and should have non-empty media id.
+     * Set a metadata. Metadata shouldn't be {@code null} and its id should be match
+     * with this instance's id.
      *
-     * @param metadata
+     * @param metadata metadata to update
      */
     public void setMetadata(@NonNull MediaMetadata2 metadata) {
-        if (metadata == null) {
-            throw new IllegalArgumentException("metadata cannot be null");
-        }
-        if (TextUtils.isEmpty(metadata.getMediaId())) {
-            throw new IllegalArgumentException("metadata must have a non-empty media id");
-        }
-        mMetadata = metadata;
+        mProvider.setMetadata_impl(metadata);
     }
 
     /**
      * Returns the metadata of the media.
      */
     public @NonNull MediaMetadata2 getMetadata() {
-        return mMetadata;
+        return mProvider.getMetadata_impl();
     }
 
     /**
@@ -139,10 +145,17 @@
      * @see MediaMetadata2#METADATA_KEY_MEDIA_ID
      */
     public @Nullable String getMediaId() {
-        return mMetadata.getMediaId();
+        return mProvider.getMediaId_impl();
     }
 
+    /**
+     * Return the {@link DataSourceDesc}
+     * <p>
+     * Can be {@code null} if the MediaItem2 came from another process and anonymized
+     *
+     * @return data source descriptor
+     */
     public @Nullable DataSourceDesc getDataSourceDesc() {
-        return mDataSourceDesc;
+        return mProvider.getDataSourceDesc_impl();
     }
 }
diff --git a/media/java/android/media/MediaPlayerInterface.java b/media/java/android/media/MediaPlayerInterface.java
index 46518d5..78e2391 100644
--- a/media/java/android/media/MediaPlayerInterface.java
+++ b/media/java/android/media/MediaPlayerInterface.java
@@ -64,10 +64,10 @@
     @Nullable
     AudioAttributes getAudioAttributes();
 
-    void setPlaylist(List<MediaItem2> list, PlaylistParams param);
     void addPlaylistItem(int index, MediaItem2 item);
     void removePlaylistItem(MediaItem2 item);
 
+    void setPlaylist(List<MediaItem2> playlist);
     List<MediaItem2> getPlaylist();
 
     void setCurrentPlaylistItem(int index);
diff --git a/media/java/android/media/MediaSession2.java b/media/java/android/media/MediaSession2.java
index 5b2fff1..aa329ab 100644
--- a/media/java/android/media/MediaSession2.java
+++ b/media/java/android/media/MediaSession2.java
@@ -34,6 +34,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.IInterface;
 import android.os.Parcelable;
 import android.os.ResultReceiver;
 import android.text.TextUtils;
@@ -630,7 +631,7 @@
         // TODO(jaewan): SystemApi
         // TODO(jaewan): Also accept componentName to check notificaiton listener.
         public ControllerInfo(Context context, int uid, int pid, String packageName,
-                IMediaSession2Callback callback) {
+                IInterface callback) {
             mProvider = ApiLoader.getProvider(context)
                     .createMediaSession2ControllerInfoProvider(
                             context, this, uid, pid, packageName, callback);
@@ -1261,10 +1262,19 @@
         // To match with KEYCODE_MEDIA_SKIP_BACKWARD
     }
 
-    public void setPlaylist(@NonNull List<MediaItem2> playlist, @NonNull PlaylistParams param) {
-        mProvider.setPlaylist_impl(playlist, param);
+    /**
+     * Sets a list of {@link MediaItem2} as the current play list.
+     *
+     * @param playlist A list of {@link MediaItem2} objects to set as a play list.
+     * @throws IllegalArgumentException if given {@param playlist} is null.
+     */
+    public void setPlaylist(@NonNull List<MediaItem2> playlist) {
+        mProvider.setPlaylist_impl(playlist);
     }
 
+    /**
+     * Returns the playlist which is lastly set.
+     */
     public List<MediaItem2> getPlaylist() {
         return mProvider.getPlaylist_impl();
     }
diff --git a/media/java/android/media/SessionPlayer2.java b/media/java/android/media/SessionPlayer2.java
index 2b5a0dc..60acf16 100644
--- a/media/java/android/media/SessionPlayer2.java
+++ b/media/java/android/media/SessionPlayer2.java
@@ -97,8 +97,8 @@
     }
 
     @Override
-    public void setPlaylist(List<MediaItem2> list, PlaylistParams param) {
-        mProvider.setPlaylist_impl(list, param);
+    public void setPlaylist(List<MediaItem2> playlist) {
+        mProvider.setPlaylist_impl(playlist);
     }
 
     @Override
diff --git a/media/java/android/media/SessionToken2.java b/media/java/android/media/SessionToken2.java
index 7591eb3..2c2090c 100644
--- a/media/java/android/media/SessionToken2.java
+++ b/media/java/android/media/SessionToken2.java
@@ -18,14 +18,12 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.media.session.MediaSessionManager;
 import android.media.update.ApiLoader;
 import android.media.update.SessionToken2Provider;
 import android.os.Bundle;
-import android.os.IInterface;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -52,38 +50,45 @@
 
     private final SessionToken2Provider mProvider;
 
+    // From the return value of android.os.Process.getUidForName(String) when error
+    private static final int UID_UNKNOWN = -1;
+
     /**
      * Constructor for the token. You can only create token for session service or library service
      * to use by {@link MediaController2} or {@link MediaBrowser2}.
      *
      * @param context context
-     * @param type type
      * @param packageName package name
      * @param serviceName name of service. Can be {@code null} if it's not an service.
      */
-    public SessionToken2(@NonNull Context context, @TokenType int type, @NonNull String packageName,
+    public SessionToken2(@NonNull Context context, @NonNull String packageName,
             @NonNull String serviceName) {
-        this(context, -1, type, packageName, serviceName, null, null);
+        this(context, packageName, serviceName, UID_UNKNOWN);
+    }
+
+    /**
+     * Constructor for the token. You can only create token for session service or library service
+     * to use by {@link MediaController2} or {@link MediaBrowser2}.
+     *
+     * @param context context
+     * @param packageName package name
+     * @param serviceName name of service. Can be {@code null} if it's not an service.
+     * @param uid uid of the app.
+     * @hide
+     */
+    public SessionToken2(@NonNull Context context, @NonNull String packageName,
+            @NonNull String serviceName, int uid) {
+        mProvider = ApiLoader.getProvider(context).createSessionToken2(
+                context, this, packageName, serviceName, uid);
     }
 
     /**
      * Constructor for the token.
-     *
-     * @param context context
-     * @param uid uid
-     * @param type type
-     * @param packageName package name
-     * @param serviceName name of service. Can be {@code null} if it's not an service.
-     * @param id id. Can be {@code null} if serviceName is specified.
-     * @param sessionBinderInterface sessionBinder. Required for the session.
+     * @hide
      */
     @SystemApi
-    public SessionToken2(@NonNull Context context, int uid, @TokenType int type,
-            @NonNull String packageName, @Nullable String serviceName, @Nullable String id,
-            @Nullable IInterface sessionBinderInterface) {
-        mProvider = ApiLoader.getProvider(context)
-                .createSessionToken2(context, this, uid, type, packageName,
-                        serviceName, id, sessionBinderInterface);
+    public SessionToken2(@NonNull SessionToken2Provider provider) {
+        mProvider = provider;
     }
 
     @Override
diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl
index 37c46cb..2d365d0 100644
--- a/media/java/android/media/session/ISessionManager.aidl
+++ b/media/java/android/media/session/ISessionManager.aidl
@@ -17,7 +17,6 @@
 
 import android.content.ComponentName;
 import android.media.IRemoteVolumeController;
-import android.media.IMediaSession2;
 import android.media.ISessionTokensListener;
 import android.media.session.IActiveSessionsListener;
 import android.media.session.ICallback;
diff --git a/media/java/android/media/update/MediaItem2Provider.java b/media/java/android/media/update/MediaItem2Provider.java
new file mode 100644
index 0000000..2970f0e
--- /dev/null
+++ b/media/java/android/media/update/MediaItem2Provider.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 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.
+ */
+
+package android.media.update;
+
+import android.media.DataSourceDesc;
+import android.media.MediaMetadata2;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+// TODO(jaewan): SystemApi
+public interface MediaItem2Provider {
+    Bundle toBundle_impl();
+    String toString_impl();
+    int getFlags_impl();
+    boolean isBrowsable_impl();
+    boolean isPlayable_impl();
+    void setMetadata_impl(MediaMetadata2 metadata);
+    MediaMetadata2 getMetadata_impl();
+    String getMediaId_impl();
+    DataSourceDesc getDataSourceDesc_impl();
+}
diff --git a/media/java/android/media/update/MediaSession2Provider.java b/media/java/android/media/update/MediaSession2Provider.java
index abe3cae..8ff0ea5 100644
--- a/media/java/android/media/update/MediaSession2Provider.java
+++ b/media/java/android/media/update/MediaSession2Provider.java
@@ -53,7 +53,7 @@
     void sendCustomCommand_impl(ControllerInfo controller, Command command, Bundle args,
             ResultReceiver receiver);
     void sendCustomCommand_impl(Command command, Bundle args);
-    void setPlaylist_impl(List<MediaItem2> playlist, PlaylistParams param);
+    void setPlaylist_impl(List<MediaItem2> playlist);
     List<MediaItem2> getPlaylist_impl();
     void setPlaylistParams_impl(PlaylistParams params);
     PlaylistParams getPlaylistParams_impl();
diff --git a/media/java/android/media/update/SessionPlayer2Provider.java b/media/java/android/media/update/SessionPlayer2Provider.java
index 96fa5e1..e068c21 100644
--- a/media/java/android/media/update/SessionPlayer2Provider.java
+++ b/media/java/android/media/update/SessionPlayer2Provider.java
@@ -42,9 +42,9 @@
     PlaybackState2 getPlaybackState_impl();
     void setAudioAttributes_impl(AudioAttributes attributes);
     AudioAttributes getAudioAttributes_impl();
-    void setPlaylist_impl(List<MediaItem2> list, PlaylistParams param);
     void addPlaylistItem_impl(int index, MediaItem2 item);
     void removePlaylistItem_impl(MediaItem2 item);
+    void setPlaylist_impl(List<MediaItem2> playlist);
     List<MediaItem2> getPlaylist_impl();
     void setCurrentPlaylistItem_impl(int index);
     void setPlaylistParams_impl(PlaylistParams params);
diff --git a/media/java/android/media/update/StaticProvider.java b/media/java/android/media/update/StaticProvider.java
index 963bc74..14b23c8 100644
--- a/media/java/android/media/update/StaticProvider.java
+++ b/media/java/android/media/update/StaticProvider.java
@@ -19,13 +19,16 @@
 import android.annotation.Nullable;
 import android.app.PendingIntent;
 import android.content.Context;
+import android.media.DataSourceDesc;
 import android.media.MediaBrowser2;
 import android.media.MediaBrowser2.BrowserCallback;
 import android.media.MediaController2;
 import android.media.MediaController2.ControllerCallback;
+import android.media.MediaItem2;
 import android.media.MediaLibraryService2;
 import android.media.MediaLibraryService2.MediaLibrarySession;
 import android.media.MediaLibraryService2.MediaLibrarySessionCallback;
+import android.media.MediaMetadata2;
 import android.media.MediaPlayerInterface;
 import android.media.MediaSession2;
 import android.media.MediaSession2.SessionCallback;
@@ -74,9 +77,12 @@
             VolumeProvider volumeProvider, int ratingType, PendingIntent sessionActivity,
             Executor executor, MediaLibrarySessionCallback callback);
     SessionToken2Provider createSessionToken2(Context context, SessionToken2 instance,
-            int uid, int type, String packageName, String serviceName, String id,
-            IInterface sessionBinderInterface);
+            String packageName, String serviceName, int uid);
     SessionToken2 SessionToken2_fromBundle(Context context, Bundle bundle);
 
     SessionPlayer2Provider createSessionPlayer2(Context context, SessionPlayer2 instance);
+
+    MediaItem2Provider createMediaItem2Provider(Context context, MediaItem2 mediaItem2,
+            String mediaId, DataSourceDesc dsd, MediaMetadata2 metadata, int flags);
+    MediaItem2 fromBundle_MediaItem2(Context context, Bundle bundle);
 }
diff --git a/packages/BackupRestoreConfirmation/AndroidManifest.xml b/packages/BackupRestoreConfirmation/AndroidManifest.xml
index 8141fa7..e67b3be 100644
--- a/packages/BackupRestoreConfirmation/AndroidManifest.xml
+++ b/packages/BackupRestoreConfirmation/AndroidManifest.xml
@@ -30,6 +30,7 @@
                   android:title=""
                   android:windowSoftInputMode="stateAlwaysHidden"
                   android:excludeFromRecents="true"
+                  android:launchMode="singleTop"
                   android:exported="true" >
         </activity>
     </application>
diff --git a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
index 9fa7a664..d6b6bf8 100644
--- a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
+++ b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
@@ -52,7 +52,9 @@
     static final String TAG = "BackupRestoreConfirmation";
     static final boolean DEBUG = true;
 
-    static final String DID_ACKNOWLEDGE = "did_acknowledge";
+    static final String KEY_DID_ACKNOWLEDGE = "did_acknowledge";
+    static final String KEY_TOKEN = "token";
+    static final String KEY_ACTION = "action";
 
     static final int MSG_START_BACKUP = 1;
     static final int MSG_BACKUP_PACKAGE = 2;
@@ -69,6 +71,7 @@
     int mToken;
     boolean mIsEncrypted;
     boolean mDidAcknowledge;
+    String mAction;
 
     TextView mStatusView;
     TextView mCurPassword;
@@ -134,26 +137,9 @@
         super.onCreate(icicle);
 
         final Intent intent = getIntent();
-        final String action = intent.getAction();
 
-        final int layoutId;
-        final int titleId;
-        if (action.equals(FullBackup.FULL_BACKUP_INTENT_ACTION)) {
-            layoutId = R.layout.confirm_backup;
-            titleId = R.string.backup_confirm_title;
-        } else if (action.equals(FullBackup.FULL_RESTORE_INTENT_ACTION)) {
-            layoutId = R.layout.confirm_restore;
-            titleId = R.string.restore_confirm_title;
-        } else {
-            Slog.w(TAG, "Backup/restore confirmation activity launched with invalid action!");
-            finish();
-            return;
-        }
-
-        mToken = intent.getIntExtra(FullBackup.CONF_TOKEN_INTENT_EXTRA, -1);
-        if (mToken < 0) {
-            Slog.e(TAG, "Backup/restore confirmation requested but no token passed!");
-            finish();
+        boolean tokenValid = setTokenOrFinish(intent, icicle);
+        if (!tokenValid) { // already called finish()
             return;
         }
 
@@ -169,6 +155,61 @@
             mObserver.setHandler(mHandler);
         }
 
+        setViews(intent, icicle);
+    }
+
+    @Override
+    public void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        setIntent(intent);
+
+        boolean tokenValid = setTokenOrFinish(intent, null);
+        if (!tokenValid) { // already called finish()
+            return;
+        }
+
+        setViews(intent, null);
+    }
+
+    private boolean setTokenOrFinish(Intent intent, Bundle icicle) {
+        mToken = intent.getIntExtra(FullBackup.CONF_TOKEN_INTENT_EXTRA, -1);
+
+        // for relaunch, we try to use the last token before exit
+        if (icicle != null) {
+            mToken = icicle.getInt(KEY_TOKEN, mToken);
+        }
+
+        if (mToken < 0) {
+            Slog.e(TAG, "Backup/restore confirmation requested but no token passed!");
+            finish();
+            return false;
+        }
+
+        return true;
+    }
+
+    private void setViews(Intent intent, Bundle icicle) {
+        mAction = intent.getAction();
+
+        // for relaunch, we try to use the last action before exit
+        if (icicle != null) {
+            mAction = icicle.getString(KEY_ACTION, mAction);
+        }
+
+        final int layoutId;
+        final int titleId;
+        if (mAction.equals(FullBackup.FULL_BACKUP_INTENT_ACTION)) {
+            layoutId = R.layout.confirm_backup;
+            titleId = R.string.backup_confirm_title;
+        } else if (mAction.equals(FullBackup.FULL_RESTORE_INTENT_ACTION)) {
+            layoutId = R.layout.confirm_restore;
+            titleId = R.string.restore_confirm_title;
+        } else {
+            Slog.w(TAG, "Backup/restore confirmation activity launched with invalid action!");
+            finish();
+            return;
+        }
+
         setTitle(titleId);
         setContentView(layoutId);
 
@@ -202,7 +243,7 @@
 
         // if we're a relaunch we may need to adjust button enable state
         if (icicle != null) {
-            mDidAcknowledge = icicle.getBoolean(DID_ACKNOWLEDGE, false);
+            mDidAcknowledge = icicle.getBoolean(KEY_DID_ACKNOWLEDGE, false);
             mAllowButton.setEnabled(!mDidAcknowledge);
             mDenyButton.setEnabled(!mDidAcknowledge);
         }
@@ -249,7 +290,9 @@
 
     @Override
     protected void onSaveInstanceState(Bundle outState) {
-        outState.putBoolean(DID_ACKNOWLEDGE, mDidAcknowledge);
+        outState.putBoolean(KEY_DID_ACKNOWLEDGE, mDidAcknowledge);
+        outState.putInt(KEY_TOKEN, mToken);
+        outState.putString(KEY_ACTION, mAction);
     }
 
     void sendAcknowledgement(int token, boolean allow, IFullBackupRestoreObserver observer) {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
index 6c74418..f6a259d 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
@@ -889,7 +889,7 @@
 
         private PersistenceManager() {
             mStatePersistFile = new AtomicFile(new File(getFilesDir(),
-                    PERSIST_FILE_NAME));
+                    PERSIST_FILE_NAME), "print-spooler");
         }
 
         public void writeStateLocked() {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java b/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java
index 7935440..5be0176 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java
@@ -547,7 +547,7 @@
 
         private PersistenceManager(final Activity activity, final int internalLoaderId) {
             mStatePersistFile = new AtomicFile(new File(activity.getFilesDir(),
-                    PERSIST_FILE_NAME));
+                    PERSIST_FILE_NAME), "printer-history");
 
             // Initialize enabled services to make sure they are set are the read task might be done
             // before the loader updated the services the first time.
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index a8a67ab..f158a65 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -166,6 +166,9 @@
     @GuardedBy("mLock")
     private final File mStatePersistFile;
 
+    @GuardedBy("mLock")
+    private final String mStatePersistTag;
+
     private final Setting mNullSetting = new Setting(null, null, false, null, null) {
         @Override
         public boolean isNull() {
@@ -250,6 +253,7 @@
         mContext = context;
         mLock = lock;
         mStatePersistFile = file;
+        mStatePersistTag = "settings-" + getTypeFromKey(key) + "-" + getUserIdFromKey(key);
         mKey = key;
         mHandler = new MyHandler(looper);
         if (maxBytesPerAppPackage == MAX_BYTES_PER_APP_PACKAGE_LIMITED) {
@@ -634,7 +638,7 @@
                 Slog.i(LOG_TAG, "[PERSIST START]");
             }
 
-            AtomicFile destination = new AtomicFile(mStatePersistFile);
+            AtomicFile destination = new AtomicFile(mStatePersistFile, mStatePersistTag);
             FileOutputStream out = null;
             try {
                 out = destination.startWrite();
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
index 32eb5d5..4b3afdc 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
@@ -99,6 +99,9 @@
         public ComponentName effectsSuppressor;
         public String effectsSuppressorName;
         public int activeStream = NO_ACTIVE_STREAM;
+        public boolean disallowAlarms;
+        public boolean disallowMedia;
+        public boolean disallowRinger;
 
         public State copy() {
             final State rt = new State();
@@ -113,6 +116,9 @@
             }
             rt.effectsSuppressorName = effectsSuppressorName;
             rt.activeStream = activeStream;
+            rt.disallowAlarms = disallowAlarms;
+            rt.disallowMedia = disallowMedia;
+            rt.disallowRinger = disallowRinger;
             return rt;
         }
 
@@ -142,6 +148,9 @@
             sep(sb, indent); sb.append("effectsSuppressor:").append(effectsSuppressor);
             sep(sb, indent); sb.append("effectsSuppressorName:").append(effectsSuppressorName);
             sep(sb, indent); sb.append("activeStream:").append(activeStream);
+            sep(sb, indent); sb.append("disallowAlarms:").append(disallowAlarms);
+            sep(sb, indent); sb.append("disallowMedia:").append(disallowMedia);
+            sep(sb, indent); sb.append("disallowRinger:").append(disallowRinger);
             if (indent > 0) sep(sb, indent);
             return sb.append('}').toString();
         }
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
index eda8c69..faa2c17 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
@@ -31,6 +31,7 @@
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:layout_marginBottom="@dimen/widget_vertical_padding"
         android:orientation="vertical">
         <RelativeLayout
             android:id="@+id/keyguard_clock_container"
@@ -63,7 +64,6 @@
             <include layout="@layout/keyguard_status_area"
                 android:id="@+id/keyguard_status_area"
                 android:layout_marginTop="20dp"
-                android:layout_marginBottom="@dimen/widget_vertical_padding"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_below="@id/clock_separator" />
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 5aca7f9..28a0935 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -75,7 +75,7 @@
     <dimen name="password_char_padding">8dp</dimen>
 
     <!-- The vertical margin between the date and the owner info. -->
-    <dimen name="date_owner_info_margin">6dp</dimen>
+    <dimen name="date_owner_info_margin">2dp</dimen>
 
     <!-- The translation for disappearing security views after having solved them. -->
     <dimen name="disappear_y_translation">-32dp</dimen>
diff --git a/packages/SystemUI/res/layout/back.xml b/packages/SystemUI/res/layout/back.xml
index 43bec91..6843db9 100644
--- a/packages/SystemUI/res/layout/back.xml
+++ b/packages/SystemUI/res/layout/back.xml
@@ -24,8 +24,8 @@
     systemui:keyCode="4"
     android:scaleType="fitCenter"
     android:contentDescription="@string/accessibility_back"
-    android:paddingTop="15dp"
-    android:paddingBottom="15dp"
+    android:paddingTop="@dimen/home_padding"
+    android:paddingBottom="@dimen/home_padding"
     android:paddingStart="@dimen/navigation_key_padding"
     android:paddingEnd="@dimen/navigation_key_padding"
     />
diff --git a/packages/SystemUI/res/layout/recent_apps.xml b/packages/SystemUI/res/layout/recent_apps.xml
index c84d280..6b08cea 100644
--- a/packages/SystemUI/res/layout/recent_apps.xml
+++ b/packages/SystemUI/res/layout/recent_apps.xml
@@ -23,8 +23,8 @@
     android:layout_weight="0"
     android:scaleType="fitCenter"
     android:contentDescription="@string/accessibility_recent"
-    android:paddingTop="15dp"
-    android:paddingBottom="15dp"
+    android:paddingTop="@dimen/home_padding"
+    android:paddingBottom="@dimen/home_padding"
     android:paddingStart="@dimen/navigation_key_padding"
     android:paddingEnd="@dimen/navigation_key_padding"
     />
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 268fdec..e95d9fe 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -97,4 +97,7 @@
 
     <!-- The offsets the tasks animate from when recents is launched while docking -->
     <dimen name="recents_task_stack_animation_launched_while_docking_offset">192dp</dimen>
+
+    <!-- Home button padding for sizing -->
+    <dimen name="home_padding">0dp</dimen>
 </resources>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
index da50776..98ede4e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
@@ -31,6 +31,11 @@
             int maxLayer, boolean useIdentityTransform, int rotation);
 
     /**
+     * Begins screen pinning on the provided {@param taskId}.
+     */
+    void startScreenPinning(int taskId);
+
+    /**
      * Called when the overview service has started the recents animation.
      */
     void onRecentsAnimationStarted();
diff --git a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
index b6e49ae..8d8b726 100644
--- a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
@@ -37,6 +37,7 @@
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.system.GraphicBufferCompat;
+import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.CallbackController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
@@ -67,6 +68,7 @@
     private int mConnectionBackoffAttempts;
 
     private ISystemUiProxy mSysUiProxy = new ISystemUiProxy.Stub() {
+
         public GraphicBufferCompat screenshot(Rect sourceCrop, int width, int height, int minLayer,
                 int maxLayer, boolean useIdentityTransform, int rotation) {
             long token = Binder.clearCallingIdentity();
@@ -78,10 +80,27 @@
             }
         }
 
+        public void startScreenPinning(int taskId) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                mHandler.post(() -> {
+                    StatusBar statusBar = ((SystemUIApplication) mContext).getComponent(
+                            StatusBar.class);
+                    if (statusBar != null) {
+                        statusBar.showScreenPinningRequest(taskId, false /* allowCancel */);
+                    }
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
         public void onRecentsAnimationStarted() {
             long token = Binder.clearCallingIdentity();
             try {
-                notifyRecentsAnimationStarted();
+                mHandler.post(() -> {
+                    notifyRecentsAnimationStarted();
+                });
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/SwipeUpOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/SwipeUpOnboarding.java
index 0494e1b..b2472bf 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/SwipeUpOnboarding.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/SwipeUpOnboarding.java
@@ -73,7 +73,6 @@
     private final RippleDrawable mLightRipple;
 
     private boolean mTaskListenerRegistered;
-    private ComponentName mLauncherComponent;
     private boolean mLayoutAttachedToWindow;
     private boolean mBackgroundIsLight;
 
@@ -92,15 +91,7 @@
                     Prefs.putInt(mContext, Prefs.Key.NUM_APPS_LAUNCHED, numAppsLaunched);
                 }
             } else {
-                String runningPackage = info.topActivity.getPackageName();
-                // TODO: use callback from the overview proxy service to handle this case
-                if (runningPackage.equals(mLauncherComponent.getPackageName())
-                        && activityType == ACTIVITY_TYPE_RECENTS) {
-                    Prefs.putBoolean(mContext, Prefs.Key.HAS_SWIPED_UP_FOR_RECENTS, true);
-                    onDisconnectedFromLauncher();
-                } else {
-                    hide(false);
-                }
+                hide(false);
             }
         }
     };
@@ -127,8 +118,8 @@
         final Resources res = context.getResources();
         mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
         mLayout = LayoutInflater.from(mContext).inflate(R.layout.recents_swipe_up_onboarding, null);
-        mTextView = (TextView) mLayout.findViewById(R.id.onboarding_text);
-        mDismissView = (ImageView) mLayout.findViewById(R.id.dismiss);
+        mTextView = mLayout.findViewById(R.id.onboarding_text);
+        mDismissView = mLayout.findViewById(R.id.dismiss);
         mDarkBackgroundColor = res.getColor(android.R.color.background_dark);
         mLightBackgroundColor = res.getColor(android.R.color.background_light);
         mDarkContentColor = res.getColor(R.color.primary_text_default_material_light);
@@ -149,13 +140,7 @@
         }
     }
 
-    public void onConnectedToLauncher(ComponentName launcherComponent) {
-        // TODO: re-enable this once we have the proper callback for when a swipe up was performed.
-        final boolean disableOnboarding = true;
-        if (disableOnboarding) {
-            return;
-        }
-        mLauncherComponent = launcherComponent;
+    public void onConnectedToLauncher() {
         boolean alreadyLearnedSwipeUpForRecents = Prefs.getBoolean(mContext,
                 Prefs.Key.HAS_SWIPED_UP_FOR_RECENTS, false);
         if (!mTaskListenerRegistered && !alreadyLearnedSwipeUpForRecents) {
@@ -164,6 +149,15 @@
         }
     }
 
+    public void onRecentsAnimationStarted() {
+        boolean alreadyLearnedSwipeUpForRecents = Prefs.getBoolean(mContext,
+                Prefs.Key.HAS_SWIPED_UP_FOR_RECENTS, false);
+        if (!alreadyLearnedSwipeUpForRecents) {
+            Prefs.putBoolean(mContext, Prefs.Key.HAS_SWIPED_UP_FOR_RECENTS, true);
+            onDisconnectedFromLauncher();
+        }
+    }
+
     public void onDisconnectedFromLauncher() {
         if (mTaskListenerRegistered) {
             ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskListener);
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
index 15e92f4..406eef8 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
@@ -81,7 +81,7 @@
     private volatile boolean mIsVrModeEnabled;
     private boolean mListening;
     private boolean mExternalChange;
-    private boolean mControlInitialized;
+    private boolean mControlValueInitialized;
 
     private ValueAnimator mSliderAnimator;
 
@@ -337,6 +337,7 @@
 
         mBackgroundHandler.post(mStopListeningRunnable);
         mListening = false;
+        mControlValueInitialized = false;
     }
 
     @Override
@@ -428,10 +429,10 @@
     }
 
     private void animateSliderTo(int target) {
-        if (!mControlInitialized) {
+        if (!mControlValueInitialized) {
             // Don't animate the first value since it's default state isn't meaningful to users.
             mControl.setValue(target);
-            mControlInitialized = true;
+            mControlValueInitialized = true;
         }
         if (mSliderAnimator != null && mSliderAnimator.isStarted()) {
             mSliderAnimator.cancel();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index b5fa523..de6ecac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -218,6 +218,9 @@
         @Override
         public void onRecentsAnimationStarted() {
             mRecentsAnimationStarted = true;
+            if (mSwipeUpOnboarding != null) {
+                mSwipeUpOnboarding.onRecentsAnimationStarted();
+            }
         }
     };
 
@@ -887,7 +890,7 @@
 
     private void setUpSwipeUpOnboarding(boolean connectedToOverviewProxy) {
         if (connectedToOverviewProxy) {
-            mSwipeUpOnboarding.onConnectedToLauncher(mOverviewProxyService.getLauncherComponent());
+            mSwipeUpOnboarding.onConnectedToLauncher();
         } else {
             mSwipeUpOnboarding.onDisconnectedFromLauncher();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/Events.java b/packages/SystemUI/src/com/android/systemui/volume/Events.java
index e1376ca..2c85bb6 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/Events.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/Events.java
@@ -51,6 +51,7 @@
     public static final int EVENT_SUPPRESSOR_CHANGED = 14;  // (component|string) (name|string)
     public static final int EVENT_MUTE_CHANGED = 15;  // (stream|int) (muted|bool)
     public static final int EVENT_TOUCH_LEVEL_DONE = 16;  // (stream|int) (level|bool)
+    public static final int EVENT_ZEN_CONFIG_CHANGED = 17; // (allow/disallow|string)
 
     private static final String[] EVENT_TAGS = {
         "show_dialog",
@@ -70,6 +71,7 @@
         "suppressor_changed",
         "mute_changed",
         "touch_level_done",
+        "zen_mode_config_changed",
     };
 
     public static final int DISMISS_REASON_UNKNOWN = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index 2e23920..a166db5 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -43,6 +43,7 @@
 import android.os.Vibrator;
 import android.provider.Settings;
 import android.service.notification.Condition;
+import android.service.notification.ZenModeConfig;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.view.accessibility.AccessibilityManager;
@@ -109,6 +110,7 @@
     private boolean mShowSafetyWarning;
     private DeviceCallback mDeviceCallback = new DeviceCallback();
     private AudioDeviceInfo mConnectedDevice;
+    private final NotificationManager mNotificationManager;
 
     private boolean mDestroyed;
     private VolumePolicy mVolumePolicy;
@@ -120,6 +122,8 @@
 
     public VolumeDialogControllerImpl(Context context) {
         mContext = context.getApplicationContext();
+        mNotificationManager = (NotificationManager) mContext.getSystemService(
+                Context.NOTIFICATION_SERVICE);
         Events.writeEvent(mContext, Events.EVENT_COLLECTION_STARTED);
         mWorkerThread = new HandlerThread(VolumeDialogControllerImpl.class.getSimpleName());
         mWorkerThread.start();
@@ -425,6 +429,7 @@
         }
         updateRingerModeExternalW(mAudio.getRingerMode());
         updateZenModeW();
+        updateZenConfig();
         updateEffectsSuppressorW(mNoMan.getEffectsSuppressor());
         mCallbacks.onStateChanged(mState);
     }
@@ -510,6 +515,26 @@
         return true;
     }
 
+    private boolean updateZenConfig() {
+        final NotificationManager.Policy policy = mNotificationManager.getNotificationPolicy();
+        boolean disallowAlarms = (policy.priorityCategories & NotificationManager.Policy
+                .PRIORITY_CATEGORY_ALARMS) == 0;
+        boolean disallowMedia = (policy.priorityCategories & NotificationManager.Policy
+                .PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER) == 0;
+        boolean disallowRinger = ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(policy);
+        if (mState.disallowAlarms == disallowAlarms && mState.disallowMedia == disallowMedia
+                && mState.disallowRinger == disallowRinger) {
+            return false;
+        }
+        mState.disallowAlarms = disallowAlarms;
+        mState.disallowMedia = disallowMedia;
+        mState.disallowRinger = disallowRinger;
+        Events.writeEvent(mContext, Events.EVENT_ZEN_CONFIG_CHANGED, "disallowAlarms=" +
+                disallowAlarms + " disallowMedia=" + disallowMedia + " disallowRinger=" +
+                disallowRinger);
+        return true;
+    }
+
     private boolean updateRingerModeExternalW(int rm) {
         if (rm == mState.ringerModeExternal) return false;
         mState.ringerModeExternal = rm;
@@ -850,6 +875,10 @@
             if (ZEN_MODE_URI.equals(uri)) {
                 changed = updateZenModeW();
             }
+            if (ZEN_MODE_CONFIG_URI.equals(uri)) {
+                changed |= updateZenConfig();
+            }
+
             if (changed) {
                 mCallbacks.onStateChanged(mState);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 3e13ddb..8cfdeeb 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -669,10 +669,14 @@
                 && mState.ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE;
         final boolean isRingSilent = isRingStream
                 && mState.ringerModeInternal == AudioManager.RINGER_MODE_SILENT;
+        final boolean isZenPriorityOnly = mState.zenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         final boolean isZenAlarms = mState.zenMode == Global.ZEN_MODE_ALARMS;
         final boolean isZenNone = mState.zenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
         final boolean zenMuted = isZenAlarms ? (isRingStream || isSystemStream)
                 : isZenNone ? (isRingStream || isSystemStream || isAlarmStream || isMusicStream)
+                : isZenPriorityOnly ? ((isAlarmStream && mState.disallowAlarms) ||
+                        (isMusicStream && mState.disallowMedia) ||
+                        (isRingStream && mState.disallowRinger))
                 : false;
 
         // update slider max
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 14b76ab..3b80f55 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -2638,7 +2638,7 @@
             confIntent.setClassName("com.android.backupconfirm",
                     "com.android.backupconfirm.BackupRestoreConfirmation");
             confIntent.putExtra(FullBackup.CONF_TOKEN_INTENT_EXTRA, token);
-            confIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            confIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
             mContext.startActivityAsUser(confIntent, UserHandle.SYSTEM);
         } catch (ActivityNotFoundException e) {
             return false;
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index f4675fd..894106a 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -39,6 +39,7 @@
 import android.os.ServiceManager;
 import android.os.ShellCallback;
 import android.os.ShellCommand;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.StorageManagerInternal;
@@ -248,7 +249,7 @@
 
     public AppOpsService(File storagePath, Handler handler) {
         LockGuard.installLock(this, LockGuard.INDEX_APP_OPS);
-        mFile = new AtomicFile(storagePath);
+        mFile = new AtomicFile(storagePath, "appops");
         mHandler = handler;
         readState();
     }
@@ -1666,8 +1667,6 @@
 
     void writeState() {
         synchronized (mFile) {
-            List<AppOpsManager.PackageOps> allOps = getPackagesForOps(null);
-
             FileOutputStream stream;
             try {
                 stream = mFile.startWrite();
@@ -1676,6 +1675,8 @@
                 return;
             }
 
+            List<AppOpsManager.PackageOps> allOps = getPackagesForOps(null);
+
             try {
                 XmlSerializer out = new FastXmlSerializer();
                 out.setOutput(stream, StandardCharsets.UTF_8.name());
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 21137ad..fc91d0d 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -4306,7 +4306,7 @@
                 Slog.w(TAG, "Couldn't create dir.: " + inputMethodDir.getAbsolutePath());
             }
             final File subtypeFile = new File(inputMethodDir, ADDITIONAL_SUBTYPES_FILE_NAME);
-            mAdditionalInputMethodSubtypeFile = new AtomicFile(subtypeFile);
+            mAdditionalInputMethodSubtypeFile = new AtomicFile(subtypeFile, "input-subtypes");
             if (!subtypeFile.exists()) {
                 // If "subtypes.xml" doesn't exist, create a blank file.
                 writeAdditionalInputMethodSubtypes(
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 7361e70..84b93e3 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -36,6 +36,7 @@
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
 import android.app.KeyguardManager;
+import android.app.admin.SecurityLog;
 import android.app.usage.StorageStatsManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -50,7 +51,6 @@
 import android.content.res.Configuration;
 import android.content.res.ObbInfo;
 import android.database.ContentObserver;
-import android.net.TrafficStats;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.DropBoxManager;
@@ -150,7 +150,6 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
-import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -1275,6 +1274,29 @@
             mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(
                     OBB_FLUSH_MOUNT_STATE, vol.path));
         }
+        maybeLogMediaMount(vol, newState);
+    }
+
+    private void maybeLogMediaMount(VolumeInfo vol, int newState) {
+        if (!SecurityLog.isLoggingEnabled()) {
+            return;
+        }
+
+        final DiskInfo disk = vol.getDisk();
+        if (disk == null || (disk.flags & (DiskInfo.FLAG_SD | DiskInfo.FLAG_USB)) == 0) {
+            return;
+        }
+
+        // Sometimes there is a newline character.
+        final String label = disk.label != null ? disk.label.trim() : "";
+
+        if (newState == VolumeInfo.STATE_MOUNTED
+                || newState == VolumeInfo.STATE_MOUNTED_READ_ONLY) {
+            SecurityLog.writeEvent(SecurityLog.TAG_MEDIA_MOUNT, vol.path, label);
+        } else if (newState == VolumeInfo.STATE_UNMOUNTED
+                || newState == VolumeInfo.STATE_BAD_REMOVAL) {
+            SecurityLog.writeEvent(SecurityLog.TAG_MEDIA_UNMOUNT, vol.path, label);
+        }
     }
 
     private void onMoveStatusLocked(int status) {
@@ -1386,7 +1408,7 @@
         }
 
         mSettingsFile = new AtomicFile(
-                new File(Environment.getDataSystemDirectory(), "storage.xml"));
+                new File(Environment.getDataSystemDirectory(), "storage.xml"), "storage-settings");
 
         synchronized (mLock) {
             readSettingsLocked();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index b704898..7e952f1e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1656,7 +1656,7 @@
     String mTrackAllocationApp = null;
     String mNativeDebuggingApp = null;
 
-    final long[] mTmpLong = new long[2];
+    final long[] mTmpLong = new long[3];
 
     private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
 
@@ -2614,22 +2614,24 @@
                 }
 
                 int num = 0;
-                long[] tmp = new long[2];
+                long[] tmp = new long[3];
                 do {
                     ProcessRecord proc;
                     int procState;
+                    int statType;
                     int pid;
                     long lastPssTime;
                     synchronized (ActivityManagerService.this) {
                         if (mPendingPssProcesses.size() <= 0) {
                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
-                                    "Collected PSS of " + num + " processes in "
+                                    "Collected pss of " + num + " processes in "
                                     + (SystemClock.uptimeMillis() - start) + "ms");
                             mPendingPssProcesses.clear();
                             return;
                         }
                         proc = mPendingPssProcesses.remove(0);
                         procState = proc.pssProcState;
+                        statType = proc.pssStatType;
                         lastPssTime = proc.lastPssTime;
                         if (proc.thread != null && procState == proc.setProcState
                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
@@ -2648,8 +2650,17 @@
                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
                                 num++;
-                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
-                                        endTime-startTime, SystemClock.uptimeMillis());
+                                ProcessList.commitNextPssTime(proc.procStateMemTracker);
+                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1], tmp[2],
+                                        statType, endTime-startTime, SystemClock.uptimeMillis());
+                            } else {
+                                ProcessList.abortNextPssTime(proc.procStateMemTracker);
+                                if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
+                                        ": " + (proc.thread == null ? "NO_THREAD " : "") +
+                                        (proc.pid != pid ? "PID_CHANGED " : "") +
+                                        " initState=" + procState + " curState=" +
+                                        proc.setProcState + " " +
+                                        (proc.lastPssTime != lastPssTime ? "TIME_CHANGED" : ""));
                             }
                         }
                     }
@@ -2946,7 +2957,7 @@
                     }
                 });
 
-        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
+        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri-grants");
 
         mUserController = new UserController(this);
 
@@ -6435,7 +6446,8 @@
                     if (!keepState) {
                         synchronized (this) {
                             // Remove all permissions granted from/to this package
-                            removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
+                            removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true,
+                                    false);
                         }
 
                         // Reset notification state
@@ -6763,7 +6775,7 @@
                     if (proc.thread != null && proc.setAdj == oomAdj) {
                         // Record this for posterity if the process has been stable.
                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
-                                infos[i].getTotalUss(), false,
+                                infos[i].getTotalUss(), infos[i].getTotalRss(), false,
                                 ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime-startTime,
                                 proc.pkgList);
                     }
@@ -6786,7 +6798,7 @@
                     oomAdj = proc != null ? proc.setAdj : 0;
                 }
             }
-            long[] tmpUss = new long[1];
+            long[] tmpUss = new long[3];
             long startTime = SystemClock.currentThreadTimeMillis();
             pss[i] = Debug.getPss(pids[i], tmpUss, null);
             long endTime = SystemClock.currentThreadTimeMillis();
@@ -6794,7 +6806,7 @@
                 synchronized (this) {
                     if (proc.thread != null && proc.setAdj == oomAdj) {
                         // Record this for posterity if the process has been stable.
-                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false,
+                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], tmpUss[2], false,
                                 ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList);
                     }
                 }
@@ -7090,7 +7102,7 @@
         }
 
         // Remove transient permissions granted from/to this package/user
-        removeUriPermissionsForPackageLocked(packageName, userId, false);
+        removeUriPermissionsForPackageLocked(packageName, userId, false, false);
 
         if (doit) {
             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
@@ -9813,9 +9825,11 @@
      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
      *            to all users.
      * @param persistable If persistable grants should be removed.
+     * @param targetOnly When {@code true}, only remove permissions where the app is the target,
+     * not source.
      */
     private void removeUriPermissionsForPackageLocked(
-            String packageName, int userHandle, boolean persistable) {
+            String packageName, int userHandle, boolean persistable, boolean targetOnly) {
         if (userHandle == UserHandle.USER_ALL && packageName == null) {
             throw new IllegalArgumentException("Must narrow by either package or user");
         }
@@ -9834,7 +9848,7 @@
                     final UriPermission perm = it.next();
 
                     // Only inspect grants matching package
-                    if (packageName == null || perm.sourcePkg.equals(packageName)
+                    if (packageName == null || (!targetOnly && perm.sourcePkg.equals(packageName))
                             || perm.targetPkg.equals(packageName)) {
                         // Hacky solution as part of fixing a security bug; ignore
                         // grants associated with DownloadManager so we don't have
@@ -9953,6 +9967,8 @@
     private void writeGrantedUriPermissions() {
         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
 
+        final long startTime = SystemClock.uptimeMillis();
+
         // Snapshot permissions so we can persist without lock
         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
         synchronized (this) {
@@ -9969,7 +9985,7 @@
 
         FileOutputStream fos = null;
         try {
-            fos = mGrantFile.startWrite();
+            fos = mGrantFile.startWrite(startTime);
 
             XmlSerializer out = new FastXmlSerializer();
             out.setOutput(fos, StandardCharsets.UTF_8.name());
@@ -10086,8 +10102,7 @@
             boolean persistChanged = false;
             GrantUri grantUri = new GrantUri(userId, uri, false);
 
-            UriPermission exactPerm = findUriPermissionLocked(callingUid,
-                    new GrantUri(userId, uri, false));
+            UriPermission exactPerm = findUriPermissionLocked(callingUid, grantUri);
             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
                     new GrantUri(userId, uri, true));
 
@@ -10270,7 +10285,9 @@
     public void clearGrantedUriPermissions(String packageName, int userId) {
         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
                 "clearGrantedUriPermissions");
-        removeUriPermissionsForPackageLocked(packageName, userId, true);
+        synchronized(this) {
+            removeUriPermissionsForPackageLocked(packageName, userId, true, true);
+        }
     }
 
     @Override
@@ -14523,7 +14540,7 @@
                         && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
                     proc.notCachedSinceIdle = true;
                     proc.initialIdlePss = 0;
-                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
+                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, null,
                             mTestPssMode, isSleepingLocked(), now);
                 }
             }
@@ -14836,6 +14853,8 @@
             mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
 
             BinderInternal.nSetBinderProxyCountEnabled(true);
+            //STOPSHIP: Temporary BinderProxy Threshold for b/71353150
+            BinderInternal.nSetBinderProxyCountWatermarks(1500, 1200);
             BinderInternal.setBinderProxyCountCallback(
                     new BinderInternal.BinderProxyLimitListener() {
                         @Override
@@ -18453,12 +18472,13 @@
 
                 final long myTotalPss = mi.getTotalPss();
                 final long myTotalUss = mi.getTotalUss();
+                final long myTotalRss = mi.getTotalRss();
                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
 
                 synchronized (this) {
                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
                         // Record this for posterity if the process has been stable.
-                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true,
+                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
                                 reportType, endTime-startTime, r.pkgList);
                     }
                 }
@@ -18949,12 +18969,13 @@
 
             final long myTotalPss = mi.getTotalPss();
             final long myTotalUss = mi.getTotalUss();
+            final long myTotalRss = mi.getTotalRss();
             final long myTotalSwapPss = mi.getTotalSwappedOutPss();
 
             synchronized (this) {
                 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
                     // Record this for posterity if the process has been stable.
-                    r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true,
+                    r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
                             reportType, endTime-startTime, r.pkgList);
                 }
             }
@@ -20861,7 +20882,8 @@
                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
 
                                         // Remove all permissions granted from/to this package
-                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
+                                        removeUriPermissionsForPackageLocked(ssp, userId, true,
+                                                false);
 
                                         mRecentTasks.removeTasksByPackageName(ssp, userId);
 
@@ -23230,14 +23252,13 @@
      * Record new PSS sample for a process.
      */
     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
-            long pssDuration, long now) {
+            long rss, int statType, long pssDuration, long now) {
         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
-                swapPss * 1024);
+                swapPss * 1024, rss * 1024, statType, procState, pssDuration);
         proc.lastPssTime = now;
-        proc.baseProcessTracker.addPss(pss, uss, true, ProcessStats.ADD_PSS_INTERNAL,
-                pssDuration, proc.pkgList);
+        proc.baseProcessTracker.addPss(pss, uss, rss, true, statType, pssDuration, proc.pkgList);
         if (DEBUG_PSS) Slog.d(TAG_PSS,
-                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
+                "pss of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
                 + " state=" + ProcessList.makeProcStateString(procState));
         if (proc.initialIdlePss == 0) {
             proc.initialIdlePss = pss;
@@ -23336,8 +23357,9 @@
         if (mPendingPssProcesses.size() == 0) {
             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
         }
-        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
+        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of: " + proc);
         proc.pssProcState = procState;
+        proc.pssStatType = ProcessStats.ADD_PSS_INTERNAL_SINGLE;
         mPendingPssProcesses.add(proc);
     }
 
@@ -23352,7 +23374,7 @@
                 return;
             }
         }
-        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
+        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of all procs!  memLowered=" + memLowered);
         mLastFullPssTime = now;
         mFullPssPending = true;
         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
@@ -23365,8 +23387,10 @@
             }
             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
                 app.pssProcState = app.setProcState;
-                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
-                        mTestPssMode, isSleepingLocked(), now);
+                app.pssStatType = always ? ProcessStats.ADD_PSS_INTERNAL_ALL_POLL
+                        : ProcessStats.ADD_PSS_INTERNAL_ALL_MEM;
+                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
+                        app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
                 mPendingPssProcesses.add(app);
             }
         }
@@ -23733,16 +23757,16 @@
                 long startTime = SystemClock.currentThreadTimeMillis();
                 long pss = Debug.getPss(app.pid, mTmpLong, null);
                 long endTime = SystemClock.currentThreadTimeMillis();
-                recordPssSampleLocked(app, app.curProcState, pss, endTime-startTime,
-                        mTmpLong[0], mTmpLong[1], now);
+                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1],
+                        mTmpLong[2], ProcessStats.ADD_PSS_INTERNAL_SINGLE, endTime-startTime, now);
                 mPendingPssProcesses.remove(app);
                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
                         + " to " + app.curProcState + ": "
                         + (SystemClock.uptimeMillis()-start) + "ms");
             }
             app.lastStateTime = now;
-            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
-                    mTestPssMode, isSleepingLocked(), now);
+            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
+                    app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
                     + ProcessList.makeProcStateString(app.setProcState) + " to "
                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
@@ -23752,10 +23776,10 @@
                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
                     mTestPssMode)))) {
                 requestPssLocked(app, app.setProcState);
-                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
-                        mTestPssMode, isSleepingLocked(), now);
+                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
+                        app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
-                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
+                    "Not requesting pss of " + app + ": next=" + (app.nextPssTime-now));
         }
         if (app.setProcState != app.curProcState) {
             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 510a3fa..7c9160a 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1245,10 +1245,14 @@
         synchronized (mService) {
             try {
                 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "resolveIntent");
+                int modifiedFlags = flags
+                        | PackageManager.MATCH_DEFAULT_ONLY | ActivityManagerService.STOCK_PM_FLAGS;
+                if (intent.isBrowsableWebIntent()
+                            || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) {
+                    modifiedFlags |= PackageManager.MATCH_INSTANT;
+                }
                 return mService.getPackageManagerInternalLocked().resolveIntent(
-                        intent, resolvedType, PackageManager.MATCH_INSTANT
-                                | PackageManager.MATCH_DEFAULT_ONLY | flags
-                                | ActivityManagerService.STOCK_PM_FLAGS, userId, true);
+                        intent, resolvedType, modifiedFlags, userId, true);
 
             } finally {
                 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
diff --git a/services/core/java/com/android/server/am/ActivityStartInterceptor.java b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
index 0480646..b86a8a6 100644
--- a/services/core/java/com/android/server/am/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import static android.app.ActivityManager.INTENT_SENDER_ACTIVITY;
+import static android.app.ActivityOptions.ANIM_OPEN_CROSS_PROFILE_APPS;
 import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
 import static android.app.PendingIntent.FLAG_IMMUTABLE;
 import static android.app.PendingIntent.FLAG_ONE_SHOT;
@@ -41,6 +42,7 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -119,11 +121,12 @@
     }
 
     private IntentSender createIntentSenderForOriginalIntent(int callingUid, int flags) {
+        Bundle activityOptions = deferCrossProfileAppsAnimationIfNecessary();
         final IIntentSender target = mService.getIntentSenderLocked(
                 INTENT_SENDER_ACTIVITY, mCallingPackage, callingUid, mUserId, null /*token*/,
                 null /*resultCode*/, 0 /*requestCode*/,
                 new Intent[] { mIntent }, new String[] { mResolvedType },
-                flags, null /*bOptions*/);
+                flags, activityOptions);
         return new IntentSender(target);
     }
 
@@ -164,11 +167,27 @@
         return interceptWorkProfileChallengeIfNeeded();
     }
 
+    /**
+     * If the activity option is the {@link ActivityOptions#ANIM_OPEN_CROSS_PROFILE_APPS} one,
+     * defer the animation until the original intent is started.
+     *
+     * @return the activity option used to start the original intent.
+     */
+    private Bundle deferCrossProfileAppsAnimationIfNecessary() {
+        if (mActivityOptions != null
+                && mActivityOptions.getAnimationType() == ANIM_OPEN_CROSS_PROFILE_APPS) {
+            mActivityOptions = null;
+            return ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle();
+        }
+        return null;
+    }
+
     private boolean interceptQuietProfileIfNeeded() {
         // Do not intercept if the user has not turned off the profile
         if (!mUserManager.isQuietModeEnabled(UserHandle.of(mUserId))) {
             return false;
         }
+
         IntentSender target = createIntentSenderForOriginalIntent(mCallingUid,
                 FLAG_CANCEL_CURRENT | FLAG_ONE_SHOT);
 
@@ -210,8 +229,7 @@
     }
 
     private boolean interceptWorkProfileChallengeIfNeeded() {
-        final Intent interceptingIntent = interceptWithConfirmCredentialsIfNeeded(mIntent,
-                mResolvedType, mAInfo, mCallingPackage, mUserId);
+        final Intent interceptingIntent = interceptWithConfirmCredentialsIfNeeded(mAInfo, mUserId);
         if (interceptingIntent == null) {
             return false;
         }
@@ -248,8 +266,7 @@
      *
      * @return The intercepting intent if needed.
      */
-    private Intent interceptWithConfirmCredentialsIfNeeded(Intent intent, String resolvedType,
-            ActivityInfo aInfo, String callingPackage, int userId) {
+    private Intent interceptWithConfirmCredentialsIfNeeded(ActivityInfo aInfo, int userId) {
         if (!mUserController.shouldConfirmCredentials(userId)) {
             return null;
         }
@@ -296,5 +313,4 @@
         mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags, null /*profilerInfo*/);
         return true;
     }
-
 }
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 8fd754a..eab88aa 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -31,6 +31,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE;
 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
 import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
@@ -789,7 +790,7 @@
         // Instead, launch the ephemeral installer. Once the installer is finished, it
         // starts either the intent we resolved here [on install error] or the ephemeral
         // app [on install success].
-        if (rInfo != null && rInfo.auxiliaryInfo != null) {
+        if (rInfo != null && rInfo.isInstantAppAvailable) {
             intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,
                     callingPackage, verificationBundle, resolvedType, userId);
             resolvedType = null;
@@ -849,22 +850,27 @@
     /**
      * Creates a launch intent for the given auxiliary resolution data.
      */
-    private @NonNull Intent createLaunchIntent(@NonNull AuxiliaryResolveInfo auxiliaryResponse,
+    private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse,
             Intent originalIntent, String callingPackage, Bundle verificationBundle,
             String resolvedType, int userId) {
-        if (auxiliaryResponse.needsPhaseTwo) {
+        if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
             // request phase two resolution
             mService.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
                     auxiliaryResponse, originalIntent, resolvedType, callingPackage,
                     verificationBundle, userId);
         }
         return InstantAppResolver.buildEphemeralInstallerIntent(
-                Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE, originalIntent,
-                auxiliaryResponse.failureIntent, callingPackage, verificationBundle,
-                resolvedType, userId, auxiliaryResponse.packageName, auxiliaryResponse.splitName,
-                auxiliaryResponse.installFailureActivity, auxiliaryResponse.versionCode,
-                auxiliaryResponse.token, auxiliaryResponse.resolveInfo.getExtras(),
-                auxiliaryResponse.needsPhaseTwo);
+                originalIntent,
+                InstantAppResolver.sanitizeIntent(originalIntent),
+                auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent,
+                callingPackage,
+                verificationBundle,
+                resolvedType,
+                userId,
+                auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity,
+                auxiliaryResponse == null ? null : auxiliaryResponse.token,
+                auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo,
+                auxiliaryResponse == null ? null : auxiliaryResponse.filters);
     }
 
     void postStartActivityProcessing(ActivityRecord r, int result, ActivityStack targetStack) {
@@ -924,12 +930,12 @@
         // Don't modify the client's object!
         intent = new Intent(intent);
         if (componentSpecified
-                && intent.getData() != null
-                && Intent.ACTION_VIEW.equals(intent.getAction())
+                && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
+                && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
                 && mService.getPackageManagerInternalLocked()
                         .isInstantAppInstallerComponent(intent.getComponent())) {
             // intercept intents targeted directly to the ephemeral installer the
-            // ephemeral installer should never be started with a raw URL; instead
+            // ephemeral installer should never be started with a raw Intent; instead
             // adjust the intent so it looks like a "normal" instant app launch
             intent.setComponent(null /*component*/);
             componentSpecified = false;
diff --git a/services/core/java/com/android/server/am/AppWarnings.java b/services/core/java/com/android/server/am/AppWarnings.java
index 806e95d..4b43bd9 100644
--- a/services/core/java/com/android/server/am/AppWarnings.java
+++ b/services/core/java/com/android/server/am/AppWarnings.java
@@ -81,7 +81,7 @@
         mUiContext = uiContext;
         mAmsHandler = new ConfigHandler(amsHandler.getLooper());
         mUiHandler = new UiHandler(uiHandler.getLooper());
-        mConfigFile = new AtomicFile(new File(systemDir, CONFIG_FILE_NAME));
+        mConfigFile = new AtomicFile(new File(systemDir, CONFIG_FILE_NAME), "warnings-config");
 
         readConfigFromFileAmsThread();
     }
diff --git a/services/core/java/com/android/server/am/CompatModePackages.java b/services/core/java/com/android/server/am/CompatModePackages.java
index 65c4a42..d84f487 100644
--- a/services/core/java/com/android/server/am/CompatModePackages.java
+++ b/services/core/java/com/android/server/am/CompatModePackages.java
@@ -82,7 +82,7 @@
 
     public CompatModePackages(ActivityManagerService service, File systemDir, Handler handler) {
         mService = service;
-        mFile = new AtomicFile(new File(systemDir, "packages-compat.xml"));
+        mFile = new AtomicFile(new File(systemDir, "packages-compat.xml"), "compat-mode");
         mHandler = new CompatHandler(handler.getLooper());
 
         FileInputStream fis = null;
diff --git a/services/core/java/com/android/server/am/EventLogTags.logtags b/services/core/java/com/android/server/am/EventLogTags.logtags
index a131db5..cb2957d 100644
--- a/services/core/java/com/android/server/am/EventLogTags.logtags
+++ b/services/core/java/com/android/server/am/EventLogTags.logtags
@@ -102,7 +102,7 @@
 # Report collection of global memory state
 30046 am_meminfo (Cached|2|2),(Free|2|2),(Zram|2|2),(Kernel|2|2),(Native|2|2)
 # Report collection of memory used by a process
-30047 am_pss (Pid|1|5),(UID|1|5),(Process Name|3),(Pss|2|2),(Uss|2|2),(SwapPss|2|2)
+30047 am_pss (Pid|1|5),(UID|1|5),(Process Name|3),(Pss|2|2),(Uss|2|2),(SwapPss|2|2),(Rss|2|2),(StatType|1|5),(ProcState|1|5),(TimeToCollect|2|2)
 
 # Attempting to stop an activity
 30048 am_stop_activity (User|1|5),(Token|1|5),(Component Name|3)
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index a50d069..08ee237 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -21,6 +21,7 @@
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.io.PrintWriter;
 import java.nio.ByteBuffer;
 
 import android.app.ActivityManager;
@@ -482,7 +483,7 @@
     public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;
 
     // The maximum amount of time we want to go between PSS collections.
-    public static final int PSS_MAX_INTERVAL = 40*60*1000;
+    public static final int PSS_MAX_INTERVAL = 60*60*1000;
 
     // The minimum amount of time between successive PSS requests for *all* processes.
     public static final int PSS_ALL_INTERVAL = 20*60*1000;
@@ -497,7 +498,10 @@
     private static final int PSS_FIRST_BACKGROUND_INTERVAL = 20*1000;
 
     // The amount of time until PSS when a process first becomes cached.
-    private static final int PSS_FIRST_CACHED_INTERVAL = 30*1000;
+    private static final int PSS_FIRST_CACHED_INTERVAL = 20*1000;
+
+    // The amount of time until PSS when an important process stays in the same state.
+    private static final int PSS_SAME_PERSISTENT_INTERVAL = 20*60*1000;
 
     // The amount of time until PSS when the top process stays in the same state.
     private static final int PSS_SAME_TOP_INTERVAL = 5*60*1000;
@@ -509,7 +513,7 @@
     private static final int PSS_SAME_SERVICE_INTERVAL = 20*60*1000;
 
     // The amount of time until PSS when a cached process stays in the same state.
-    private static final int PSS_SAME_CACHED_INTERVAL = 30*60*1000;
+    private static final int PSS_SAME_CACHED_INTERVAL = 20*60*1000;
 
     // The amount of time until PSS when a persistent process first appears.
     private static final int PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL = 1*60*1000;
@@ -543,7 +547,9 @@
     public static final int PROC_MEM_IMPORTANT = 2;
     public static final int PROC_MEM_SERVICE = 3;
     public static final int PROC_MEM_CACHED = 4;
+    public static final int PROC_MEM_NUM = 5;
 
+    // Map large set of system process states to
     private static final int[] sProcStateToProcMem = new int[] {
         PROC_MEM_PERSISTENT,            // ActivityManager.PROCESS_STATE_PERSISTENT
         PROC_MEM_PERSISTENT,            // ActivityManager.PROCESS_STATE_PERSISTENT_UI
@@ -567,138 +573,96 @@
     };
 
     private static final long[] sFirstAwakePssTimes = new long[] {
-        PSS_FIRST_PERSISTENT_INTERVAL,  // ActivityManager.PROCESS_STATE_PERSISTENT
-        PSS_FIRST_PERSISTENT_INTERVAL,  // ActivityManager.PROCESS_STATE_PERSISTENT_UI
-        PSS_FIRST_TOP_INTERVAL,         // ActivityManager.PROCESS_STATE_TOP
-        PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
-        PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
-        PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
-        PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
-        PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
-        PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_BACKUP
-        PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_SERVICE
-        PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_RECEIVER
-        PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_TOP_SLEEPING
-        PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
-        PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_HOME
-        PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
-        PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
-        PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
-        PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_RECENT
-        PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_EMPTY
+        PSS_FIRST_PERSISTENT_INTERVAL,  // PROC_MEM_PERSISTENT
+        PSS_FIRST_TOP_INTERVAL,         // PROC_MEM_TOP
+        PSS_FIRST_BACKGROUND_INTERVAL,  // PROC_MEM_IMPORTANT
+        PSS_FIRST_BACKGROUND_INTERVAL,  // PROC_MEM_SERVICE
+        PSS_FIRST_CACHED_INTERVAL,      // PROC_MEM_CACHED
     };
 
     private static final long[] sSameAwakePssTimes = new long[] {
-        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_PERSISTENT
-        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_PERSISTENT_UI
-        PSS_SAME_TOP_INTERVAL,          // ActivityManager.PROCESS_STATE_TOP
-        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
-        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
-        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
-        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
-        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
-        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_BACKUP
-        PSS_SAME_SERVICE_INTERVAL,      // ActivityManager.PROCESS_STATE_SERVICE
-        PSS_SAME_SERVICE_INTERVAL,      // ActivityManager.PROCESS_STATE_RECEIVER
-        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_TOP_SLEEPING
-        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
-        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_HOME
-        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
-        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
-        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
-        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_RECENT
-        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_EMPTY
+        PSS_SAME_PERSISTENT_INTERVAL,   // PROC_MEM_PERSISTENT
+        PSS_SAME_TOP_INTERVAL,          // PROC_MEM_TOP
+        PSS_SAME_IMPORTANT_INTERVAL,    // PROC_MEM_IMPORTANT
+        PSS_SAME_SERVICE_INTERVAL,      // PROC_MEM_SERVICE
+        PSS_SAME_CACHED_INTERVAL,       // PROC_MEM_CACHED
     };
 
     private static final long[] sFirstAsleepPssTimes = new long[] {
-        PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL,   // ActivityManager.PROCESS_STATE_PERSISTENT
-        PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL,   // ActivityManager.PROCESS_STATE_PERSISTENT_UI
-        PSS_FIRST_ASLEEP_TOP_INTERVAL,          // ActivityManager.PROCESS_STATE_TOP
-        PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
-        PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
-        PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
-        PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
-        PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
-        PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // ActivityManager.PROCESS_STATE_BACKUP
-        PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // ActivityManager.PROCESS_STATE_SERVICE
-        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_RECEIVER
-        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_TOP_SLEEPING
-        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
-        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_HOME
-        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
-        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
-        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
-        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_RECENT
-        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_EMPTY
+        PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL,   // PROC_MEM_PERSISTENT
+        PSS_FIRST_ASLEEP_TOP_INTERVAL,          // PROC_MEM_TOP
+        PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // PROC_MEM_IMPORTANT
+        PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // PROC_MEM_SERVICE
+        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // PROC_MEM_CACHED
     };
 
     private static final long[] sSameAsleepPssTimes = new long[] {
-        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_PERSISTENT
-        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_PERSISTENT_UI
-        PSS_SAME_TOP_INTERVAL,          // ActivityManager.PROCESS_STATE_TOP
-        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
-        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
-        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
-        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
-        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
-        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
-        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_BACKUP
-        PSS_SAME_SERVICE_INTERVAL,      // ActivityManager.PROCESS_STATE_SERVICE
-        PSS_SAME_SERVICE_INTERVAL,      // ActivityManager.PROCESS_STATE_RECEIVER
-        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_TOP_SLEEPING
-        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
-        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_HOME
-        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
-        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
-        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
-        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_RECENT
-        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_EMPTY
+        PSS_SAME_PERSISTENT_INTERVAL,   // PROC_MEM_PERSISTENT
+        PSS_SAME_TOP_INTERVAL,          // PROC_MEM_TOP
+        PSS_SAME_IMPORTANT_INTERVAL,    // PROC_MEM_IMPORTANT
+        PSS_SAME_SERVICE_INTERVAL,      // PROC_MEM_SERVICE
+        PSS_SAME_CACHED_INTERVAL,       // PROC_MEM_CACHED
     };
 
     private static final long[] sTestFirstPssTimes = new long[] {
-        PSS_TEST_FIRST_TOP_INTERVAL,        // ActivityManager.PROCESS_STATE_PERSISTENT
-        PSS_TEST_FIRST_TOP_INTERVAL,        // ActivityManager.PROCESS_STATE_PERSISTENT_UI
-        PSS_TEST_FIRST_TOP_INTERVAL,        // ActivityManager.PROCESS_STATE_TOP
-        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
-        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
-        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
-        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
-        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
-        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP
-        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE
-        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER
-        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
-        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
-        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HOME
-        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
-        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
-        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
-        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_RECENT
-        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
+        PSS_TEST_FIRST_TOP_INTERVAL,        // PROC_MEM_PERSISTENT
+        PSS_TEST_FIRST_TOP_INTERVAL,        // PROC_MEM_TOP
+        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT
+        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
+        PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_CACHED
     };
 
     private static final long[] sTestSamePssTimes = new long[] {
-        PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_PERSISTENT
-        PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_PERSISTENT_UI
-        PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_TOP
-        PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
-        PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
-        PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
-        PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
-        PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
-        PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_BACKUP
-        PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_SERVICE
-        PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_RECEIVER
-        PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_TOP_SLEEPING
-        PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
-        PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_HOME
-        PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
-        PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
-        PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
-        PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_CACHED_RECENT
-        PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_CACHED_EMPTY
+        PSS_TEST_SAME_BACKGROUND_INTERVAL,  // PROC_MEM_PERSISTENT
+        PSS_TEST_SAME_IMPORTANT_INTERVAL,   // PROC_MEM_TOP
+        PSS_TEST_SAME_IMPORTANT_INTERVAL,   // PROC_MEM_IMPORTANT
+        PSS_TEST_SAME_BACKGROUND_INTERVAL,  // PROC_MEM_SERVICE
+        PSS_TEST_SAME_BACKGROUND_INTERVAL,  // PROC_MEM_CACHED
     };
 
+    public static final class ProcStateMemTracker {
+        final int[] mHighestMem = new int[PROC_MEM_NUM];
+        int mTotalHighestMem = PROC_MEM_CACHED;
+        float mCurFactor = 1.0f;
+
+        int mPendingMemState;
+        int mPendingHighestMemState;
+        boolean mPendingSame;
+
+        public ProcStateMemTracker() {
+            for (int i = PROC_MEM_PERSISTENT; i < PROC_MEM_NUM; i++) {
+                mHighestMem[i] = PROC_MEM_NUM;
+            }
+            mPendingMemState = -1;
+        }
+
+        public void dumpLine(PrintWriter pw) {
+            pw.print("best=");
+            pw.print(mTotalHighestMem);
+            pw.print(" ");
+            pw.print(mCurFactor);
+            pw.print("x (");
+            for (int i = 0; i < PROC_MEM_NUM; i++) {
+                if (i != 0) {
+                    pw.print(", ");
+                }
+                pw.print(i);
+                pw.print("=");
+                pw.print(mHighestMem[i]);
+            }
+            pw.print(")");
+            if (mPendingMemState >= 0) {
+                pw.print(" / pending state=");
+                pw.print(mPendingMemState);
+                pw.print(" highest=");
+                pw.print(mPendingHighestMemState);
+                pw.print(" same=");
+                pw.print(mPendingSame);
+            }
+            pw.println();
+        }
+    }
+
     public static boolean procStatesDifferForMem(int procState1, int procState2) {
         return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
     }
@@ -707,16 +671,50 @@
         return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE;
     }
 
-    public static long computeNextPssTime(int procState, boolean first, boolean test,
+    public static void commitNextPssTime(ProcStateMemTracker tracker) {
+        if (tracker.mPendingMemState >= 0) {
+            tracker.mHighestMem[tracker.mPendingMemState] = tracker.mPendingHighestMemState;
+            tracker.mTotalHighestMem = tracker.mPendingHighestMemState;
+            if (tracker.mPendingSame) {
+                tracker.mCurFactor *= 1.5f;
+            } else {
+                tracker.mCurFactor = 1;
+            }
+            tracker.mPendingMemState = -1;
+        }
+    }
+
+    public static void abortNextPssTime(ProcStateMemTracker tracker) {
+        tracker.mPendingMemState = -1;
+    }
+
+    public static long computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test,
             boolean sleeping, long now) {
+        boolean first;
+        final int memState = sProcStateToProcMem[procState];
+        if (tracker != null) {
+            final int highestMemState = memState < tracker.mTotalHighestMem
+                    ? memState : tracker.mTotalHighestMem;
+            first = highestMemState < tracker.mHighestMem[memState];
+            tracker.mPendingMemState = memState;
+            tracker.mPendingHighestMemState = highestMemState;
+            tracker.mPendingSame = !first;
+        } else {
+            first = true;
+        }
         final long[] table = test
                 ? (first
-                        ? sTestFirstPssTimes
-                        : sTestSamePssTimes)
+                ? sTestFirstPssTimes
+                : sTestSamePssTimes)
                 : (first
-                        ? (sleeping ? sFirstAsleepPssTimes : sFirstAwakePssTimes)
-                        : (sleeping ? sSameAsleepPssTimes : sSameAwakePssTimes));
-        return now + table[procState];
+                ? (sleeping ? sFirstAsleepPssTimes : sFirstAwakePssTimes)
+                : (sleeping ? sSameAsleepPssTimes : sSameAwakePssTimes));
+        long delay = (long)(table[memState] * (tracker != null && !first
+                ? tracker.mCurFactor : 1.0f));
+        if (delay > PSS_MAX_INTERVAL) {
+            delay = PSS_MAX_INTERVAL;
+        }
+        return now + delay;
     }
 
     long getMemLevel(int adjustment) {
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 03e140d..1f60755 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -66,6 +66,8 @@
     final String processName;   // name of the process
     // List of packages running in the process
     final ArrayMap<String, ProcessStats.ProcessStateHolder> pkgList = new ArrayMap<>();
+    final ProcessList.ProcStateMemTracker procStateMemTracker
+            = new ProcessList.ProcStateMemTracker();
     UidRecord uidRecord;        // overall state of process's uid.
     ArraySet<String> pkgDeps;   // additional packages we have a dependency on
     IApplicationThread thread;  // the actual proc...  may be null only if
@@ -102,6 +104,7 @@
     int repProcState = PROCESS_STATE_NONEXISTENT; // Last reported process state
     int setProcState = PROCESS_STATE_NONEXISTENT; // Last set process state in process tracker
     int pssProcState = PROCESS_STATE_NONEXISTENT; // Currently requesting pss for
+    int pssStatType;            // The type of stat collection that we are currently requesting
     int savedPriority;          // Previous priority value if we're switching to non-SCHED_OTHER
     int renderThreadTid;        // TID for RenderThread
     boolean serviceb;           // Process currently is on the service B list
@@ -285,6 +288,7 @@
                 TimeUtils.formatDuration(lastActivityTime, nowUptime, pw);
                 pw.print(" lastPssTime=");
                 TimeUtils.formatDuration(lastPssTime, nowUptime, pw);
+                pw.print(" pssStatType="); pw.print(pssStatType);
                 pw.print(" nextPssTime=");
                 TimeUtils.formatDuration(nextPssTime, nowUptime, pw);
                 pw.println();
@@ -295,6 +299,8 @@
                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, lastCachedPss*1024);
                 pw.print(" lastCachedSwapPss="); DebugUtils.printSizeValue(pw, lastCachedSwapPss*1024);
                 pw.println();
+        pw.print(prefix); pw.print("procStateMemTracker: ");
+        procStateMemTracker.dumpLine(pw);
         pw.print(prefix); pw.print("cached="); pw.print(cached);
                 pw.print(" empty="); pw.println(empty);
         if (serviceb) {
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index af42997..8bf320e 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -220,8 +220,9 @@
     }
 
     public void writeStateLocked(boolean sync, final boolean commit) {
+        final long totalTime;
         synchronized (mPendingWriteLock) {
-            long now = SystemClock.uptimeMillis();
+            final long now = SystemClock.uptimeMillis();
             if (mPendingWrite == null || !mPendingWriteCommitted) {
                 mPendingWrite = Parcel.obtain();
                 mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
@@ -238,19 +239,19 @@
                 updateFile();
             }
             mLastWriteTime = SystemClock.uptimeMillis();
-            if (DEBUG) Slog.d(TAG, "Prepared write state in "
-                    + (SystemClock.uptimeMillis()-now) + "ms");
+            totalTime = SystemClock.uptimeMillis() - now;
+            if (DEBUG) Slog.d(TAG, "Prepared write state in " + now + "ms");
             if (!sync) {
                 BackgroundThread.getHandler().post(new Runnable() {
                     @Override public void run() {
-                        performWriteState();
+                        performWriteState(totalTime);
                     }
                 });
                 return;
             }
         }
 
-        performWriteState();
+        performWriteState(totalTime);
     }
 
     private void updateFile() {
@@ -259,7 +260,7 @@
         mLastWriteTime = SystemClock.uptimeMillis();
     }
 
-    void performWriteState() {
+    void performWriteState(long initialTime) {
         if (DEBUG) Slog.d(TAG, "Performing write to " + mFile.getBaseFile());
         Parcel data;
         AtomicFile file;
@@ -275,12 +276,15 @@
             mWriteLock.lock();
         }
 
+        final long startTime = SystemClock.uptimeMillis();
         FileOutputStream stream = null;
         try {
             stream = file.startWrite();
             stream.write(data.marshall());
             stream.flush();
             file.finishWrite(stream);
+            com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
+                    "procstats", SystemClock.uptimeMillis() - startTime + initialTime);
             if (DEBUG) Slog.d(TAG, "Write completed successfully!");
         } catch (IOException e) {
             Slog.w(TAG, "Error writing process statistics", e);
diff --git a/services/core/java/com/android/server/am/RecentsAnimation.java b/services/core/java/com/android/server/am/RecentsAnimation.java
index fe576fda..c188ccb 100644
--- a/services/core/java/com/android/server/am/RecentsAnimation.java
+++ b/services/core/java/com/android/server/am/RecentsAnimation.java
@@ -70,55 +70,61 @@
 
     void startRecentsActivity(Intent intent, IRecentsAnimationRunner recentsAnimationRunner,
             ComponentName recentsComponent, int recentsUid) {
+        mWindowManager.deferSurfaceLayout();
+        try {
+            // Cancel the previous recents animation if necessary
+            mWindowManager.cancelRecentsAnimation();
 
-        // Cancel the previous recents animation if necessary
-        mWindowManager.cancelRecentsAnimation();
+            final boolean hasExistingHomeActivity = mStackSupervisor.getHomeActivity() != null;
+            if (!hasExistingHomeActivity) {
+                // No home activity
+                final ActivityOptions opts = ActivityOptions.makeBasic();
+                opts.setLaunchActivityType(ACTIVITY_TYPE_HOME);
+                opts.setAvoidMoveToFront();
+                intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NO_ANIMATION);
 
-        final boolean hasExistingHomeActivity = mStackSupervisor.getHomeActivity() != null;
-        if (!hasExistingHomeActivity) {
-            // No home activity
-            final ActivityOptions opts = ActivityOptions.makeBasic();
-            opts.setLaunchActivityType(ACTIVITY_TYPE_HOME);
-            opts.setAvoidMoveToFront();
-            intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NO_ANIMATION);
+                mActivityStartController
+                        .obtainStarter(intent, "startRecentsActivity_noHomeActivity")
+                        .setCallingUid(recentsUid)
+                        .setCallingPackage(recentsComponent.getPackageName())
+                        .setActivityOptions(SafeActivityOptions.fromBundle(opts.toBundle()))
+                        .setMayWait(mUserController.getCurrentUserId())
+                        .execute();
+                mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
 
-            mActivityStartController.obtainStarter(intent, "startRecentsActivity_noHomeActivity")
-                    .setCallingUid(recentsUid)
-                    .setCallingPackage(recentsComponent.getPackageName())
-                    .setActivityOptions(SafeActivityOptions.fromBundle(opts.toBundle()))
-                    .setMayWait(mUserController.getCurrentUserId())
-                    .execute();
-            mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
+                // TODO: Maybe wait for app to draw in this particular case?
+            }
 
-            // TODO: Maybe wait for app to draw in this particular case?
+            final ActivityRecord homeActivity = mStackSupervisor.getHomeActivity();
+            final ActivityDisplay display = homeActivity.getDisplay();
+
+            // Save the initial position of the home activity stack to be restored to after the
+            // animation completes
+            mRestoreHomeBehindStack = hasExistingHomeActivity
+                    ? display.getStackAboveHome()
+                    : null;
+
+            // Move the home activity into place for the animation
+            display.moveHomeStackBehindBottomMostVisibleStack();
+
+            // Mark the home activity as launch-behind to bump its visibility for the
+            // duration of the gesture that is driven by the recents component
+            homeActivity.mLaunchTaskBehind = true;
+
+            // Fetch all the surface controls and pass them to the client to get the animation
+            // started
+            mWindowManager.initializeRecentsAnimation(recentsAnimationRunner, this,
+                    display.mDisplayId);
+
+            // If we updated the launch-behind state, update the visibility of the activities after
+            // we fetch the visible tasks to be controlled by the animation
+            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS);
+
+            // Post a timeout for the animation
+            mHandler.postDelayed(mCancelAnimationRunnable, RECENTS_ANIMATION_TIMEOUT);
+        } finally {
+            mWindowManager.continueSurfaceLayout();
         }
-
-        final ActivityRecord homeActivity = mStackSupervisor.getHomeActivity();
-        final ActivityDisplay display = homeActivity.getDisplay();
-
-        // Save the initial position of the home activity stack to be restored to after the
-        // animation completes
-        mRestoreHomeBehindStack = hasExistingHomeActivity
-                ? display.getStackAboveHome()
-                : null;
-
-        // Move the home activity into place for the animation
-        display.moveHomeStackBehindBottomMostVisibleStack();
-
-        // Mark the home activity as launch-behind to bump its visibility for the
-        // duration of the gesture that is driven by the recents component
-        homeActivity.mLaunchTaskBehind = true;
-
-        // Fetch all the surface controls and pass them to the client to get the animation
-        // started
-        mWindowManager.initializeRecentsAnimation(recentsAnimationRunner, this, display.mDisplayId);
-
-        // If we updated the launch-behind state, update the visibility of the activities after we
-        // fetch the visible tasks to be controlled by the animation
-        mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS);
-
-        // Post a timeout for the animation
-        mHandler.postDelayed(mCancelAnimationRunnable, RECENTS_ANIMATION_TIMEOUT);
     }
 
     @Override
@@ -128,31 +134,40 @@
             if (mWindowManager.getRecentsAnimationController() == null) return;
 
             mWindowManager.inSurfaceTransaction(() -> {
-                mWindowManager.cleanupRecentsAnimation();
+                mWindowManager.deferSurfaceLayout();
+                try {
+                    mWindowManager.cleanupRecentsAnimation();
 
-                // Move the home stack to the front
-                final ActivityRecord homeActivity = mStackSupervisor.getHomeActivity();
-                if (homeActivity == null) {
-                    return;
+                    // Move the home stack to the front
+                    final ActivityRecord homeActivity = mStackSupervisor.getHomeActivity();
+                    if (homeActivity == null) {
+                        return;
+                    }
+
+                    // Restore the launched-behind state
+                    homeActivity.mLaunchTaskBehind = false;
+
+                    if (moveHomeToTop) {
+                        // Bring the home stack to the front
+                        final ActivityStack homeStack = homeActivity.getStack();
+                        homeStack.mNoAnimActivities.add(homeActivity);
+                        homeStack.moveToFront("RecentsAnimation.onAnimationFinished()");
+                    } else {
+                        // Restore the home stack to its previous position
+                        final ActivityDisplay display = homeActivity.getDisplay();
+                        display.moveHomeStackBehindStack(mRestoreHomeBehindStack);
+                    }
+
+                    mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
+                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, false);
+                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
+
+                    // No reason to wait for the pausing activity in this case, as the hiding of
+                    // surfaces needs to be done immediately.
+                    mWindowManager.executeAppTransition();
+                } finally {
+                    mWindowManager.continueSurfaceLayout();
                 }
-
-                // Restore the launched-behind state
-                homeActivity.mLaunchTaskBehind = false;
-
-                if (moveHomeToTop) {
-                    // Bring the home stack to the front
-                    final ActivityStack homeStack = homeActivity.getStack();
-                    homeStack.mNoAnimActivities.add(homeActivity);
-                    homeStack.moveToFront("RecentsAnimation.onAnimationFinished()");
-                } else {
-                    // Restore the home stack to its previous position
-                    final ActivityDisplay display = homeActivity.getDisplay();
-                    display.moveHomeStackBehindStack(mRestoreHomeBehindStack);
-                }
-
-                mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
-                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, false);
-                mStackSupervisor.resumeFocusedStackTopActivityLocked();
             });
         }
     }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index edeee3e..f6bcb25 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -16,11 +16,6 @@
 
 package com.android.server.audio;
 
-import com.android.server.audio.AudioServiceEvents.ForceUseEvent;
-import com.android.server.audio.AudioServiceEvents.PhoneStateEvent;
-import com.android.server.audio.AudioServiceEvents.VolumeEvent;
-import com.android.server.audio.AudioServiceEvents.WiredDevConnectEvent;
-
 import static android.Manifest.permission.REMOTE_AUDIO_PLAYBACK;
 import static android.media.AudioManager.RINGER_MODE_NORMAL;
 import static android.media.AudioManager.RINGER_MODE_SILENT;
@@ -64,14 +59,14 @@
 import android.media.AudioDevicePort;
 import android.media.AudioFocusInfo;
 import android.media.AudioFocusRequest;
-import android.media.AudioSystem;
 import android.media.AudioFormat;
 import android.media.AudioManager;
 import android.media.AudioManagerInternal;
-import android.media.AudioPort;
 import android.media.AudioPlaybackConfiguration;
+import android.media.AudioPort;
 import android.media.AudioRecordingConfiguration;
 import android.media.AudioRoutesInfo;
+import android.media.AudioSystem;
 import android.media.IAudioFocusDispatcher;
 import android.media.IAudioRoutesObserver;
 import android.media.IAudioService;
@@ -80,12 +75,12 @@
 import android.media.IRingtonePlayer;
 import android.media.IVolumeController;
 import android.media.MediaPlayer;
-import android.media.SoundPool;
-import android.media.VolumePolicy;
-import android.media.audiofx.AudioEffect;
 import android.media.MediaPlayer.OnCompletionListener;
 import android.media.MediaPlayer.OnErrorListener;
 import android.media.PlayerBase;
+import android.media.SoundPool;
+import android.media.VolumePolicy;
+import android.media.audiofx.AudioEffect;
 import android.media.audiopolicy.AudioMix;
 import android.media.audiopolicy.AudioPolicy;
 import android.media.audiopolicy.AudioPolicyConfig;
@@ -110,6 +105,7 @@
 import android.os.Vibrator;
 import android.provider.Settings;
 import android.provider.Settings.System;
+import android.service.notification.ZenModeConfig;
 import android.telecom.TelecomManager;
 import android.text.TextUtils;
 import android.util.AndroidRuntimeException;
@@ -129,6 +125,10 @@
 import com.android.server.EventLogTags;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.audio.AudioServiceEvents.ForceUseEvent;
+import com.android.server.audio.AudioServiceEvents.PhoneStateEvent;
+import com.android.server.audio.AudioServiceEvents.VolumeEvent;
+import com.android.server.audio.AudioServiceEvents.WiredDevConnectEvent;
 import com.android.server.pm.UserManagerService;
 
 import org.xmlpull.v1.XmlPullParserException;
@@ -1853,10 +1853,12 @@
         sendVolumeUpdate(streamType, oldIndex, index, flags);
     }
 
-    // No ringer affected streams can be changed in total silence mode except those that
-    // will cause the device to exit total silence mode.
+    // No ringer affected streams can be changed in total silence mode or priority-only
+    // (with alarms/media toggled off) except those that will cause the device to exit
+    // the mode.
     private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) {
-        if (mNm.getZenMode() == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS
+        if ((mNm.getZenMode() == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS
+                || mNm.getZenMode() == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
                 && isStreamMutedByRingerMode(streamTypeAlias)) {
             if (!(((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
                     (streamTypeAlias == getUiSoundsStreamType()))) {
@@ -2381,11 +2383,30 @@
         // Unmute stream if previously muted by ringer mode and ringer mode
         // is RINGER_MODE_NORMAL or stream is not affected by ringer mode.
         int numStreamTypes = AudioSystem.getNumStreamTypes();
+
+        if (mNm == null) {
+            mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+        }
+
+        // in priority only dnd, alarms and media streams can be muted when ringer is not muted
+        boolean isZenPriorityMode = mNm.getZenMode() ==
+                Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        NotificationManager.Policy zenPolicy = mNm.getNotificationPolicy();
+        boolean muteAlarms = isZenPriorityMode && ((zenPolicy.priorityCategories
+                & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0);
+        boolean muteMedia = isZenPriorityMode && ((zenPolicy.priorityCategories
+                & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER) == 0);
+
         final boolean ringerModeMute = mRingerMode == AudioManager.RINGER_MODE_VIBRATE
                 || mRingerMode == AudioManager.RINGER_MODE_SILENT;
+
         for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
             final boolean isMuted = isStreamMutedByRingerMode(streamType);
-            final boolean shouldMute = ringerModeMute && isStreamAffectedByRingerMode(streamType);
+
+            final boolean shouldZenMute = (isAlarm(streamType) && muteAlarms)
+                    || (isMedia(streamType) && muteMedia);
+            final boolean shouldMute = (shouldZenMute || ringerModeMute)
+                    && isStreamAffectedByRingerMode(streamType);
             if (isMuted == shouldMute) continue;
             if (!shouldMute) {
                 // unmute
@@ -2421,6 +2442,19 @@
         }
     }
 
+    private boolean isAlarm(int streamType) {
+        return streamType == AudioSystem.STREAM_ALARM;
+    }
+
+    private boolean isNotificationOrRinger(int streamType) {
+        return streamType == AudioSystem.STREAM_NOTIFICATION
+                || streamType == AudioSystem.STREAM_RING;
+    }
+
+    private boolean isMedia(int streamType) {
+        return streamType == AudioSystem.STREAM_SYSTEM || streamType == AudioSystem.STREAM_MUSIC;
+    }
+
     private void setRingerModeInt(int ringerMode, boolean persist) {
         final boolean change;
         synchronized(mSettingsLock) {
diff --git a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
index 57258a8..f1a806b 100644
--- a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
+++ b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
@@ -219,11 +219,7 @@
 
         for (INetdEventCallback callback : mNetdEventCallbackList) {
             if (callback != null) {
-                // TODO(rickywai): Remove this checking to collect ip in watchlist.
-                if (callback ==
-                        mNetdEventCallbackList[INetdEventCallback.CALLBACK_CALLER_DEVICE_POLICY]) {
-                    callback.onConnectEvent(ipAddr, port, timestamp, uid);
-                }
+                callback.onConnectEvent(ipAddr, port, timestamp, uid);
             }
         }
     }
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index e498666..5a37ee2 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -481,9 +481,9 @@
 
         maybeDeleteLegacyPendingInfoLocked(syncDir);
 
-        mAccountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
-        mStatusFile = new AtomicFile(new File(syncDir, "status.bin"));
-        mStatisticsFile = new AtomicFile(new File(syncDir, "stats.bin"));
+        mAccountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"), "sync-accounts");
+        mStatusFile = new AtomicFile(new File(syncDir, "status.bin"), "sync-status");
+        mStatisticsFile = new AtomicFile(new File(syncDir, "stats.bin"), "sync-stats");
 
         readAccountInfoLocked();
         readStatusLocked();
diff --git a/services/core/java/com/android/server/display/PersistentDataStore.java b/services/core/java/com/android/server/display/PersistentDataStore.java
index cbf46f8..1af03de 100644
--- a/services/core/java/com/android/server/display/PersistentDataStore.java
+++ b/services/core/java/com/android/server/display/PersistentDataStore.java
@@ -771,7 +771,8 @@
         private final AtomicFile mAtomicFile;
 
         public Injector() {
-            mAtomicFile = new AtomicFile(new File("/data/system/display-manager-state.xml"));
+            mAtomicFile = new AtomicFile(new File("/data/system/display-manager-state.xml"),
+                    "display-state");
         }
 
         public InputStream openRead() throws FileNotFoundException {
diff --git a/services/core/java/com/android/server/input/PersistentDataStore.java b/services/core/java/com/android/server/input/PersistentDataStore.java
index f67e0fd..372db41 100644
--- a/services/core/java/com/android/server/input/PersistentDataStore.java
+++ b/services/core/java/com/android/server/input/PersistentDataStore.java
@@ -82,7 +82,8 @@
     private boolean mDirty;
 
     public PersistentDataStore() {
-        mAtomicFile = new AtomicFile(new File("/data/system/input-manager-state.xml"));
+        mAtomicFile = new AtomicFile(new File("/data/system/input-manager-state.xml"),
+                "input-state");
     }
 
     public void saveIfNeeded() {
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index a24a4ac..f4bbf4c 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -29,6 +29,7 @@
 import android.os.Handler;
 import android.os.PersistableBundle;
 import android.os.Process;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.text.format.DateUtils;
 import android.util.ArraySet;
@@ -133,7 +134,7 @@
         File systemDir = new File(dataDir, "system");
         File jobDir = new File(systemDir, "job");
         jobDir.mkdirs();
-        mJobsFile = new AtomicFile(new File(jobDir, "jobs.xml"));
+        mJobsFile = new AtomicFile(new File(jobDir, "jobs.xml"), "jobs");
 
         mJobSet = new JobSet();
 
@@ -361,6 +362,7 @@
             int numSystemJobs = 0;
             int numSyncJobs = 0;
             try {
+                final long startTime = SystemClock.uptimeMillis();
                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
                 XmlSerializer out = new FastXmlSerializer();
                 out.setOutput(baos, StandardCharsets.UTF_8.name());
@@ -393,7 +395,7 @@
                 out.endDocument();
 
                 // Write out to disk in one fell swoop.
-                FileOutputStream fos = mJobsFile.startWrite();
+                FileOutputStream fos = mJobsFile.startWrite(startTime);
                 fos.write(baos.toByteArray());
                 mJobsFile.finishWrite(fos);
                 mDirtyOperations = 0;
diff --git a/services/core/java/com/android/server/media/MediaSession2Record.java b/services/core/java/com/android/server/media/MediaSession2Record.java
index ffddf60..97c7bf6c 100644
--- a/services/core/java/com/android/server/media/MediaSession2Record.java
+++ b/services/core/java/com/android/server/media/MediaSession2Record.java
@@ -16,19 +16,13 @@
 
 package com.android.server.media;
 
-import android.annotation.CallSuper;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.content.Context;
-import android.media.IMediaSession2;
 import android.media.MediaController2;
 import android.media.MediaSession2;
 import android.media.SessionToken2;
-import android.os.Handler;
-import android.os.Looper;
 import android.util.Log;
 import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * Records a {@link MediaSession2} and holds {@link MediaController2}.
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 02df84e..b877184 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -39,7 +39,6 @@
 import android.media.AudioPlaybackConfiguration;
 import android.media.AudioSystem;
 import android.media.IAudioService;
-import android.media.IMediaSession2;
 import android.media.IRemoteVolumeController;
 import android.media.ISessionTokensListener;
 import android.media.MediaLibraryService2;
@@ -470,31 +469,21 @@
                 ServiceInfo serviceInfo = services.get(i).serviceInfo;
                 int uid;
                 try {
+                    // TODO(jaewan): Do this per user.
                     uid = manager.getPackageUid(serviceInfo.packageName,
                             PackageManager.GET_META_DATA);
                 } catch (NameNotFoundException e) {
                     continue;
                 }
-                String id = (serviceInfo.metaData != null) ? serviceInfo.metaData.getString(
-                        MediaSessionService2.SERVICE_META_DATA) : null;
-                // Do basic sanity check
-                // TODO(jaewan): also santity check if it's protected with the system|privileged
-                //               permission
-                boolean conflict = (getSessionRecordLocked(uid, serviceInfo.name, id) != null);
-                if (conflict) {
-                    Log.w(TAG, serviceInfo.packageName + " contains multiple"
-                            + " MediaSessionService2s declared in the manifest with"
-                            + " the same ID=" + id + ". Ignoring "
-                            + serviceInfo.packageName + "/" + serviceInfo.name);
-                } else {
-                    int type = (libraryServices.contains(services.get(i)))
-                            ? SessionToken2.TYPE_LIBRARY_SERVICE
-                            : SessionToken2.TYPE_SESSION_SERVICE;
-                    SessionToken2 token = new SessionToken2(getContext(), uid, type,
-                            serviceInfo.packageName, serviceInfo.name, id, null);
+
+                try {
+                    SessionToken2 token = new SessionToken2(getContext(),
+                            serviceInfo.packageName, serviceInfo.name, uid);
                     MediaSession2Record record = new MediaSession2Record(getContext(),
                             token, mSessionDestroyedListener);
                     mSessions.add(record);
+                } catch (IllegalArgumentException e) {
+                    Log.d(TAG, "Invalid session service", e);
                 }
             }
         }
@@ -1425,6 +1414,16 @@
                     mUserRecords.valueAt(i).dumpLocked(pw, "");
                 }
                 mAudioPlayerStateMonitor.dump(getContext(), pw, "");
+
+                // TODO(jaewan): Remove this debug command before ship.
+                if (args != null && args.length > 0 && "--purge".equals(args[0])) {
+                    mSessions.clear();
+                }
+                pw.println();
+                pw.println("Session2: size=" + mSessions.size());
+                for (int i = 0; i < mSessions.size(); i++) {
+                    pw.println("  " + mSessions.get(i));
+                }
             }
         }
 
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 0e54768..f09de52 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -551,7 +551,7 @@
 
         mSuppressDefaultPolicy = suppressDefaultPolicy;
 
-        mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"));
+        mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"), "net-policy");
 
         mAppOps = context.getSystemService(AppOpsManager.class);
 
diff --git a/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java b/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java
index b78fe4d..f5ba889 100644
--- a/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java
+++ b/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java
@@ -77,7 +77,7 @@
 
     @VisibleForTesting
     protected WatchlistSettings(File xmlFile) {
-        mXmlFile = new AtomicFile(xmlFile);
+        mXmlFile = new AtomicFile(xmlFile, "net-watchlist");
         reloadSettings();
         if (mPrivacySecretKey == null) {
             // Generate a new secret key and save settings
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index cbfa067..727e7ee 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1413,7 +1413,7 @@
                         AppGlobals.getPackageManager()),
                 new ConditionProviders(getContext(), mUserProfiles, AppGlobals.getPackageManager()),
                 null, snoozeHelper, new NotificationUsageStats(getContext()),
-                new AtomicFile(new File(systemDir, "notification_policy.xml")),
+                new AtomicFile(new File(systemDir, "notification_policy.xml"), "notification-policy"),
                 (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE),
                 getGroupHelper());
 
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 2859613..7e3b551 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -129,7 +129,6 @@
         mFiltering = new ZenModeFiltering(mContext);
         mConditions = new ZenModeConditions(this, conditionProviders);
         mServiceConfig = conditionProviders.getConfig();
-
     }
 
     public Looper getLooper() {
@@ -822,7 +821,7 @@
     @VisibleForTesting
     protected void applyRestrictions() {
         final boolean zenPriorityOnly = mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        final boolean zenSilence  = mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
+        final boolean zenSilence = mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
         final boolean zenAlarmsOnly = mZenMode == Global.ZEN_MODE_ALARMS;
 
         // notification restrictions
@@ -838,7 +837,7 @@
         final boolean muteMediaAndSystemSounds = zenPriorityOnly && !mConfig.allowMediaSystemOther;
         // total silence restrictions
         final boolean muteEverything = zenSilence
-                || (zenPriorityOnly && areAllBehaviorSoundsMuted());
+                || (zenPriorityOnly && ZenModeConfig.areAllZenBehaviorSoundsMuted(mConfig));
 
         for (int usage : AudioAttributes.SDK_USAGES) {
             final int suppressionBehavior = AudioAttributes.SUPPRESSIBLE_USAGES.get(usage);
@@ -871,12 +870,6 @@
                 exceptionPackages);
     }
 
-    private boolean areAllBehaviorSoundsMuted() {
-        return !mConfig.allowAlarms  && !mConfig.allowMediaSystemOther && !mConfig.allowReminders
-                && !mConfig.allowCalls && !mConfig.allowMessages && !mConfig.allowEvents
-                && !mConfig.allowRepeatCallers;
-    }
-
     private void applyZenToRingerMode() {
         if (mAudioManager == null) return;
         // force the ringer mode into compliance
@@ -891,6 +884,18 @@
                 }
                 break;
             case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
+                if (ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(mConfig)) {
+                    if (ringerModeInternal != AudioManager.RINGER_MODE_SILENT) {
+                        setPreviousRingerModeSetting(ringerModeInternal);
+                        newRingerModeInternal = AudioManager.RINGER_MODE_SILENT;
+                    }
+                } else {
+                    if (ringerModeInternal == AudioManager.RINGER_MODE_SILENT) {
+                        newRingerModeInternal = getPreviousRingerModeSetting();
+                        setPreviousRingerModeSetting(null);
+                    }
+                }
+                break;
             case Global.ZEN_MODE_OFF:
                 if (ringerModeInternal == AudioManager.RINGER_MODE_SILENT) {
                     newRingerModeInternal = getPreviousRingerModeSetting();
@@ -999,8 +1004,7 @@
             switch (ringerModeNew) {
                 case AudioManager.RINGER_MODE_SILENT:
                     if (isChange && policy.doNotDisturbWhenSilent) {
-                        if (mZenMode != Global.ZEN_MODE_NO_INTERRUPTIONS
-                                && mZenMode != Global.ZEN_MODE_ALARMS) {
+                        if (mZenMode == Global.ZEN_MODE_OFF) {
                             newZen = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
                         }
                         setPreviousRingerModeSetting(ringerModeOld);
@@ -1010,7 +1014,10 @@
                 case AudioManager.RINGER_MODE_NORMAL:
                     if (isChange && ringerModeOld == AudioManager.RINGER_MODE_SILENT
                             && (mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS
-                                    || mZenMode == Global.ZEN_MODE_ALARMS)) {
+                            || mZenMode == Global.ZEN_MODE_ALARMS
+                            || (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
+                            && ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(
+                                    mConfig)))) {
                         newZen = Global.ZEN_MODE_OFF;
                     } else if (mZenMode != Global.ZEN_MODE_OFF) {
                         ringerModeExternalOut = AudioManager.RINGER_MODE_SILENT;
@@ -1078,10 +1085,24 @@
                        (1 << AudioSystem.STREAM_NOTIFICATION) |
                        (1 << AudioSystem.STREAM_SYSTEM);
 
-            // alarm and music streams are only affected by ringer mode when in total silence
             if (mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS) {
+                // alarm and music streams affected by ringer mode when in total silence
                 streams |= (1 << AudioSystem.STREAM_ALARM) |
                            (1 << AudioSystem.STREAM_MUSIC);
+            } else if (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
+                // alarm and music streams affected by ringer mode when in priority only with
+                // media and alarms not allowed to bypass dnd
+                if (!mConfig.allowMediaSystemOther) {
+                    streams |= (1 << AudioSystem.STREAM_MUSIC);
+                } else {
+                    streams &= ~(1 << AudioSystem.STREAM_MUSIC);
+                }
+
+                if (!mConfig.allowAlarms) {
+                    streams |= (1 << AudioSystem.STREAM_ALARM);
+                } else {
+                    streams &= ~(1 << AudioSystem.STREAM_ALARM);
+                }
             } else {
                 streams &= ~((1 << AudioSystem.STREAM_ALARM) |
                              (1 << AudioSystem.STREAM_MUSIC));
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 2041de6..4bc4a7e 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -228,7 +228,7 @@
             @NonNull final Installer installer) {
         super(context);
         mSettingsFile =
-            new AtomicFile(new File(Environment.getDataSystemDirectory(), "overlays.xml"));
+            new AtomicFile(new File(Environment.getDataSystemDirectory(), "overlays.xml"), "overlays");
         mPackageManager = new PackageManagerHelper();
         mUserManager = UserManagerService.getInstance();
         IdmapManager im = new IdmapManager(installer);
diff --git a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
index b5ddf8c..6d6c960 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
@@ -43,6 +43,7 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.NoSuchElementException;
 import java.util.concurrent.TimeoutException;
@@ -84,8 +85,8 @@
         mIntent = new Intent(action).setComponent(componentName);
     }
 
-    public final List<InstantAppResolveInfo> getInstantAppResolveInfoList(int hashPrefix[],
-            String token) throws ConnectionException {
+    public final List<InstantAppResolveInfo> getInstantAppResolveInfoList(Intent sanitizedIntent,
+            int hashPrefix[], String token) throws ConnectionException {
         throwIfCalledOnMainThread();
         IInstantAppResolver target = null;
         try {
@@ -98,7 +99,7 @@
             }
             try {
                 return mGetEphemeralResolveInfoCaller
-                        .getEphemeralResolveInfoList(target, hashPrefix, token);
+                        .getEphemeralResolveInfoList(target, sanitizedIntent, hashPrefix, token);
             } catch (TimeoutException e) {
                 throw new ConnectionException(ConnectionException.FAILURE_CALL);
             } catch (RemoteException ignore) {
@@ -111,26 +112,22 @@
         return null;
     }
 
-    public final void getInstantAppIntentFilterList(int hashPrefix[], String token,
-            String hostName, PhaseTwoCallback callback, Handler callbackHandler,
-            final long startTime) throws ConnectionException {
+    public final void getInstantAppIntentFilterList(Intent sanitizedIntent, int hashPrefix[],
+            String token, PhaseTwoCallback callback, Handler callbackHandler, final long startTime)
+            throws ConnectionException {
         final IRemoteCallback remoteCallback = new IRemoteCallback.Stub() {
             @Override
             public void sendResult(Bundle data) throws RemoteException {
                 final ArrayList<InstantAppResolveInfo> resolveList =
                         data.getParcelableArrayList(
                                 InstantAppResolverService.EXTRA_RESOLVE_INFO);
-                callbackHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        callback.onPhaseTwoResolved(resolveList, startTime);
-                    }
-                });
+                callbackHandler.post(() -> callback.onPhaseTwoResolved(resolveList, startTime));
             }
         };
         try {
             getRemoteInstanceLazy(token)
-                    .getInstantAppIntentFilterList(hashPrefix, token, hostName, remoteCallback);
+                    .getInstantAppIntentFilterList(sanitizedIntent, hashPrefix, token,
+                            remoteCallback);
         } catch (TimeoutException e) {
             throw new ConnectionException(ConnectionException.FAILURE_BIND);
         } catch (InterruptedException e) {
@@ -337,10 +334,11 @@
         }
 
         public List<InstantAppResolveInfo> getEphemeralResolveInfoList(
-                IInstantAppResolver target, int hashPrefix[], String token)
+                IInstantAppResolver target, Intent sanitizedIntent,  int hashPrefix[], String token)
                         throws RemoteException, TimeoutException {
             final int sequence = onBeforeRemoteCall();
-            target.getInstantAppResolveInfoList(hashPrefix, token, sequence, mCallback);
+            target.getInstantAppResolveInfoList(sanitizedIntent, hashPrefix, token, sequence,
+                    mCallback);
             return getResultTimed(sequence);
         }
     }
diff --git a/services/core/java/com/android/server/pm/InstantAppResolver.java b/services/core/java/com/android/server/pm/InstantAppResolver.java
index 30072d4..55212cc 100644
--- a/services/core/java/com/android/server/pm/InstantAppResolver.java
+++ b/services/core/java/com/android/server/pm/InstantAppResolver.java
@@ -40,11 +40,14 @@
 import android.content.pm.InstantAppResolveInfo;
 import android.content.pm.InstantAppResolveInfo.InstantAppDigest;
 import android.metrics.LogMaker;
+import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.RemoteException;
+import android.text.TextUtils;
 import android.util.Log;
+import android.util.Slog;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
@@ -53,8 +56,12 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 import java.util.UUID;
 
 /** @hide */
@@ -79,6 +86,7 @@
     public @interface ResolutionStatus {}
 
     private static MetricsLogger sMetricsLogger;
+
     private static MetricsLogger getLogger() {
         if (sMetricsLogger == null) {
             sMetricsLogger = new MetricsLogger();
@@ -86,26 +94,49 @@
         return sMetricsLogger;
     }
 
-    public static AuxiliaryResolveInfo doInstantAppResolutionPhaseOne(Context context,
+    /**
+     * Returns an intent with potential PII removed from the original intent. Fields removed
+     * include extras and the host + path of the data, if defined.
+     */
+    public static Intent sanitizeIntent(Intent origIntent) {
+        final Intent sanitizedIntent;
+        sanitizedIntent = new Intent(origIntent.getAction());
+        Set<String> categories = origIntent.getCategories();
+        if (categories != null) {
+            for (String category : categories) {
+                sanitizedIntent.addCategory(category);
+            }
+        }
+        Uri sanitizedUri = origIntent.getData() == null
+                ? null
+                : Uri.fromParts(origIntent.getScheme(), "", "");
+        sanitizedIntent.setDataAndType(sanitizedUri, origIntent.getType());
+        sanitizedIntent.addFlags(origIntent.getFlags());
+        sanitizedIntent.setPackage(origIntent.getPackage());
+        return sanitizedIntent;
+    }
+
+    public static AuxiliaryResolveInfo doInstantAppResolutionPhaseOne(
             EphemeralResolverConnection connection, InstantAppRequest requestObj) {
         final long startTime = System.currentTimeMillis();
         final String token = UUID.randomUUID().toString();
         if (DEBUG_EPHEMERAL) {
             Log.d(TAG, "[" + token + "] Phase1; resolving");
         }
-        final Intent intent = requestObj.origIntent;
-        final InstantAppDigest digest =
-                new InstantAppDigest(intent.getData().getHost(), 5 /*maxDigests*/);
+        final Intent origIntent = requestObj.origIntent;
+        final Intent sanitizedIntent = sanitizeIntent(origIntent);
+
+        final InstantAppDigest digest = getInstantAppDigest(origIntent);
         final int[] shaPrefix = digest.getDigestPrefix();
         AuxiliaryResolveInfo resolveInfo = null;
         @ResolutionStatus int resolutionStatus = RESOLUTION_SUCCESS;
         try {
             final List<InstantAppResolveInfo> instantAppResolveInfoList =
-                    connection.getInstantAppResolveInfoList(shaPrefix, token);
+                    connection.getInstantAppResolveInfoList(sanitizedIntent, shaPrefix, token);
             if (instantAppResolveInfoList != null && instantAppResolveInfoList.size() > 0) {
                 resolveInfo = InstantAppResolver.filterInstantAppIntent(
-                        instantAppResolveInfoList, intent, requestObj.resolvedType,
-                        requestObj.userId, intent.getPackage(), digest, token);
+                        instantAppResolveInfoList, origIntent, requestObj.resolvedType,
+                        requestObj.userId, origIntent.getPackage(), digest, token);
             }
         } catch (ConnectionException e) {
             if (e.failure == ConnectionException.FAILURE_BIND) {
@@ -135,6 +166,12 @@
         return resolveInfo;
     }
 
+    private static InstantAppDigest getInstantAppDigest(Intent origIntent) {
+        return origIntent.getData() != null && !TextUtils.isEmpty(origIntent.getData().getHost())
+                ? new InstantAppDigest(origIntent.getData().getHost(), 5 /*maxDigests*/)
+                : InstantAppDigest.UNDEFINED;
+    }
+
     public static void doInstantAppResolutionPhaseTwo(Context context,
             EphemeralResolverConnection connection, InstantAppRequest requestObj,
             ActivityInfo instantAppInstaller, Handler callbackHandler) {
@@ -143,73 +180,53 @@
         if (DEBUG_EPHEMERAL) {
             Log.d(TAG, "[" + token + "] Phase2; resolving");
         }
-        final Intent intent = requestObj.origIntent;
-        final String hostName = intent.getData().getHost();
-        final InstantAppDigest digest = new InstantAppDigest(hostName, 5 /*maxDigests*/);
+        final Intent origIntent = requestObj.origIntent;
+        final Intent sanitizedIntent = sanitizeIntent(origIntent);
+        final InstantAppDigest digest = getInstantAppDigest(origIntent);
         final int[] shaPrefix = digest.getDigestPrefix();
 
         final PhaseTwoCallback callback = new PhaseTwoCallback() {
             @Override
             void onPhaseTwoResolved(List<InstantAppResolveInfo> instantAppResolveInfoList,
                     long startTime) {
-                final String packageName;
-                final String splitName;
-                final long versionCode;
                 final Intent failureIntent;
-                final Bundle extras;
                 if (instantAppResolveInfoList != null && instantAppResolveInfoList.size() > 0) {
                     final AuxiliaryResolveInfo instantAppIntentInfo =
                             InstantAppResolver.filterInstantAppIntent(
-                                    instantAppResolveInfoList, intent, null /*resolvedType*/,
-                                    0 /*userId*/, intent.getPackage(), digest, token);
-                    if (instantAppIntentInfo != null
-                            && instantAppIntentInfo.resolveInfo != null) {
-                        packageName = instantAppIntentInfo.resolveInfo.getPackageName();
-                        splitName = instantAppIntentInfo.splitName;
-                        versionCode = instantAppIntentInfo.resolveInfo.getVersionCode();
+                                    instantAppResolveInfoList, origIntent, null /*resolvedType*/,
+                                    0 /*userId*/, origIntent.getPackage(), digest, token);
+                    if (instantAppIntentInfo != null) {
                         failureIntent = instantAppIntentInfo.failureIntent;
-                        extras = instantAppIntentInfo.resolveInfo.getExtras();
                     } else {
-                        packageName = null;
-                        splitName = null;
-                        versionCode = -1;
                         failureIntent = null;
-                        extras = null;
                     }
                 } else {
-                    packageName = null;
-                    splitName = null;
-                    versionCode = -1;
                     failureIntent = null;
-                    extras = null;
                 }
                 final Intent installerIntent = buildEphemeralInstallerIntent(
-                        Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE,
                         requestObj.origIntent,
+                        sanitizedIntent,
                         failureIntent,
                         requestObj.callingPackage,
                         requestObj.verificationBundle,
                         requestObj.resolvedType,
                         requestObj.userId,
-                        packageName,
-                        splitName,
                         requestObj.responseObj.installFailureActivity,
-                        versionCode,
                         token,
-                        extras,
-                        false /*needsPhaseTwo*/);
+                        false /*needsPhaseTwo*/,
+                        requestObj.responseObj.filters);
                 installerIntent.setComponent(new ComponentName(
                         instantAppInstaller.packageName, instantAppInstaller.name));
 
                 logMetrics(ACTION_INSTANT_APP_RESOLUTION_PHASE_TWO, startTime, token,
-                        packageName != null ? RESOLUTION_SUCCESS : RESOLUTION_FAILURE);
+                        requestObj.responseObj.filters != null ? RESOLUTION_SUCCESS : RESOLUTION_FAILURE);
 
                 context.startActivity(installerIntent);
             }
         };
         try {
-            connection.getInstantAppIntentFilterList(
-                    shaPrefix, token, hostName, callback, callbackHandler, startTime);
+            connection.getInstantAppIntentFilterList(sanitizedIntent, shaPrefix, token, callback,
+                    callbackHandler, startTime);
         } catch (ConnectionException e) {
             @ResolutionStatus int resolutionStatus = RESOLUTION_FAILURE;
             if (e.failure == ConnectionException.FAILURE_BIND) {
@@ -231,23 +248,20 @@
      * Builds and returns an intent to launch the instant installer.
      */
     public static Intent buildEphemeralInstallerIntent(
-            @NonNull String action,
             @NonNull Intent origIntent,
-            @NonNull Intent failureIntent,
+            @NonNull Intent sanitizedIntent,
+            @Nullable Intent failureIntent,
             @NonNull String callingPackage,
             @Nullable Bundle verificationBundle,
             @NonNull String resolvedType,
             int userId,
-            @NonNull String instantAppPackageName,
-            @Nullable String instantAppSplitName,
             @Nullable ComponentName installFailureActivity,
-            long versionCode,
             @Nullable String token,
-            @Nullable Bundle extras,
-            boolean needsPhaseTwo) {
+            boolean needsPhaseTwo,
+            List<AuxiliaryResolveInfo.AuxiliaryFilter> filters) {
         // Construct the intent that launches the instant installer
         int flags = origIntent.getFlags();
-        final Intent intent = new Intent(action);
+        final Intent intent = new Intent();
         intent.setFlags(flags
                 | Intent.FLAG_ACTIVITY_NEW_TASK
                 | Intent.FLAG_ACTIVITY_CLEAR_TASK
@@ -260,20 +274,23 @@
             intent.putExtra(Intent.EXTRA_EPHEMERAL_HOSTNAME, origIntent.getData().getHost());
         }
         intent.putExtra(Intent.EXTRA_INSTANT_APP_ACTION, origIntent.getAction());
-        if (extras != null) {
-            intent.putExtra(Intent.EXTRA_INSTANT_APP_EXTRAS, extras);
-        }
+        intent.putExtra(Intent.EXTRA_INTENT, sanitizedIntent);
 
-        // We have all of the data we need; just start the installer without a second phase
-        if (!needsPhaseTwo) {
-            // Intent that is launched if the package couldn't be installed for any reason.
+        if (needsPhaseTwo) {
+            intent.setAction(Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE);
+        } else {
+            // We have all of the data we need; just start the installer without a second phase
             if (failureIntent != null || installFailureActivity != null) {
+                // Intent that is launched if the package couldn't be installed for any reason.
                 try {
                     final Intent onFailureIntent;
                     if (installFailureActivity != null) {
                         onFailureIntent = new Intent();
                         onFailureIntent.setComponent(installFailureActivity);
-                        onFailureIntent.putExtra(Intent.EXTRA_SPLIT_NAME, instantAppSplitName);
+                        if (filters != null && filters.size() == 1) {
+                            onFailureIntent.putExtra(Intent.EXTRA_SPLIT_NAME,
+                                    filters.get(0).splitName);
+                        }
                         onFailureIntent.putExtra(Intent.EXTRA_INTENT, origIntent);
                     } else {
                         onFailureIntent = failureIntent;
@@ -309,17 +326,35 @@
                 intent.putExtra(Intent.EXTRA_EPHEMERAL_SUCCESS,
                         new IntentSender(successIntentTarget));
             } catch (RemoteException ignore) { /* ignore; same process */ }
-
-            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, instantAppPackageName);
-            intent.putExtra(Intent.EXTRA_SPLIT_NAME, instantAppSplitName);
-            intent.putExtra(Intent.EXTRA_VERSION_CODE, (int) (versionCode & 0x7fffffff));
-            intent.putExtra(Intent.EXTRA_LONG_VERSION_CODE, versionCode);
-            intent.putExtra(Intent.EXTRA_CALLING_PACKAGE, callingPackage);
             if (verificationBundle != null) {
                 intent.putExtra(Intent.EXTRA_VERIFICATION_BUNDLE, verificationBundle);
             }
-        }
+            intent.putExtra(Intent.EXTRA_CALLING_PACKAGE, callingPackage);
 
+            if (filters != null) {
+                Bundle resolvableFilters[] = new Bundle[filters.size()];
+                for (int i = 0, max = filters.size(); i < max; i++) {
+                    Bundle resolvableFilter = new Bundle();
+                    AuxiliaryResolveInfo.AuxiliaryFilter filter = filters.get(i);
+                    resolvableFilter.putBoolean(Intent.EXTRA_UNKNOWN_INSTANT_APP,
+                            filter.resolveInfo != null
+                                    && filter.resolveInfo.shouldLetInstallerDecide());
+                    resolvableFilter.putString(Intent.EXTRA_PACKAGE_NAME, filter.packageName);
+                    resolvableFilter.putString(Intent.EXTRA_SPLIT_NAME, filter.splitName);
+                    resolvableFilter.putLong(Intent.EXTRA_LONG_VERSION_CODE, filter.versionCode);
+                    resolvableFilter.putBundle(Intent.EXTRA_INSTANT_APP_EXTRAS, filter.extras);
+                    resolvableFilters[i] = resolvableFilter;
+                    if (i == 0) {
+                        // for backwards compat, always set the first result on the intent and add
+                        // the int version code
+                        intent.putExtras(resolvableFilter);
+                        intent.putExtra(Intent.EXTRA_VERSION_CODE, (int) filter.versionCode);
+                    }
+                }
+                intent.putExtra(Intent.EXTRA_INSTANT_APP_BUNDLES, resolvableFilters);
+            }
+            intent.setAction(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
+        }
         return intent;
     }
 
@@ -330,69 +365,134 @@
         final int[] shaPrefix = digest.getDigestPrefix();
         final byte[][] digestBytes = digest.getDigestBytes();
         final Intent failureIntent = new Intent(origIntent);
+        boolean requiresSecondPhase = false;
         failureIntent.setFlags(failureIntent.getFlags() | Intent.FLAG_IGNORE_EPHEMERAL);
         failureIntent.setLaunchToken(token);
-        // Go in reverse order so we match the narrowest scope first.
-        for (int i = shaPrefix.length - 1; i >= 0 ; --i) {
-            for (InstantAppResolveInfo instantAppInfo : instantAppResolveInfoList) {
-                if (!Arrays.equals(digestBytes[i], instantAppInfo.getDigestBytes())) {
+        ArrayList<AuxiliaryResolveInfo.AuxiliaryFilter> filters = null;
+        boolean isWebIntent = origIntent.isBrowsableWebIntent();
+        for (InstantAppResolveInfo instantAppResolveInfo : instantAppResolveInfoList) {
+            if (shaPrefix.length > 0 && instantAppResolveInfo.shouldLetInstallerDecide()) {
+                Slog.e(TAG, "InstantAppResolveInfo with mShouldLetInstallerDecide=true when digest"
+                        + " provided; ignoring");
+                continue;
+            }
+            byte[] filterDigestBytes = instantAppResolveInfo.getDigestBytes();
+            // Only include matching digests if we have a prefix and we're either dealing with a
+            // web intent or the resolveInfo specifies digest details.
+            if (shaPrefix.length > 0 && (isWebIntent || filterDigestBytes.length > 0)) {
+                boolean matchFound = false;
+                // Go in reverse order so we match the narrowest scope first.
+                for (int i = shaPrefix.length - 1; i >= 0; --i) {
+                    if (Arrays.equals(digestBytes[i], filterDigestBytes)) {
+                        matchFound = true;
+                        break;
+                    }
+                }
+                if (!matchFound) {
                     continue;
                 }
-                if (packageName != null
-                        && !packageName.equals(instantAppInfo.getPackageName())) {
-                    continue;
+            }
+            // We matched a resolve info; resolve the filters to see if anything matches completely.
+            List<AuxiliaryResolveInfo.AuxiliaryFilter> matchFilters = computeResolveFilters(
+                    origIntent, resolvedType, userId, packageName, token, instantAppResolveInfo);
+            if (matchFilters != null) {
+                if (matchFilters.isEmpty()) {
+                    requiresSecondPhase = true;
                 }
-                final List<InstantAppIntentFilter> instantAppFilters =
-                        instantAppInfo.getIntentFilters();
-                // No filters; we need to start phase two
-                if (instantAppFilters == null || instantAppFilters.isEmpty()) {
-                    if (DEBUG_EPHEMERAL) {
-                        Log.d(TAG, "No app filters; go to phase 2");
-                    }
-                    return new AuxiliaryResolveInfo(instantAppInfo,
-                            new IntentFilter(Intent.ACTION_VIEW) /*intentFilter*/,
-                            null /*splitName*/, token, true /*needsPhase2*/,
-                            null /*failureIntent*/);
-                }
-                // We have a domain match; resolve the filters to see if anything matches.
-                final PackageManagerService.EphemeralIntentResolver instantAppResolver =
-                        new PackageManagerService.EphemeralIntentResolver();
-                for (int j = instantAppFilters.size() - 1; j >= 0; --j) {
-                    final InstantAppIntentFilter instantAppFilter = instantAppFilters.get(j);
-                    final List<IntentFilter> splitFilters = instantAppFilter.getFilters();
-                    if (splitFilters == null || splitFilters.isEmpty()) {
-                        continue;
-                    }
-                    for (int k = splitFilters.size() - 1; k >= 0; --k) {
-                        final AuxiliaryResolveInfo intentInfo =
-                                new AuxiliaryResolveInfo(instantAppInfo,
-                                        splitFilters.get(k), instantAppFilter.getSplitName(),
-                                        token, false /*needsPhase2*/, failureIntent);
-                        instantAppResolver.addFilter(intentInfo);
-                    }
-                }
-                List<AuxiliaryResolveInfo> matchedResolveInfoList = instantAppResolver.queryIntent(
-                        origIntent, resolvedType, false /*defaultOnly*/, userId);
-                if (!matchedResolveInfoList.isEmpty()) {
-                    if (DEBUG_EPHEMERAL) {
-                        final AuxiliaryResolveInfo info = matchedResolveInfoList.get(0);
-                        Log.d(TAG, "[" + token + "] Found match;"
-                                + " package: " + info.packageName
-                                + ", split: " + info.splitName
-                                + ", versionCode: " + info.versionCode);
-                    }
-                    return matchedResolveInfoList.get(0);
-                } else if (DEBUG_EPHEMERAL) {
-                    Log.d(TAG, "[" + token + "] No matches found"
-                            + " package: " + instantAppInfo.getPackageName()
-                            + ", versionCode: " + instantAppInfo.getVersionCode());
+                if (filters == null) {
+                    filters = new ArrayList<>(matchFilters);
+                } else {
+                    filters.addAll(matchFilters);
                 }
             }
         }
+        if (filters != null && !filters.isEmpty()) {
+            return new AuxiliaryResolveInfo(token, requiresSecondPhase, failureIntent, filters);
+        }
         // Hash or filter mis-match; no instant apps for this domain.
         return null;
     }
 
+    /**
+     * Returns one of three states: <p/>
+     * <ul>
+     *     <li>{@code null} if there are no matches will not be; resolution is unnecessary.</li>
+     *     <li>An empty list signifying that a 2nd phase of resolution is required.</li>
+     *     <li>A populated list meaning that matches were found and should be sent directly to the
+     *     installer</li>
+     * </ul>
+     *
+     */
+    private static List<AuxiliaryResolveInfo.AuxiliaryFilter> computeResolveFilters(
+            Intent origIntent, String resolvedType, int userId, String packageName, String token,
+            InstantAppResolveInfo instantAppInfo) {
+        if (instantAppInfo.shouldLetInstallerDecide()) {
+            return Collections.singletonList(
+                    new AuxiliaryResolveInfo.AuxiliaryFilter(
+                            instantAppInfo, null /* splitName */,
+                            instantAppInfo.getExtras()));
+        }
+        if (packageName != null
+                && !packageName.equals(instantAppInfo.getPackageName())) {
+            return null;
+        }
+        final List<InstantAppIntentFilter> instantAppFilters =
+                instantAppInfo.getIntentFilters();
+        if (instantAppFilters == null || instantAppFilters.isEmpty()) {
+            // No filters on web intent; no matches, 2nd phase unnecessary.
+            if (origIntent.isBrowsableWebIntent()) {
+                return null;
+            }
+            // No filters; we need to start phase two
+            if (DEBUG_EPHEMERAL) {
+                Log.d(TAG, "No app filters; go to phase 2");
+            }
+            return Collections.emptyList();
+        }
+        final PackageManagerService.EphemeralIntentResolver instantAppResolver =
+                new PackageManagerService.EphemeralIntentResolver();
+        for (int j = instantAppFilters.size() - 1; j >= 0; --j) {
+            final InstantAppIntentFilter instantAppFilter = instantAppFilters.get(j);
+            final List<IntentFilter> splitFilters = instantAppFilter.getFilters();
+            if (splitFilters == null || splitFilters.isEmpty()) {
+                continue;
+            }
+            for (int k = splitFilters.size() - 1; k >= 0; --k) {
+                IntentFilter filter = splitFilters.get(k);
+                Iterator<IntentFilter.AuthorityEntry> authorities =
+                        filter.authoritiesIterator();
+                // ignore http/s-only filters.
+                if ((authorities == null || !authorities.hasNext())
+                        && (filter.hasDataScheme("http") || filter.hasDataScheme("https"))
+                        && filter.hasAction(Intent.ACTION_VIEW)
+                        && filter.hasCategory(Intent.CATEGORY_BROWSABLE)) {
+                    continue;
+                }
+                instantAppResolver.addFilter(
+                        new AuxiliaryResolveInfo.AuxiliaryFilter(
+                                filter,
+                                instantAppInfo,
+                                instantAppFilter.getSplitName(),
+                                instantAppInfo.getExtras()
+                        ));
+            }
+        }
+        List<AuxiliaryResolveInfo.AuxiliaryFilter> matchedResolveInfoList =
+                instantAppResolver.queryIntent(
+                        origIntent, resolvedType, false /*defaultOnly*/, userId);
+        if (!matchedResolveInfoList.isEmpty()) {
+            if (DEBUG_EPHEMERAL) {
+                Log.d(TAG, "[" + token + "] Found match(es); " + matchedResolveInfoList);
+            }
+            return matchedResolveInfoList;
+        } else if (DEBUG_EPHEMERAL) {
+            Log.d(TAG, "[" + token + "] No matches found"
+                    + " package: " + instantAppInfo.getPackageName()
+                    + ", versionCode: " + instantAppInfo.getVersionCode());
+        }
+        return null;
+    }
+
     private static void logMetrics(int action, long startTime, String token,
             @ResolutionStatus int status) {
         final LogMaker logMaker = new LogMaker(action)
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 16fae99..59f9dae 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -58,6 +58,7 @@
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.SELinux;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.StorageManager;
@@ -193,7 +194,8 @@
         mCallbacks = new Callbacks(mInstallThread.getLooper());
 
         mSessionsFile = new AtomicFile(
-                new File(Environment.getDataSystemDirectory(), "install_sessions.xml"));
+                new File(Environment.getDataSystemDirectory(), "install_sessions.xml"),
+                "package-session");
         mSessionsDir = new File(Environment.getDataSystemDirectory(), "install_sessions");
         mSessionsDir.mkdirs();
     }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 3049e98..fdb157e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3595,24 +3595,35 @@
     }
 
     private @Nullable ActivityInfo getInstantAppInstallerLPr() {
-        final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
-        intent.addCategory(Intent.CATEGORY_DEFAULT);
-        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
+        String[] orderedActions = Build.IS_ENG
+                ? new String[]{
+                        Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE + "_TEST",
+                        Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE,
+                        Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE}
+                : new String[]{
+                        Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE,
+                        Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE};
 
         final int resolveFlags =
                 MATCH_DIRECT_BOOT_AWARE
-                | MATCH_DIRECT_BOOT_UNAWARE
-                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
-        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
-                resolveFlags, UserHandle.USER_SYSTEM);
-        // temporarily look for the old action
-        if (matches.isEmpty()) {
-            if (DEBUG_EPHEMERAL) {
-                Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
-            }
-            intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
+                        | MATCH_DIRECT_BOOT_UNAWARE
+                        | Intent.FLAG_IGNORE_EPHEMERAL
+                        | (!Build.IS_ENG ? MATCH_SYSTEM_ONLY : 0);
+        final Intent intent = new Intent();
+        intent.addCategory(Intent.CATEGORY_DEFAULT);
+        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
+        List<ResolveInfo> matches = null;
+        for (String action : orderedActions) {
+            intent.setAction(action);
             matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
                     resolveFlags, UserHandle.USER_SYSTEM);
+            if (matches.isEmpty()) {
+                if (DEBUG_EPHEMERAL) {
+                    Slog.d(TAG, "Instant App installer not found with " + action);
+                }
+            } else {
+                break;
+            }
         }
         Iterator<ResolveInfo> iter = matches.iterator();
         while (iter.hasNext()) {
@@ -3620,7 +3631,8 @@
             final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
             if (ps != null) {
                 final PermissionsState permissionsState = ps.getPermissionsState();
-                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
+                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)
+                        || Build.IS_ENG) {
                     continue;
                 }
             }
@@ -4779,10 +4791,7 @@
             flags |= PackageManager.MATCH_INSTANT;
         } else {
             final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
-            final boolean allowMatchInstant =
-                    (wantInstantApps
-                            && Intent.ACTION_VIEW.equals(intent.getAction())
-                            && hasWebURI(intent))
+            final boolean allowMatchInstant = wantInstantApps
                     || (wantMatchInstant && canViewInstantApps(callingUid, userId));
             flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
                     | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
@@ -5972,8 +5981,14 @@
         if (!skipPackageCheck && intent.getPackage() != null) {
             return false;
         }
-        final boolean isWebUri = hasWebURI(intent);
-        if (!isWebUri || intent.getData().getHost() == null) {
+        if (!intent.isBrowsableWebIntent()) {
+            // for non web intents, we should not resolve externally if an app already exists to
+            // handle it or if the caller didn't explicitly request it.
+            if ((resolvedActivities != null && resolvedActivities.size() != 0)
+                    || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) == 0) {
+                return false;
+            }
+        } else if (intent.getData() == null) {
             return false;
         }
         // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
@@ -6371,7 +6386,7 @@
                 if (matches.get(i).getTargetUserId() == targetUserId) return true;
             }
         }
-        if (hasWebURI(intent)) {
+        if (intent.hasWebURI()) {
             // cross-profile app linking works only towards the parent.
             final int callingUid = Binder.getCallingUid();
             final UserInfo parent = getProfileParent(sourceUserId);
@@ -6546,7 +6561,7 @@
                         sortResult = true;
                     }
                 }
-                if (hasWebURI(intent)) {
+                if (intent.hasWebURI()) {
                     CrossProfileDomainInfo xpDomainInfo = null;
                     final UserInfo parent = getProfileParent(userId);
                     if (parent != null) {
@@ -6632,7 +6647,6 @@
                 if (ps.getInstantApp(userId)) {
                     final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
                     final int status = (int)(packedStatus >> 32);
-                    final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
                     if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
                         // there's a local instant application installed, but, the user has
                         // chosen to never use it; skip resolution and don't acknowledge
@@ -6664,9 +6678,8 @@
                         null /*responseObj*/, intent /*origIntent*/, resolvedType,
                         null /*callingPackage*/, userId, null /*verificationBundle*/,
                         resolveForStart);
-                auxiliaryResponse =
-                        InstantAppResolver.doInstantAppResolutionPhaseOne(
-                                mContext, mInstantAppResolverConnection, requestObject);
+                auxiliaryResponse = InstantAppResolver.doInstantAppResolutionPhaseOne(
+                        mInstantAppResolverConnection, requestObject);
                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
             } else {
                 // we have an instant application locally, but, we can't admit that since
@@ -6675,35 +6688,40 @@
                 // instant application available externally. when it comes time to start
                 // the instant application, we'll do the right thing.
                 final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
-                auxiliaryResponse = new AuxiliaryResolveInfo(
-                        ai.packageName, null /*splitName*/, null /*failureActivity*/,
-                        ai.versionCode, null /*failureIntent*/);
+                auxiliaryResponse = new AuxiliaryResolveInfo(null /* failureActivity */,
+                                        ai.packageName, ai.versionCode, null /* splitName */);
             }
         }
-        if (auxiliaryResponse != null) {
-            if (DEBUG_EPHEMERAL) {
-                Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
-            }
-            final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
-            final PackageSetting ps =
-                    mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
-            if (ps != null) {
-                ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
-                        mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
-                ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
-                ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
-                // make sure this resolver is the default
-                ephemeralInstaller.isDefault = true;
-                ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
-                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
-                // add a non-generic filter
-                ephemeralInstaller.filter = new IntentFilter(intent.getAction());
-                ephemeralInstaller.filter.addDataPath(
-                        intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
-                ephemeralInstaller.isInstantAppAvailable = true;
-                result.add(ephemeralInstaller);
-            }
+        if (intent.isBrowsableWebIntent() && auxiliaryResponse == null) {
+            return result;
         }
+        final PackageSetting ps = mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
+        if (ps == null) {
+            return result;
+        }
+        final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
+        ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
+                mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
+        ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
+                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
+        // add a non-generic filter
+        ephemeralInstaller.filter = new IntentFilter();
+        if (intent.getAction() != null) {
+            ephemeralInstaller.filter.addAction(intent.getAction());
+        }
+        if (intent.getData() != null && intent.getData().getPath() != null) {
+            ephemeralInstaller.filter.addDataPath(
+                    intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
+        }
+        ephemeralInstaller.isInstantAppAvailable = true;
+        // make sure this resolver is the default
+        ephemeralInstaller.isDefault = true;
+        ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
+        if (DEBUG_EPHEMERAL) {
+            Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
+        }
+
+        result.add(ephemeralInstaller);
         return result;
     }
 
@@ -6818,10 +6836,11 @@
             final ResolveInfo info = resolveInfos.get(i);
             // allow activities that are defined in the provided package
             if (allowDynamicSplits
+                    && info.activityInfo != null
                     && info.activityInfo.splitName != null
                     && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
                             info.activityInfo.splitName)) {
-                if (mInstantAppInstallerInfo == null) {
+                if (mInstantAppInstallerActivity == null) {
                     if (DEBUG_INSTALL) {
                         Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
                     }
@@ -6833,14 +6852,15 @@
                 if (DEBUG_INSTALL) {
                     Slog.v(TAG, "Adding installer to the ResolveInfo list");
                 }
-                final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
+                final ResolveInfo installerInfo = new ResolveInfo(
+                        mInstantAppInstallerInfo);
                 final ComponentName installFailureActivity = findInstallFailureActivity(
                         info.activityInfo.packageName,  filterCallingUid, userId);
                 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
-                        info.activityInfo.packageName, info.activityInfo.splitName,
                         installFailureActivity,
+                        info.activityInfo.packageName,
                         info.activityInfo.applicationInfo.versionCode,
-                        null /*failureIntent*/);
+                        info.activityInfo.splitName);
                 installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
                         | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
                 // add a non-generic filter
@@ -6857,6 +6877,7 @@
                 installerInfo.priority = info.priority;
                 installerInfo.preferredOrder = info.preferredOrder;
                 installerInfo.isDefault = info.isDefault;
+                installerInfo.isInstantAppAvailable = true;
                 resolveInfos.set(i, installerInfo);
                 continue;
             }
@@ -6914,17 +6935,6 @@
         return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
     }
 
-    private static boolean hasWebURI(Intent intent) {
-        if (intent.getData() == null) {
-            return false;
-        }
-        final String scheme = intent.getScheme();
-        if (TextUtils.isEmpty(scheme)) {
-            return false;
-        }
-        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
-    }
-
     private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
             int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
             int userId) {
@@ -7597,11 +7607,13 @@
                     if (DEBUG_EPHEMERAL) {
                         Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
                     }
-                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
+                    final ResolveInfo installerInfo = new ResolveInfo(
+                            mInstantAppInstallerInfo);
                     installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
-                            info.serviceInfo.packageName, info.serviceInfo.splitName,
-                            null /*failureActivity*/, info.serviceInfo.applicationInfo.versionCode,
-                            null /*failureIntent*/);
+                            null /* installFailureActivity */,
+                            info.serviceInfo.packageName,
+                            info.serviceInfo.applicationInfo.versionCode,
+                            info.serviceInfo.splitName);
                     // make sure this resolver is the default
                     installerInfo.isDefault = true;
                     installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
@@ -7717,11 +7729,13 @@
                     if (DEBUG_EPHEMERAL) {
                         Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
                     }
-                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
+                    final ResolveInfo installerInfo = new ResolveInfo(
+                            mInstantAppInstallerInfo);
                     installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
-                            info.providerInfo.packageName, info.providerInfo.splitName,
-                            null /*failureActivity*/, info.providerInfo.applicationInfo.versionCode,
-                            null /*failureIntent*/);
+                            null /*failureActivity*/,
+                            info.providerInfo.packageName,
+                            info.providerInfo.applicationInfo.versionCode,
+                            info.providerInfo.splitName);
                     // make sure this resolver is the default
                     installerInfo.isDefault = true;
                     installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
@@ -11761,7 +11775,7 @@
         mInstantAppInstallerActivity.exported = true;
         mInstantAppInstallerActivity.enabled = true;
         mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
-        mInstantAppInstallerInfo.priority = 0;
+        mInstantAppInstallerInfo.priority = 1;
         mInstantAppInstallerInfo.preferredOrder = 1;
         mInstantAppInstallerInfo.isDefault = true;
         mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
@@ -13211,7 +13225,8 @@
     }
 
     static final class EphemeralIntentResolver
-            extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
+            extends IntentResolver<AuxiliaryResolveInfo.AuxiliaryFilter,
+            AuxiliaryResolveInfo.AuxiliaryFilter> {
         /**
          * The result that has the highest defined order. Ordering applies on a
          * per-package basis. Mapping is from package name to Pair of order and
@@ -13226,18 +13241,19 @@
         final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
 
         @Override
-        protected AuxiliaryResolveInfo[] newArray(int size) {
-            return new AuxiliaryResolveInfo[size];
+        protected AuxiliaryResolveInfo.AuxiliaryFilter[] newArray(int size) {
+            return new AuxiliaryResolveInfo.AuxiliaryFilter[size];
         }
 
         @Override
-        protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
+        protected boolean isPackageForFilter(String packageName,
+                AuxiliaryResolveInfo.AuxiliaryFilter responseObj) {
             return true;
         }
 
         @Override
-        protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
-                int userId) {
+        protected AuxiliaryResolveInfo.AuxiliaryFilter newResult(
+                AuxiliaryResolveInfo.AuxiliaryFilter responseObj, int match, int userId) {
             if (!sUserManager.exists(userId)) {
                 return null;
             }
@@ -13258,7 +13274,7 @@
         }
 
         @Override
-        protected void filterResults(List<AuxiliaryResolveInfo> results) {
+        protected void filterResults(List<AuxiliaryResolveInfo.AuxiliaryFilter> results) {
             // only do work if ordering is enabled [most of the time it won't be]
             if (mOrderResult.size() == 0) {
                 return;
diff --git a/services/core/java/com/android/server/pm/PackageSignatures.java b/services/core/java/com/android/server/pm/PackageSignatures.java
index d471fc8..0229a37 100644
--- a/services/core/java/com/android/server/pm/PackageSignatures.java
+++ b/services/core/java/com/android/server/pm/PackageSignatures.java
@@ -182,7 +182,6 @@
                                     Signature sig = readSignatures.get(idx);
                                     if (sig != null) {
                                         signatures[pos] = readSignatures.get(idx);
-                                        pos++;
                                     } else {
                                         PackageManagerService.reportSettingsProblem(Log.WARN,
                                                 "Error in package manager settings: <cert> "
@@ -202,7 +201,6 @@
                                 Signature sig = new Signature(key);
                                 readSignatures.set(idx, sig);
                                 signatures[pos] = sig;
-                                pos++;
                             }
                         } catch (NumberFormatException e) {
                             PackageManagerService.reportSettingsProblem(Log.WARN,
@@ -245,6 +243,8 @@
                                     + "many <cert> tags, expected " + count
                                     + " at " + parser.getPositionDescription());
                 }
+                pos++;
+                XmlUtils.skipCurrentTag(parser);
             } else if (tagName.equals("pastSigs")) {
                 if (flags == null) {
                     // we haven't encountered pastSigs yet, go ahead
@@ -296,8 +296,8 @@
                 PackageManagerService.reportSettingsProblem(Log.WARN,
                         "Unknown element under <sigs>: "
                                 + parser.getName());
+                XmlUtils.skipCurrentTag(parser);
             }
-            XmlUtils.skipCurrentTag(parser);
         }
         return pos;
     }
@@ -330,4 +330,4 @@
         }
         return buf.toString();
     }
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 5e9019d..b6e1534 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -1996,6 +1996,8 @@
         if (DEBUG_MU) {
             Log.i(TAG, "Writing package restrictions for user=" + userId);
         }
+        final long startTime = SystemClock.uptimeMillis();
+
         // Keep the old stopped packages around until we know the new ones have
         // been successfully written.
         File userPackagesStateFile = getUserPackagesStateFile(userId);
@@ -2129,6 +2131,9 @@
                     |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
                     -1, -1);
 
+            com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
+                    "package-user-" + userId, SystemClock.uptimeMillis() - startTime);
+
             // Done, all is good!
             return;
         } catch(java.io.IOException e) {
@@ -2390,6 +2395,8 @@
     void writeLPr() {
         //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
 
+        final long startTime = SystemClock.uptimeMillis();
+
         // Keep the old settings around until we know the new ones have
         // been successfully written.
         if (mSettingsFilename.exists()) {
@@ -2535,6 +2542,8 @@
             writePackageListLPr();
             writeAllUsersPackageRestrictionsLPr();
             writeAllRuntimePermissionsLPr();
+            com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
+                    "package", SystemClock.uptimeMillis() - startTime);
             return;
 
         } catch(java.io.IOException e) {
@@ -5134,7 +5143,8 @@
         }
 
         private void writePermissionsSync(int userId) {
-            AtomicFile destination = new AtomicFile(getUserRuntimePermissionsFile(userId));
+            AtomicFile destination = new AtomicFile(getUserRuntimePermissionsFile(userId),
+                    "package-perms-" + userId);
 
             ArrayMap<String, List<PermissionState>> permissionsForPackage = new ArrayMap<>();
             ArrayMap<String, List<PermissionState>> permissionsForSharedUser = new ArrayMap<>();
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 0f394a4..0502848 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1025,7 +1025,7 @@
             public void run() {
                 // send interaction hint to improve redraw performance
                 mPowerManagerInternal.powerHint(PowerHint.INTERACTION, 0);
-                if (isRotationChoiceEnabled()) {
+                if (isRotationChoicePossible(mCurrentAppOrientation)) {
                     final boolean isValid = isValidRotationChoice(mCurrentAppOrientation,
                             mRotation);
                     sendProposedRotationChangeToStatusBarInternal(mRotation, isValid);
@@ -7144,7 +7144,7 @@
         mOrientationListener.setCurrentRotation(rotation);
     }
 
-    public boolean isRotationChoiceEnabled() {
+    public boolean isRotationChoicePossible(int orientation) {
         // Rotation choice is only shown when the user is in locked mode.
         if (mUserRotationMode != WindowManagerPolicy.USER_ROTATION_LOCKED) return false;
 
@@ -7184,50 +7184,45 @@
             return false;
         }
 
-        // Rotation isn't forced, enable choice
-        return true;
+        // Ensure that some rotation choice is possible for the given orientation
+        switch (orientation) {
+            case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
+            case ActivityInfo.SCREEN_ORIENTATION_USER:
+            case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
+            case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
+            case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
+                // NOSENSOR description is ambiguous, in reality WM ignores user choice
+                return true;
+        }
+
+        // Rotation is forced, should be controlled by system
+        return false;
     }
 
     public boolean isValidRotationChoice(int orientation, final int preferredRotation) {
-        // Determine if the given app orientation can be chosen and, if so, if it is compatible
-        // with the provided rotation choice
-
+        // Determine if the given app orientation is compatible with the provided rotation choice
         switch (orientation) {
-            case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
-            case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
-            case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
-            case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
-            case ActivityInfo.SCREEN_ORIENTATION_LOCKED:
-                return false; // Forced into a particular rotation, no user choice
-
-            case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
-            case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
-            case ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR:
-            case ActivityInfo.SCREEN_ORIENTATION_SENSOR:
-                return false; // Sensor overrides user choice
-
-            case ActivityInfo.SCREEN_ORIENTATION_NOSENSOR:
-                // TODO Can sensor be used to indirectly determine the orientation?
-                return false;
-
-            case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
-                // If the user has locked sensor-based rotation, this behaves the same as landscape
-                return false; // User has locked the rotation, will behave as LANDSCAPE
-            case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
-                // If the user has locked sensor-based rotation, this behaves the same as portrait
-                return false; // User has locked the rotation, will behave as PORTRAIT
-            case ActivityInfo.SCREEN_ORIENTATION_USER:
-                // Works with any rotation except upside down
-                return (preferredRotation >= 0) && (preferredRotation != mUpsideDownRotation);
             case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
                 // Works with any of the 4 rotations
                 return preferredRotation >= 0;
 
-            default:
-                // TODO: how to handle SCREEN_ORIENTATION_BEHIND, UNSET?
-                // For UNSPECIFIED use preferred orientation matching SCREEN_ORIENTATION_USER
+            case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
+                // It's possible for the user pref to be set at 180 because of FULL_USER. This would
+                // make switching to USER_PORTRAIT appear at 180. Provide choice to back to portrait
+                // but never to go to 180.
+                return preferredRotation == mPortraitRotation;
+
+            case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
+                // Works landscape or seascape
+                return isLandscapeOrSeascape(preferredRotation);
+
+            case ActivityInfo.SCREEN_ORIENTATION_USER:
+            case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
+                // Works with any rotation except upside down
                 return (preferredRotation >= 0) && (preferredRotation != mUpsideDownRotation);
         }
+
+        return false;
     }
 
     private boolean isLandscapeOrSeascape(int rotation) {
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index b986e04..eed3102 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -21,6 +21,7 @@
 import android.app.Dialog;
 import android.app.IActivityManager;
 import android.app.ProgressDialog;
+import android.app.admin.SecurityLog;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -390,6 +391,10 @@
             }
         }
 
+        if (SecurityLog.isLoggingEnabled()) {
+            SecurityLog.writeEvent(SecurityLog.TAG_OS_SHUTDOWN);
+        }
+
         // start the thread that initiates shutdown
         sInstance.mHandler = new Handler() {
         };
diff --git a/services/core/java/com/android/server/timezone/PackageStatusStorage.java b/services/core/java/com/android/server/timezone/PackageStatusStorage.java
index 251a277..04f0871 100644
--- a/services/core/java/com/android/server/timezone/PackageStatusStorage.java
+++ b/services/core/java/com/android/server/timezone/PackageStatusStorage.java
@@ -81,7 +81,7 @@
     private final AtomicFile mPackageStatusFile;
 
     PackageStatusStorage(File storageDir) {
-        mPackageStatusFile = new AtomicFile(new File(storageDir, "package-status.xml"));
+        mPackageStatusFile = new AtomicFile(new File(storageDir, "package-status.xml"), "timezone-status");
     }
 
     /**
diff --git a/services/core/java/com/android/server/tv/PersistentDataStore.java b/services/core/java/com/android/server/tv/PersistentDataStore.java
index 85a8829..8f2194c 100644
--- a/services/core/java/com/android/server/tv/PersistentDataStore.java
+++ b/services/core/java/com/android/server/tv/PersistentDataStore.java
@@ -91,7 +91,7 @@
                 throw new IllegalStateException("User dir cannot be created: " + userDir);
             }
         }
-        mAtomicFile = new AtomicFile(new File(userDir, "tv-input-manager-state.xml"));
+        mAtomicFile = new AtomicFile(new File(userDir, "tv-input-manager-state.xml"), "tv-input-state");
     }
 
     public boolean isParentalControlsEnabled() {
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index fc7ad09..2bdaa1a 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -38,6 +38,7 @@
 import static android.view.WindowManager.TRANSIT_WALLPAPER_INTRA_CLOSE;
 import static android.view.WindowManager.TRANSIT_WALLPAPER_INTRA_OPEN;
 import static android.view.WindowManager.TRANSIT_WALLPAPER_OPEN;
+
 import static com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation;
 import static com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
 import static com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation;
@@ -1647,10 +1648,7 @@
                         + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
                         + " Callers=" + Debug.getCallers(3));
             }
-        } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS
-                && (transit == TRANSIT_ACTIVITY_OPEN
-                        || transit == TRANSIT_TASK_OPEN
-                        || transit == TRANSIT_TASK_TO_FRONT)) {
+        } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS && enter) {
 
             a = loadAnimationRes("android", enter
                     ? com.android.internal.R.anim.task_open_enter_cross_profile_apps
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index d340923..2c2389b 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -219,6 +219,14 @@
     }
 
     /**
+     * Returns {@code true} if the {@link WindowConfiguration} in the override
+     * {@link Configuration} specifies bounds.
+     */
+    public boolean hasOverrideBounds() {
+        return !getOverrideBounds().isEmpty();
+    }
+
+    /**
      * Sets the passed in {@link Rect} to the current bounds.
      * @see {@link #getOverrideBounds()}.
      */
diff --git a/services/core/java/com/android/server/wm/DisplaySettings.java b/services/core/java/com/android/server/wm/DisplaySettings.java
index 7f79686..97b64dc 100644
--- a/services/core/java/com/android/server/wm/DisplaySettings.java
+++ b/services/core/java/com/android/server/wm/DisplaySettings.java
@@ -64,7 +64,7 @@
     public DisplaySettings() {
         File dataDir = Environment.getDataDirectory();
         File systemDir = new File(dataDir, "system");
-        mFile = new AtomicFile(new File(systemDir, "display_settings.xml"));
+        mFile = new AtomicFile(new File(systemDir, "display_settings.xml"), "wm-displays");
     }
 
     public void getOverscanLocked(String name, String uniqueId, Rect outRect) {
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index c7d4b8e..fe5b65c 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -265,7 +265,6 @@
         mPendingAnimations.clear();
 
         mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
-        mService.scheduleAnimationLocked();
         mService.destroyInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION);
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 1f9255a..a1026bd 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -467,10 +467,22 @@
     void onResize() {
         for (int i = mChildren.size() - 1; i >= 0; --i) {
             final WindowContainer wc = mChildren.get(i);
-            wc.onResize();
+            wc.onParentResize();
         }
     }
 
+    void onParentResize() {
+        // In the case this container has specified its own bounds, a parent resize will not
+        // affect its bounds. Any relevant changes will be propagated through changes to the
+        // Configuration override.
+        if (hasOverrideBounds()) {
+            return;
+        }
+
+        // Default implementation is to treat as resize on self.
+        onResize();
+    }
+
     void onMovedByResize() {
         for (int i = mChildren.size() - 1; i >= 0; --i) {
             final WindowContainer wc = mChildren.get(i);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index f238302..7d1b38b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -744,7 +744,8 @@
                 if (deviceOwner != null) {
                     Bundle extras = new Bundle();
                     extras.putParcelable(Intent.EXTRA_USER, UserHandle.of(userHandle));
-                    sendAdminCommandLocked(deviceOwner, action, extras, null);
+                    sendAdminCommandLocked(deviceOwner, action, extras, /* result */ null,
+                            /* inForeground */ true);
                 }
             }
         }
@@ -3313,6 +3314,7 @@
         cleanUpOldUsers();
         maybeSetDefaultProfileOwnerUserRestrictions();
         handleStartUser(UserHandle.USER_SYSTEM);
+        maybeLogStart();
 
         // Register an observer for watching for user setup complete and settings changes.
         mSetupContentObserver.register();
@@ -3368,6 +3370,16 @@
         updateSystemUpdateFreezePeriodsRecord(/* saveIfChanged */ true);
     }
 
+    private void maybeLogStart() {
+        if (!SecurityLog.isLoggingEnabled()) {
+            return;
+        }
+        final String verifiedBootState =
+                mInjector.systemPropertiesGet("ro.boot.verifiedbootstate");
+        final String verityMode = mInjector.systemPropertiesGet("ro.boot.veritymode");
+        SecurityLog.writeEvent(SecurityLog.TAG_OS_STARTUP, verifiedBootState, verityMode);
+    }
+
     private void ensureDeviceOwnerUserStarted() {
         final int userId;
         synchronized (this) {
@@ -3874,14 +3886,17 @@
         Preconditions.checkNotNull(who, "ComponentName is null");
         validateQualityConstant(quality);
 
+        final int userId = mInjector.userHandleGetCallingUserId();
         synchronized (this) {
             ActiveAdmin ap = getActiveAdminForCallerLocked(
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
-            if (ap.minimumPasswordMetrics.quality != quality) {
-                ap.minimumPasswordMetrics.quality = quality;
-                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
-                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
+            final PasswordMetrics metrics = ap.minimumPasswordMetrics;
+            if (metrics.quality != quality) {
+                metrics.quality = quality;
+                updatePasswordValidityCheckpointLocked(userId);
+                saveSettingsLocked(userId);
             }
+            maybeLogPasswordComplexitySet(who, userId, parent, metrics);
         }
     }
 
@@ -3974,14 +3989,17 @@
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
+        final int userId = mInjector.userHandleGetCallingUserId();
         synchronized (this) {
             ActiveAdmin ap = getActiveAdminForCallerLocked(
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
-            if (ap.minimumPasswordMetrics.length != length) {
-                ap.minimumPasswordMetrics.length = length;
-                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
-                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
+            final PasswordMetrics metrics = ap.minimumPasswordMetrics;
+            if (metrics.length != length) {
+                metrics.length = length;
+                updatePasswordValidityCheckpointLocked(userId);
+                saveSettingsLocked(userId);
             }
+            maybeLogPasswordComplexitySet(who, userId, parent, metrics);
         }
     }
 
@@ -3997,15 +4015,21 @@
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
+        final int userId = mInjector.userHandleGetCallingUserId();
         synchronized (this) {
             ActiveAdmin ap = getActiveAdminForCallerLocked(
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.passwordHistoryLength != length) {
                 ap.passwordHistoryLength = length;
-                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
-                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
+                updatePasswordValidityCheckpointLocked(userId);
+                saveSettingsLocked(userId);
             }
         }
+        if (SecurityLog.isLoggingEnabled()) {
+            final int affectedUserId = parent ? getProfileParentId(userId) : userId;
+            SecurityLog.writeEvent(SecurityLog.TAG_PASSWORD_HISTORY_LENGTH_SET,
+                    who.getPackageName(), userId, affectedUserId, length);
+        }
     }
 
     @Override
@@ -4039,6 +4063,11 @@
             // in case this is the first one, set the alarm on the appropriate user.
             setExpirationAlarmCheckLocked(mContext, userHandle, parent);
         }
+        if (SecurityLog.isLoggingEnabled()) {
+            final int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle;
+            SecurityLog.writeEvent(SecurityLog.TAG_PASSWORD_EXPIRATION_SET, who.getPackageName(),
+                    userHandle, affectedUserId, timeout);
+        }
     }
 
     /**
@@ -4187,14 +4216,17 @@
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
+        final int userId = mInjector.userHandleGetCallingUserId();
         synchronized (this) {
-            ActiveAdmin ap = getActiveAdminForCallerLocked(
+            final ActiveAdmin ap = getActiveAdminForCallerLocked(
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
-            if (ap.minimumPasswordMetrics.upperCase != length) {
-                ap.minimumPasswordMetrics.upperCase = length;
-                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
-                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
+            final PasswordMetrics metrics = ap.minimumPasswordMetrics;
+            if (metrics.upperCase != length) {
+                metrics.upperCase = length;
+                updatePasswordValidityCheckpointLocked(userId);
+                saveSettingsLocked(userId);
             }
+            maybeLogPasswordComplexitySet(who, userId, parent, metrics);
         }
     }
 
@@ -4207,14 +4239,17 @@
     @Override
     public void setPasswordMinimumLowerCase(ComponentName who, int length, boolean parent) {
         Preconditions.checkNotNull(who, "ComponentName is null");
+        final int userId = mInjector.userHandleGetCallingUserId();
         synchronized (this) {
             ActiveAdmin ap = getActiveAdminForCallerLocked(
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
-            if (ap.minimumPasswordMetrics.lowerCase != length) {
-                ap.minimumPasswordMetrics.lowerCase = length;
-                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
-                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
+            final PasswordMetrics metrics = ap.minimumPasswordMetrics;
+            if (metrics.lowerCase != length) {
+                metrics.lowerCase = length;
+                updatePasswordValidityCheckpointLocked(userId);
+                saveSettingsLocked(userId);
             }
+            maybeLogPasswordComplexitySet(who, userId, parent, metrics);
         }
     }
 
@@ -4230,14 +4265,17 @@
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
+        final int userId = mInjector.userHandleGetCallingUserId();
         synchronized (this) {
             ActiveAdmin ap = getActiveAdminForCallerLocked(
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
-            if (ap.minimumPasswordMetrics.letters != length) {
-                ap.minimumPasswordMetrics.letters = length;
-                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
-                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
+            final PasswordMetrics metrics = ap.minimumPasswordMetrics;
+            if (metrics.letters != length) {
+                metrics.letters = length;
+                updatePasswordValidityCheckpointLocked(userId);
+                saveSettingsLocked(userId);
             }
+            maybeLogPasswordComplexitySet(who, userId, parent, metrics);
         }
     }
 
@@ -4253,14 +4291,17 @@
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
+        final int userId = mInjector.userHandleGetCallingUserId();
         synchronized (this) {
             ActiveAdmin ap = getActiveAdminForCallerLocked(
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
-            if (ap.minimumPasswordMetrics.numeric != length) {
-                ap.minimumPasswordMetrics.numeric = length;
-                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
-                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
+            final PasswordMetrics metrics = ap.minimumPasswordMetrics;
+            if (metrics.numeric != length) {
+                metrics.numeric = length;
+                updatePasswordValidityCheckpointLocked(userId);
+                saveSettingsLocked(userId);
             }
+            maybeLogPasswordComplexitySet(who, userId, parent, metrics);
         }
     }
 
@@ -4268,7 +4309,7 @@
     public int getPasswordMinimumNumeric(ComponentName who, int userHandle, boolean parent) {
         return getStrictestPasswordRequirement(who, userHandle, parent,
                 admin -> admin.minimumPasswordMetrics.numeric, PASSWORD_QUALITY_COMPLEX);
-   }
+    }
 
     @Override
     public void setPasswordMinimumSymbols(ComponentName who, int length, boolean parent) {
@@ -4276,14 +4317,17 @@
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
+        final int userId = mInjector.userHandleGetCallingUserId();
         synchronized (this) {
             ActiveAdmin ap = getActiveAdminForCallerLocked(
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
-            if (ap.minimumPasswordMetrics.symbols != length) {
+            final PasswordMetrics metrics = ap.minimumPasswordMetrics;
+            if (metrics.symbols != length) {
                 ap.minimumPasswordMetrics.symbols = length;
-                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
-                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
+                updatePasswordValidityCheckpointLocked(userId);
+                saveSettingsLocked(userId);
             }
+            maybeLogPasswordComplexitySet(who, userId, parent, metrics);
         }
     }
 
@@ -4299,14 +4343,17 @@
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
+        final int userId = mInjector.userHandleGetCallingUserId();
         synchronized (this) {
             ActiveAdmin ap = getActiveAdminForCallerLocked(
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
-            if (ap.minimumPasswordMetrics.nonLetter != length) {
+            final PasswordMetrics metrics = ap.minimumPasswordMetrics;
+            if (metrics.nonLetter != length) {
                 ap.minimumPasswordMetrics.nonLetter = length;
-                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
-                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
+                updatePasswordValidityCheckpointLocked(userId);
+                saveSettingsLocked(userId);
             }
+            maybeLogPasswordComplexitySet(who, userId, parent, metrics);
         }
     }
 
@@ -4593,6 +4640,7 @@
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
+        final int userId = mInjector.userHandleGetCallingUserId();
         synchronized (this) {
             // This API can only be called by an active device admin,
             // so try to retrieve it to check that the caller is one.
@@ -4602,9 +4650,14 @@
                     who, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent);
             if (ap.maximumFailedPasswordsForWipe != num) {
                 ap.maximumFailedPasswordsForWipe = num;
-                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
+                saveSettingsLocked(userId);
             }
         }
+        if (SecurityLog.isLoggingEnabled()) {
+            final int affectedUserId = parent ? getProfileParentId(userId) : userId;
+            SecurityLog.writeEvent(SecurityLog.TAG_MAX_PASSWORD_ATTEMPTS_SET, who.getPackageName(),
+                    userId, affectedUserId, num);
+        }
     }
 
     @Override
@@ -4702,7 +4755,6 @@
             return false;
         }
     }
-
     @Override
     public boolean resetPassword(String passwordOrNull, int flags) throws RemoteException {
         final int callingUid = mInjector.binderGetCallingUid();
@@ -4958,6 +5010,11 @@
                 updateMaximumTimeToLockLocked(userHandle);
             }
         }
+        if (SecurityLog.isLoggingEnabled()) {
+            final int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle;
+            SecurityLog.writeEvent(SecurityLog.TAG_MAX_SCREEN_LOCK_TIMEOUT_SET,
+                    who.getPackageName(), userHandle, affectedUserId, timeMs);
+        }
     }
 
     private void updateMaximumTimeToLockLocked(@UserIdInt int userId) {
@@ -5127,11 +5184,12 @@
 
             final long ident = mInjector.binderClearCallingIdentity();
             try {
+                final ComponentName adminComponent = admin.info.getComponent();
                 // Evict key
                 if ((flags & DevicePolicyManager.FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY) != 0) {
                     enforceManagedProfile(
                             callingUserId, "set FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY");
-                    if (!isProfileOwner(admin.info.getComponent(), callingUserId)) {
+                    if (!isProfileOwner(adminComponent, callingUserId)) {
                         throw new SecurityException("Only profile owner admins can set "
                                 + "FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY");
                     }
@@ -5161,6 +5219,13 @@
                 } else {
                     mInjector.getTrustManager().setDeviceLockedForUser(userToLock, true);
                 }
+
+                if (SecurityLog.isLoggingEnabled()) {
+                    final int affectedUserId =
+                            parent ? getProfileParentId(callingUserId) : callingUserId;
+                    SecurityLog.writeEvent(SecurityLog.TAG_REMOTE_LOCK,
+                            adminComponent.getPackageName(), callingUserId, affectedUserId);
+                }
             } catch (RemoteException e) {
             } finally {
                 mInjector.binderRestoreCallingIdentity(ident);
@@ -6191,8 +6256,7 @@
 
         if (mInjector.securityLogIsLoggingEnabled()) {
             SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT,
-                    /*result*/ 0,
-                    /*method strength*/ 1);
+                    /*result*/ 0, /*method strength*/ 1);
         }
     }
 
@@ -7039,6 +7103,11 @@
                 saveSettingsLocked(userHandle);
             }
         }
+        if (SecurityLog.isLoggingEnabled()) {
+            final int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle;
+            SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_DISABLED_FEATURES_SET,
+                    who.getPackageName(), userHandle, affectedUserId, which);
+        }
     }
 
     /**
@@ -9186,6 +9255,12 @@
             }
             saveUserRestrictionsLocked(userHandle);
         }
+        if (SecurityLog.isLoggingEnabled()) {
+            final int eventTag = enabledFromThisOwner
+                    ? SecurityLog.TAG_USER_RESTRICTION_ADDED
+                    : SecurityLog.TAG_USER_RESTRICTION_REMOVED;
+            SecurityLog.writeEvent(eventTag, who.getPackageName(), userHandle, key);
+        }
     }
 
     private void saveUserRestrictionsLocked(int userId) {
@@ -12399,9 +12474,11 @@
     }
 
     @Override
-    public boolean clearApplicationUserData(ComponentName admin, String packageName,
+    public void clearApplicationUserData(ComponentName admin, String packageName,
             IPackageDataObserver callback) {
         Preconditions.checkNotNull(admin, "ComponentName is null");
+        Preconditions.checkNotNull(packageName, "packageName is null");
+        Preconditions.checkNotNull(callback, "callback is null");
         synchronized (this) {
             getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
         }
@@ -12409,29 +12486,24 @@
 
         long ident = mInjector.binderClearCallingIdentity();
         try {
-            return ActivityManager.getService().clearApplicationUserData(packageName, false,
-                    callback, userId);
+            ActivityManager.getService().clearApplicationUserData(packageName, false, callback,
+                    userId);
         } catch(RemoteException re) {
             // Same process, should not happen.
         } catch (SecurityException se) {
             // This can happen e.g. for device admin packages, do not throw out the exception,
             // because callers have no means to know beforehand for which packages this might
-            // happen.
+            // happen. If so, we send back that removal failed.
             Slog.w(LOG_TAG, "Not allowed to clear application user data for package " + packageName,
                     se);
-        } finally {
-            mInjector.binderRestoreCallingIdentity(ident);
-        }
-
-        if (callback != null) {
             try {
-                // If there was a throw above, we send back that removal failed
                 callback.onRemoveCompleted(packageName, false);
             } catch (RemoteException re) {
                 // Caller is no longer available, ignore
             }
+        } finally {
+            mInjector.binderRestoreCallingIdentity(ident);
         }
-        return false;
     }
 
     @Override
@@ -12962,4 +13034,15 @@
                 TRANSFER_OWNERSHIP_PARAMETERS_XML);
         parametersFile.delete();
     }
+
+    private void maybeLogPasswordComplexitySet(ComponentName who, int userId, boolean parent,
+            PasswordMetrics metrics) {
+        if (SecurityLog.isLoggingEnabled()) {
+            final int affectedUserId = parent ? getProfileParentId(userId) : userId;
+            SecurityLog.writeEvent(SecurityLog.TAG_PASSWORD_COMPLEXITY_SET, who.getPackageName(),
+                    userId, affectedUserId, metrics.length, metrics.quality, metrics.letters,
+                    metrics.nonLetter, metrics.numeric, metrics.upperCase, metrics.lowerCase,
+                    metrics.symbols);
+        }
+    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PasswordBlacklist.java b/services/devicepolicy/java/com/android/server/devicepolicy/PasswordBlacklist.java
index 6a9b53a..a17a107 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PasswordBlacklist.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PasswordBlacklist.java
@@ -47,7 +47,7 @@
      * This is a lightweight operation to prepare variables but not perform any IO.
      */
     public PasswordBlacklist(File file) {
-        mFile = new AtomicFile(file);
+        mFile = new AtomicFile(file, "device-policy");
     }
 
     /**
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java b/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java
index a9fd8e5..3277adf 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java
@@ -71,6 +71,10 @@
      */
     private static final int BUFFER_ENTRIES_MAXIMUM_LEVEL = BUFFER_ENTRIES_NOTIFICATION_LEVEL * 10;
     /**
+     * Critical log buffer level, 90% of capacity.
+     */
+    private static final int BUFFER_ENTRIES_CRITICAL_LEVEL = BUFFER_ENTRIES_MAXIMUM_LEVEL * 9 / 10;
+    /**
      * How often should Device Owner be notified under normal circumstances.
      */
     private static final long RATE_LIMIT_INTERVAL_MILLISECONDS = TimeUnit.HOURS.toMillis(2);
@@ -97,6 +101,10 @@
     @GuardedBy("mLock")
     private boolean mAllowedToRetrieve = false;
 
+    // Whether we have already logged the fact that log buffer reached 90%, to avoid dupes.
+    @GuardedBy("mLock")
+    private boolean mCriticalLevelLogged = false;
+
     /**
      * Last events fetched from log to check for overlap between batches. We can leave it empty if
      * we are sure there will be no overlap anymore, e.g. when we get empty batch.
@@ -116,10 +124,12 @@
 
     void start() {
         Slog.i(TAG, "Starting security logging.");
+        SecurityLog.writeEvent(SecurityLog.TAG_LOGGING_STARTED);
         mLock.lock();
         try {
             if (mMonitorThread == null) {
                 mPendingLogs = new ArrayList<>();
+                mCriticalLevelLogged = false;
                 mId = 0;
                 mAllowedToRetrieve = false;
                 mNextAllowedRetrievalTimeMillis = -1;
@@ -135,6 +145,7 @@
 
     void stop() {
         Slog.i(TAG, "Stopping security logging.");
+        SecurityLog.writeEvent(SecurityLog.TAG_LOGGING_STOPPED);
         mLock.lock();
         try {
             if (mMonitorThread != null) {
@@ -205,6 +216,7 @@
         mLock.lock();
         mAllowedToRetrieve = false;
         mPendingLogs = new ArrayList<>();
+        mCriticalLevelLogged = false;
         mLock.unlock();
         Slog.i(TAG, "Discarded all logs.");
     }
@@ -222,6 +234,7 @@
                         + RATE_LIMIT_INTERVAL_MILLISECONDS;
                 List<SecurityEvent> result = mPendingLogs;
                 mPendingLogs = new ArrayList<>();
+                mCriticalLevelLogged = false;
                 return result;
             } else {
                 return null;
@@ -344,11 +357,14 @@
         // Save the rest of the new batch.
         mPendingLogs.addAll(idLogs);
 
+        checkCriticalLevel();
+
         if (mPendingLogs.size() > BUFFER_ENTRIES_MAXIMUM_LEVEL) {
             // Truncate buffer down to half of BUFFER_ENTRIES_MAXIMUM_LEVEL.
             mPendingLogs = new ArrayList<>(mPendingLogs.subList(
                     mPendingLogs.size() - (BUFFER_ENTRIES_MAXIMUM_LEVEL / 2),
                     mPendingLogs.size()));
+            mCriticalLevelLogged = false;
             Slog.i(TAG, "Pending logs buffer full. Discarding old logs.");
         }
         if (DEBUG) Slog.d(TAG, mPendingLogs.size() + " pending events in the buffer after merging,"
@@ -357,6 +373,20 @@
     }
 
     @GuardedBy("mLock")
+    private void checkCriticalLevel() {
+        if (!SecurityLog.isLoggingEnabled()) {
+            return;
+        }
+
+        if (mPendingLogs.size() >= BUFFER_ENTRIES_CRITICAL_LEVEL) {
+            if (!mCriticalLevelLogged) {
+                mCriticalLevelLogged = true;
+                SecurityLog.writeEvent(SecurityLog.TAG_LOG_BUFFER_SIZE_CRITICAL);
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
     private void assignLogId(SecurityEvent event) {
         event.setId(mId);
         if (mId == Long.MAX_VALUE) {
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
index 196b4a9..1bd9a93 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
@@ -20,6 +20,7 @@
 import org.junit.runner.RunWith;
 
 import android.content.res.Configuration;
+import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -41,11 +42,16 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
 /**
  * Test class for {@link WindowContainer}.
  *
  * Build/Install/Run:
- *  bit FrameworksServicesTests:com.android.server.wm.WindowContainerTests
+ *  atest FrameworksServicesTests:com.android.server.wm.WindowContainerTests
  */
 @SmallTest
 @Presubmit
@@ -644,6 +650,37 @@
         assertEquals(1, child2.getPrefixOrderIndex());
     }
 
+    /**
+     * Ensure children of a {@link WindowContainer} do not have
+     * {@link WindowContainer#onParentResize()} called when {@link WindowContainer#onParentResize()}
+     * is invoked with overridden bounds.
+     */
+    @Test
+    public void testOnParentResizePropagation() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.build();
+
+        final TestWindowContainer child = root.addChildWindow();
+        child.setBounds(new Rect(1,1,2,2));
+
+        final TestWindowContainer grandChild = mock(TestWindowContainer.class);
+
+        child.addChildWindow(grandChild);
+        root.onResize();
+
+        // Make sure the child does not propagate resize through onParentResize when bounds are set.
+        verify(grandChild, never()).onParentResize();
+
+        child.removeChild(grandChild);
+
+        child.setBounds(null);
+        child.addChildWindow(grandChild);
+        root.onResize();
+
+        // Make sure the child propagates resize through onParentResize when no bounds set.
+        verify(grandChild, times(1)).onParentResize();
+    }
+
     /* Used so we can gain access to some protected members of the {@link WindowContainer} class */
     private class TestWindowContainer extends WindowContainer<TestWindowContainer> {
         private final int mLayer;
diff --git a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
index 917e651..5f1f5e4 100644
--- a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
@@ -208,7 +208,7 @@
         mParentUser = user;
         mSettingsFile = new AtomicFile(new File(
                 Environment.getUserSystemDirectory(user.getIdentifier()),
-                "usb_device_manager.xml"));
+                "usb_device_manager.xml"), "usb-state");
 
         mDisablePermissionDialogs = context.getResources().getBoolean(
                 com.android.internal.R.bool.config_disableUsbPermissionDialogs);