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);