Merge "Import translations. DO NOT MERGE"
diff --git a/Android.mk b/Android.mk
index a78a01a..f420820 100644
--- a/Android.mk
+++ b/Android.mk
@@ -36,7 +36,7 @@
define stubs-to-aidl-parcelables
gen := $(TARGET_OUT_COMMON_INTERMEDIATES)/$1.aidl
aidl_parcelables += $$(gen)
- $$(gen): $(call java-lib-header-files,$1) | $(HOST_OUT_EXECUTABLES)/sdkparcelables
+ $$(gen): $(call java-lib-header-files,$1) $(HOST_OUT_EXECUTABLES)/sdkparcelables
@echo Extract SDK parcelables: $$@
rm -f $$@
$(HOST_OUT_EXECUTABLES)/sdkparcelables $$< $$@
diff --git a/apct-tests/perftests/core/src/android/text/MeasuredTextMemoryUsageTest.java b/apct-tests/perftests/core/src/android/text/PrecomputedTextMemoryUsageTest.java
similarity index 73%
rename from apct-tests/perftests/core/src/android/text/MeasuredTextMemoryUsageTest.java
rename to apct-tests/perftests/core/src/android/text/PrecomputedTextMemoryUsageTest.java
index fc6302e..73e1724 100644
--- a/apct-tests/perftests/core/src/android/text/MeasuredTextMemoryUsageTest.java
+++ b/apct-tests/perftests/core/src/android/text/PrecomputedTextMemoryUsageTest.java
@@ -45,7 +45,7 @@
@LargeTest
@RunWith(AndroidJUnit4.class)
-public class MeasuredTextMemoryUsageTest {
+public class PrecomputedTextMemoryUsageTest {
private static final int WORD_LENGTH = 9; // Random word has 9 characters.
private static final boolean NO_STYLE_TEXT = false;
@@ -53,7 +53,7 @@
private static int TRIAL_COUNT = 100;
- public MeasuredTextMemoryUsageTest() {}
+ public PrecomputedTextMemoryUsageTest() {}
private TextPerfUtils mTextUtil = new TextPerfUtils();
@@ -77,13 +77,16 @@
@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)
+ final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT)
.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
- .build().getMemoryUsage();
+ .build();
+
+ // Report median of randomly generated PrecomputedText.
+ for (int i = 0; i < TRIAL_COUNT; ++i) {
+ memories[i] = PrecomputedText.create(
+ mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), param)
+ .getMemoryUsage();
}
reportMemoryUsage(median(memories), "MemoryUsage_NoHyphenation");
}
@@ -91,13 +94,16 @@
@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)
+ final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT)
.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
- .build().getMemoryUsage();
+ .build();
+
+ // Report median of randomly generated PrecomputedText.
+ for (int i = 0; i < TRIAL_COUNT; ++i) {
+ memories[i] = PrecomputedText.create(
+ mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), param)
+ .getMemoryUsage();
}
reportMemoryUsage(median(memories), "MemoryUsage_Hyphenation");
}
@@ -105,13 +111,16 @@
@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)
+ final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT)
.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
- .build(false /* width only */).getMemoryUsage();
+ .build();
+
+ // Report median of randomly generated PrecomputedText.
+ for (int i = 0; i < TRIAL_COUNT; ++i) {
+ CharSequence cs = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
+ memories[i] = PrecomputedText.createWidthOnly(cs, param, 0, cs.length())
+ .getMemoryUsage();
}
reportMemoryUsage(median(memories), "MemoryUsage_NoHyphenation_WidthOnly");
}
@@ -119,13 +128,16 @@
@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)
+ final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT)
.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
- .build(false /* width only */).getMemoryUsage();
+ .build();
+
+ // Report median of randomly generated PrecomputedText.
+ for (int i = 0; i < TRIAL_COUNT; ++i) {
+ CharSequence cs = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
+ memories[i] = PrecomputedText.createWidthOnly(cs, param, 0, cs.length())
+ .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/PrecomputedTextPerfTest.java
similarity index 66%
rename from apct-tests/perftests/core/src/android/text/MeasuredTextPerfTest.java
rename to apct-tests/perftests/core/src/android/text/PrecomputedTextPerfTest.java
index 98f2bd5..1cd0ae1 100644
--- a/apct-tests/perftests/core/src/android/text/MeasuredTextPerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/PrecomputedTextPerfTest.java
@@ -42,7 +42,7 @@
@LargeTest
@RunWith(AndroidJUnit4.class)
-public class MeasuredTextPerfTest {
+public class PrecomputedTextPerfTest {
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;
@@ -51,7 +51,7 @@
private static TextPaint PAINT = new TextPaint();
private static final int TEXT_WIDTH = WORDS_IN_LINE * WORD_LENGTH * (int) PAINT.getTextSize();
- public MeasuredTextPerfTest() {}
+ public PrecomputedTextPerfTest() {}
@Rule
public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
@@ -66,120 +66,136 @@
@Test
public void testCreate_NoStyled_Hyphenation() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT)
+ .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
+ .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
+ .build();
+
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 */);
+ PrecomputedText.create(text, param);
}
}
@Test
public void testCreate_NoStyled_NoHyphenation() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT)
+ .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
+ .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
+ .build();
+
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 */);
+ PrecomputedText.create(text, param);
}
}
@Test
public void testCreate_NoStyled_Hyphenation_WidthOnly() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT)
+ .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
+ .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
+ .build();
+
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 */);
+ PrecomputedText.create(text, param);
}
}
@Test
public void testCreate_NoStyled_NoHyphenation_WidthOnly() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT)
+ .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
+ .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
+ .build();
+
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 */);
+ PrecomputedText.create(text, param);
}
}
@Test
public void testCreate_Styled_Hyphenation() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT)
+ .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
+ .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
+ .build();
+
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 */);
+ PrecomputedText.create(text, param);
}
}
@Test
public void testCreate_Styled_NoHyphenation() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT)
+ .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
+ .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
+ .build();
+
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 */);
+ PrecomputedText.create(text, param);
}
}
@Test
public void testCreate_Styled_Hyphenation_WidthOnly() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT)
+ .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
+ .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
+ .build();
+
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 */);
+ PrecomputedText.create(text, param);
}
}
@Test
public void testCreate_Styled_NoHyphenation_WidthOnly() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT)
+ .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
+ .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
+ .build();
+
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 */);
+ PrecomputedText.create(text, param);
}
}
}
diff --git a/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java b/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java
index 231aaf2..8823af1 100644
--- a/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java
@@ -63,6 +63,18 @@
mTextUtil.resetRandom(0 /* seed */);
}
+ private PrecomputedText makeMeasured(CharSequence text, TextPaint paint) {
+ PrecomputedText.Params param = new PrecomputedText.Params.Builder(paint).build();
+ return PrecomputedText.create(text, param);
+ }
+
+ private PrecomputedText makeMeasured(CharSequence text, TextPaint paint, int strategy,
+ int frequency) {
+ PrecomputedText.Params param = new PrecomputedText.Params.Builder(paint)
+ .setHyphenationFrequency(frequency).setBreakStrategy(strategy).build();
+ return PrecomputedText.create(text, param);
+ }
+
@Test
public void testCreate_FixedText_NoStyle_Greedy_NoHyphenation() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
@@ -151,18 +163,16 @@
}
@Test
- public void testCreate_MeasuredText_NoStyled_Greedy_NoHyphenation() {
+ public void testCreate_PrecomputedText_NoStyled_Greedy_NoHyphenation() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
state.pauseTiming();
- final MeasuredText text = new MeasuredText.Builder(
- mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT)
- .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
- .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
- .build();
+ final PrecomputedText text = makeMeasured(
+ mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT,
+ Layout.BREAK_STRATEGY_SIMPLE, Layout.HYPHENATION_FREQUENCY_NONE);
state.resumeTiming();
- StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
+ StaticLayout.Builder.obtain(text, 0, text.getText().length(), PAINT, TEXT_WIDTH)
.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
.build();
@@ -170,18 +180,16 @@
}
@Test
- public void testCreate_MeasuredText_NoStyled_Greedy_Hyphenation() {
+ public void testCreate_PrecomputedText_NoStyled_Greedy_Hyphenation() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
state.pauseTiming();
- final MeasuredText text = new MeasuredText.Builder(
- mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT)
- .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
- .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
- .build();
+ final PrecomputedText text = makeMeasured(
+ mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT,
+ Layout.BREAK_STRATEGY_SIMPLE, Layout.HYPHENATION_FREQUENCY_NORMAL);
state.resumeTiming();
- StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
+ StaticLayout.Builder.obtain(text, 0, text.getText().length(), PAINT, TEXT_WIDTH)
.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
.build();
@@ -189,18 +197,16 @@
}
@Test
- public void testCreate_MeasuredText_NoStyled_Balanced_NoHyphenation() {
+ public void testCreate_PrecomputedText_NoStyled_Balanced_NoHyphenation() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
state.pauseTiming();
- final MeasuredText text = new MeasuredText.Builder(
- mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT)
- .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
- .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
- .build();
+ final PrecomputedText text = makeMeasured(
+ mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT,
+ Layout.BREAK_STRATEGY_BALANCED, Layout.HYPHENATION_FREQUENCY_NONE);
state.resumeTiming();
- StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
+ StaticLayout.Builder.obtain(text, 0, text.getText().length(), PAINT, TEXT_WIDTH)
.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
.build();
@@ -208,18 +214,16 @@
}
@Test
- public void testCreate_MeasuredText_NoStyled_Balanced_Hyphenation() {
+ public void testCreate_PrecomputedText_NoStyled_Balanced_Hyphenation() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
state.pauseTiming();
- final MeasuredText text = new MeasuredText.Builder(
- mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT)
- .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
- .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
- .build();
+ final PrecomputedText text = makeMeasured(
+ mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT,
+ Layout.BREAK_STRATEGY_BALANCED, Layout.HYPHENATION_FREQUENCY_NORMAL);
state.resumeTiming();
- StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
+ StaticLayout.Builder.obtain(text, 0, text.getText().length(), PAINT, TEXT_WIDTH)
.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
.build();
@@ -227,18 +231,16 @@
}
@Test
- public void testCreate_MeasuredText_Styled_Greedy_NoHyphenation() {
+ public void testCreate_PrecomputedText_Styled_Greedy_NoHyphenation() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
state.pauseTiming();
- final MeasuredText text = new MeasuredText.Builder(
- mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT)
- .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
- .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
- .build();
+ final PrecomputedText text = makeMeasured(
+ mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT,
+ Layout.BREAK_STRATEGY_SIMPLE, Layout.HYPHENATION_FREQUENCY_NONE);
state.resumeTiming();
- StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
+ StaticLayout.Builder.obtain(text, 0, text.getText().length(), PAINT, TEXT_WIDTH)
.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
.build();
@@ -328,15 +330,16 @@
}
@Test
- public void testDraw_MeasuredText_Styled() {
+ public void testDraw_PrecomputedText_Styled() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
final RenderNode node = RenderNode.create("benchmark", null);
while (state.keepRunning()) {
state.pauseTiming();
- final MeasuredText text = new MeasuredText.Builder(
- mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT).build();
+ final PrecomputedText text = makeMeasured(
+ mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT);
final StaticLayout layout =
- StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
+ StaticLayout.Builder.obtain(
+ text, 0, text.getText().length(), PAINT, TEXT_WIDTH).build();
final DisplayListCanvas c = node.start(1200, 200);
state.resumeTiming();
@@ -345,15 +348,16 @@
}
@Test
- public void testDraw_MeasuredText_NoStyled() {
+ public void testDraw_PrecomputedText_NoStyled() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
final RenderNode node = RenderNode.create("benchmark", null);
while (state.keepRunning()) {
state.pauseTiming();
- final MeasuredText text = new MeasuredText.Builder(
- mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT).build();
+ final PrecomputedText text = makeMeasured(
+ mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT);
final StaticLayout layout =
- StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
+ StaticLayout.Builder.obtain(
+ text, 0, text.getText().length(), PAINT, TEXT_WIDTH).build();
final DisplayListCanvas c = node.start(1200, 200);
state.resumeTiming();
@@ -362,15 +366,16 @@
}
@Test
- public void testDraw_MeasuredText_Styled_WithoutCache() {
+ public void testDraw_PrecomputedText_Styled_WithoutCache() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
final RenderNode node = RenderNode.create("benchmark", null);
while (state.keepRunning()) {
state.pauseTiming();
- final MeasuredText text = new MeasuredText.Builder(
- mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT).build();
+ final PrecomputedText text = makeMeasured(
+ mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT);
final StaticLayout layout =
- StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
+ StaticLayout.Builder.obtain(
+ text, 0, text.getText().length(), PAINT, TEXT_WIDTH).build();
final DisplayListCanvas c = node.start(1200, 200);
Canvas.freeTextLayoutCaches();
state.resumeTiming();
@@ -380,15 +385,16 @@
}
@Test
- public void testDraw_MeasuredText_NoStyled_WithoutCache() {
+ public void testDraw_PrecomputedText_NoStyled_WithoutCache() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
final RenderNode node = RenderNode.create("benchmark", null);
while (state.keepRunning()) {
state.pauseTiming();
- final MeasuredText text = new MeasuredText.Builder(
- mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT).build();
+ final PrecomputedText text = makeMeasured(
+ mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT);
final StaticLayout layout =
- StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
+ StaticLayout.Builder.obtain(
+ text, 0, text.getText().length(), PAINT, TEXT_WIDTH).build();
final DisplayListCanvas c = node.start(1200, 200);
Canvas.freeTextLayoutCaches();
state.resumeTiming();
diff --git a/api/current.txt b/api/current.txt
index 14d61f7..3edd2c0 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -73,7 +73,6 @@
field public static final java.lang.String DUMP = "android.permission.DUMP";
field public static final java.lang.String EXPAND_STATUS_BAR = "android.permission.EXPAND_STATUS_BAR";
field public static final java.lang.String FACTORY_TEST = "android.permission.FACTORY_TEST";
- field public static final java.lang.String FOREGROUND_SERVICE = "android.permission.FOREGROUND_SERVICE";
field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
field public static final java.lang.String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED";
field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
@@ -6706,6 +6705,7 @@
field public static final int USER_OPERATION_ERROR_MAX_RUNNING_USERS = 3; // 0x3
field public static final int USER_OPERATION_ERROR_UNKNOWN = 1; // 0x1
field public static final int USER_OPERATION_SUCCESS = 0; // 0x0
+ field public static final int WIPE_EUICC = 4; // 0x4
field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1
field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
}
@@ -9442,6 +9442,7 @@
field public static final java.lang.String DISPLAY_SERVICE = "display";
field public static final java.lang.String DOWNLOAD_SERVICE = "download";
field public static final java.lang.String DROPBOX_SERVICE = "dropbox";
+ field public static final java.lang.String EUICC_SERVICE = "euicc";
field public static final java.lang.String FINGERPRINT_SERVICE = "fingerprint";
field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
@@ -11267,6 +11268,7 @@
field public static final java.lang.String FEATURE_STRONGBOX_KEYSTORE = "android.hardware.strongbox_keystore";
field public static final java.lang.String FEATURE_TELEPHONY = "android.hardware.telephony";
field public static final java.lang.String FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma";
+ field public static final java.lang.String FEATURE_TELEPHONY_EUICC = "android.hardware.telephony.euicc";
field public static final java.lang.String FEATURE_TELEPHONY_GSM = "android.hardware.telephony.gsm";
field public static final java.lang.String FEATURE_TELEPHONY_MBMS = "android.hardware.telephony.mbms";
field public static final deprecated java.lang.String FEATURE_TELEVISION = "android.hardware.type.television";
@@ -13833,6 +13835,7 @@
method public int breakText(java.lang.String, boolean, float, float[]);
method public void clearShadowLayer();
method public float descent();
+ method public boolean equalsForTextMeasurement(android.graphics.Paint);
method public int getAlpha();
method public int getColor();
method public android.graphics.ColorFilter getColorFilter();
@@ -15844,8 +15847,6 @@
method public abstract void createReprocessableCaptureSessionByConfigurations(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract java.lang.String getId();
field public static final int TEMPLATE_MANUAL = 6; // 0x6
- field public static final int TEMPLATE_MOTION_TRACKING_BEST = 8; // 0x8
- field public static final int TEMPLATE_MOTION_TRACKING_PREVIEW = 7; // 0x7
field public static final int TEMPLATE_PREVIEW = 1; // 0x1
field public static final int TEMPLATE_RECORD = 3; // 0x3
field public static final int TEMPLATE_STILL_CAPTURE = 2; // 0x2
@@ -42207,13 +42208,16 @@
method public java.lang.String getNumber();
method public int getSimSlotIndex();
method public int getSubscriptionId();
+ method public boolean isEmbedded();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.telephony.SubscriptionInfo> CREATOR;
}
public class SubscriptionManager {
method public void addOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
+ method public boolean canManageSubscription(android.telephony.SubscriptionInfo);
method public static deprecated android.telephony.SubscriptionManager from(android.content.Context);
+ method public java.util.List<android.telephony.SubscriptionInfo> getAccessibleSubscriptionInfoList();
method public android.telephony.SubscriptionInfo getActiveSubscriptionInfo(int);
method public int getActiveSubscriptionInfoCount();
method public int getActiveSubscriptionInfoCountMax();
@@ -42598,6 +42602,44 @@
}
+package android.telephony.euicc {
+
+ public final class DownloadableSubscription implements android.os.Parcelable {
+ method public int describeContents();
+ method public static android.telephony.euicc.DownloadableSubscription forActivationCode(java.lang.String);
+ method public java.lang.String getConfirmationCode();
+ method public java.lang.String getEncodedActivationCode();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.euicc.DownloadableSubscription> CREATOR;
+ }
+
+ public final class EuiccInfo implements android.os.Parcelable {
+ ctor public EuiccInfo(java.lang.String);
+ method public int describeContents();
+ method public java.lang.String getOsVersion();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.euicc.EuiccInfo> CREATOR;
+ }
+
+ public class EuiccManager {
+ method public void deleteSubscription(int, android.app.PendingIntent);
+ method public void downloadSubscription(android.telephony.euicc.DownloadableSubscription, boolean, android.app.PendingIntent);
+ method public java.lang.String getEid();
+ method public android.telephony.euicc.EuiccInfo getEuiccInfo();
+ method public boolean isEnabled();
+ method public void startResolutionActivity(android.app.Activity, int, android.content.Intent, android.app.PendingIntent) throws android.content.IntentSender.SendIntentException;
+ method public void switchToSubscription(int, android.app.PendingIntent);
+ field public static final java.lang.String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS = "android.telephony.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS";
+ field public static final java.lang.String ACTION_NOTIFY_CARRIER_SETUP_INCOMPLETE = "android.telephony.euicc.action.NOTIFY_CARRIER_SETUP_INCOMPLETE";
+ field public static final int EMBEDDED_SUBSCRIPTION_RESULT_ERROR = 2; // 0x2
+ field public static final int EMBEDDED_SUBSCRIPTION_RESULT_OK = 0; // 0x0
+ field public static final int EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR = 1; // 0x1
+ field public static final java.lang.String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE";
+ field public static final java.lang.String META_DATA_CARRIER_ICON = "android.telephony.euicc.carriericon";
+ }
+
+}
+
package android.telephony.gsm {
public class GsmCellLocation extends android.telephony.CellLocation {
@@ -43183,36 +43225,6 @@
method public boolean isAllowed(char);
}
- public class MeasuredText implements android.text.Spanned {
- method public char charAt(int);
- method public int getBreakStrategy();
- method public int getEnd();
- method public int getHyphenationFrequency();
- method public android.text.TextPaint getPaint();
- method public int getParagraphCount();
- method public int getParagraphEnd(int);
- method public int getParagraphStart(int);
- method public int getSpanEnd(java.lang.Object);
- method public int getSpanFlags(java.lang.Object);
- method public int getSpanStart(java.lang.Object);
- method public <T> T[] getSpans(int, int, java.lang.Class<T>);
- method public int getStart();
- method public java.lang.CharSequence getText();
- method public android.text.TextDirectionHeuristic getTextDir();
- method public int length();
- method public int nextSpanTransition(int, int, java.lang.Class);
- method public java.lang.CharSequence subSequence(int, int);
- }
-
- public static final class MeasuredText.Builder {
- ctor public MeasuredText.Builder(java.lang.CharSequence, android.text.TextPaint);
- method public android.text.MeasuredText build();
- method public android.text.MeasuredText.Builder setBreakStrategy(int);
- method public android.text.MeasuredText.Builder setHyphenationFrequency(int);
- method public android.text.MeasuredText.Builder setRange(int, int);
- method public android.text.MeasuredText.Builder setTextDirection(android.text.TextDirectionHeuristic);
- }
-
public abstract interface NoCopySpan {
}
@@ -43224,6 +43236,31 @@
method public abstract int getSpanTypeId();
}
+ public class PrecomputedText {
+ method public static android.text.PrecomputedText create(java.lang.CharSequence, android.text.PrecomputedText.Params);
+ method public int getParagraphCount();
+ method public int getParagraphEnd(int);
+ method public int getParagraphStart(int);
+ method public android.text.PrecomputedText.Params getParams();
+ method public java.lang.CharSequence getText();
+ }
+
+ public static class PrecomputedText.Params {
+ method public int getBreakStrategy();
+ method public int getHyphenationFrequency();
+ method public android.text.TextDirectionHeuristic getTextDirection();
+ method public android.text.TextPaint getTextPaint();
+ method public boolean sameTextMetrics(android.text.PrecomputedText.Params);
+ }
+
+ public static class PrecomputedText.Params.Builder {
+ ctor public PrecomputedText.Params.Builder(android.text.TextPaint);
+ method public android.text.PrecomputedText.Params build();
+ method public android.text.PrecomputedText.Params.Builder setBreakStrategy(int);
+ method public android.text.PrecomputedText.Params.Builder setHyphenationFrequency(int);
+ method public android.text.PrecomputedText.Params.Builder setTextDirection(android.text.TextDirectionHeuristic);
+ }
+
public class Selection {
method public static boolean extendDown(android.text.Spannable, android.text.Layout);
method public static boolean extendLeft(android.text.Spannable, android.text.Layout);
@@ -43355,6 +43392,7 @@
public static final class StaticLayout.Builder {
method public android.text.StaticLayout build();
+ method public static android.text.StaticLayout.Builder obtain(android.text.PrecomputedText, int, int, android.text.TextPaint, int);
method public static android.text.StaticLayout.Builder obtain(java.lang.CharSequence, int, int, android.text.TextPaint, int);
method public android.text.StaticLayout.Builder setAlignment(android.text.Layout.Alignment);
method public android.text.StaticLayout.Builder setBreakStrategy(int);
@@ -53606,6 +53644,7 @@
method public final android.content.res.ColorStateList getTextColors();
method public java.util.Locale getTextLocale();
method public android.os.LocaleList getTextLocales();
+ method public android.text.PrecomputedText.Params getTextMetricsParams();
method public float getTextScaleX();
method public float getTextSize();
method public int getTotalPaddingBottom();
@@ -53711,6 +53750,8 @@
method public final void setMovementMethod(android.text.method.MovementMethod);
method public void setOnEditorActionListener(android.widget.TextView.OnEditorActionListener);
method public void setPaintFlags(int);
+ method public void setPrecomputedTextAndParams(android.text.PrecomputedText);
+ method public void setPrecomputedTextOrThrow(android.text.PrecomputedText);
method public void setPrivateImeOptions(java.lang.String);
method public void setRawInputType(int);
method public void setScroller(android.widget.Scroller);
@@ -53735,6 +53776,7 @@
method public final void setTextKeepState(java.lang.CharSequence, android.widget.TextView.BufferType);
method public void setTextLocale(java.util.Locale);
method public void setTextLocales(android.os.LocaleList);
+ method public void setTextMetricsParams(android.text.PrecomputedText.Params);
method public void setTextScaleX(float);
method public void setTextSize(float);
method public void setTextSize(int, float);
diff --git a/api/system-current.txt b/api/system-current.txt
index 71df272..953941f 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -20,6 +20,7 @@
field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
field public static final deprecated java.lang.String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE";
field public static final java.lang.String BIND_DIRECTORY_SEARCH = "android.permission.BIND_DIRECTORY_SEARCH";
+ field public static final java.lang.String BIND_EUICC_SERVICE = "android.permission.BIND_EUICC_SERVICE";
field public static final java.lang.String BIND_IMS_SERVICE = "android.permission.BIND_IMS_SERVICE";
field public static final java.lang.String BIND_KEYGUARD_APPWIDGET = "android.permission.BIND_KEYGUARD_APPWIDGET";
field public static final java.lang.String BIND_NETWORK_RECOMMENDATION_SERVICE = "android.permission.BIND_NETWORK_RECOMMENDATION_SERVICE";
@@ -186,6 +187,7 @@
field public static final java.lang.String USE_RESERVED_DISK = "android.permission.USE_RESERVED_DISK";
field public static final java.lang.String WRITE_APN_SETTINGS = "android.permission.WRITE_APN_SETTINGS";
field public static final java.lang.String WRITE_DREAM_STATE = "android.permission.WRITE_DREAM_STATE";
+ field public static final java.lang.String WRITE_EMBEDDED_SUBSCRIPTIONS = "android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS";
field public static final java.lang.String WRITE_GSERVICES = "android.permission.WRITE_GSERVICES";
field public static final java.lang.String WRITE_MEDIA_STORAGE = "android.permission.WRITE_MEDIA_STORAGE";
field public static final java.lang.String WRITE_SECURE_SETTINGS = "android.permission.WRITE_SECURE_SETTINGS";
@@ -341,11 +343,13 @@
method public java.lang.String getChannelId();
method public android.app.PendingIntent getContentIntent();
method public android.app.PendingIntent getDeleteIntent();
+ method public boolean getSuppressShowOverApps();
method public boolean isAvailableOnTv();
method public android.app.Notification.TvExtender setChannel(java.lang.String);
method public android.app.Notification.TvExtender setChannelId(java.lang.String);
method public android.app.Notification.TvExtender setContentIntent(android.app.PendingIntent);
method public android.app.Notification.TvExtender setDeleteIntent(android.app.PendingIntent);
+ method public android.app.Notification.TvExtender setSuppressShowOverApps(boolean);
}
public final class NotificationChannel implements android.os.Parcelable {
@@ -791,6 +795,7 @@
method public abstract void sendOrderedBroadcast(android.content.Intent, java.lang.String, android.os.Bundle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
field public static final java.lang.String BACKUP_SERVICE = "backup";
field public static final java.lang.String CONTEXTHUB_SERVICE = "contexthub";
+ field public static final java.lang.String EUICC_CARD_SERVICE = "euicc_card";
field public static final java.lang.String HDMI_CONTROL_SERVICE = "hdmi_control";
field public static final java.lang.String NETWORK_SCORE_SERVICE = "network_score";
field public static final java.lang.String OEM_LOCK_SERVICE = "oem_lock";
@@ -4134,6 +4139,7 @@
method public static boolean putString(android.content.ContentResolver, java.lang.String, java.lang.String, java.lang.String, boolean);
method public static void resetToDefaults(android.content.ContentResolver, java.lang.String);
field public static final java.lang.String AUTOFILL_COMPAT_ALLOWED_PACKAGES = "autofill_compat_allowed_packages";
+ field public static final java.lang.String DEFAULT_SM_DP_PLUS = "default_sm_dp_plus";
field public static final java.lang.String OTA_DISABLE_AUTOMATIC_UPDATE = "ota_disable_automatic_update";
field public static final java.lang.String THEATER_MODE_ON = "theater_mode_on";
field public static final java.lang.String WEBVIEW_MULTIPROCESS = "webview_multiprocess";
@@ -4307,6 +4313,125 @@
}
+package android.service.euicc {
+
+ public final class EuiccProfileInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public android.service.carrier.CarrierIdentifier getCarrierIdentifier();
+ method public java.lang.String getIccid();
+ method public java.lang.String getNickname();
+ method public int getPolicyRules();
+ method public int getProfileClass();
+ method public java.lang.String getProfileName();
+ method public java.lang.String getServiceProviderName();
+ method public int getState();
+ method public java.util.List<android.telephony.UiccAccessRule> getUiccAccessRules();
+ method public boolean hasPolicyRule(int);
+ method public boolean hasPolicyRules();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.euicc.EuiccProfileInfo> CREATOR;
+ field public static final int POLICY_RULE_DELETE_AFTER_DISABLING = 4; // 0x4
+ field public static final int POLICY_RULE_DO_NOT_DELETE = 2; // 0x2
+ field public static final int POLICY_RULE_DO_NOT_DISABLE = 1; // 0x1
+ field public static final int PROFILE_CLASS_OPERATIONAL = 2; // 0x2
+ field public static final int PROFILE_CLASS_PROVISIONING = 1; // 0x1
+ field public static final int PROFILE_CLASS_TESTING = 0; // 0x0
+ field public static final int PROFILE_STATE_DISABLED = 0; // 0x0
+ field public static final int PROFILE_STATE_ENABLED = 1; // 0x1
+ }
+
+ public static final class EuiccProfileInfo.Builder {
+ ctor public EuiccProfileInfo.Builder(java.lang.String);
+ ctor public EuiccProfileInfo.Builder(android.service.euicc.EuiccProfileInfo);
+ method public android.service.euicc.EuiccProfileInfo build();
+ method public android.service.euicc.EuiccProfileInfo.Builder setCarrierIdentifier(android.service.carrier.CarrierIdentifier);
+ method public android.service.euicc.EuiccProfileInfo.Builder setIccid(java.lang.String);
+ method public android.service.euicc.EuiccProfileInfo.Builder setNickname(java.lang.String);
+ method public android.service.euicc.EuiccProfileInfo.Builder setPolicyRules(int);
+ method public android.service.euicc.EuiccProfileInfo.Builder setProfileClass(int);
+ method public android.service.euicc.EuiccProfileInfo.Builder setProfileName(java.lang.String);
+ method public android.service.euicc.EuiccProfileInfo.Builder setServiceProviderName(java.lang.String);
+ method public android.service.euicc.EuiccProfileInfo.Builder setState(int);
+ method public android.service.euicc.EuiccProfileInfo.Builder setUiccAccessRule(java.util.List<android.telephony.UiccAccessRule>);
+ }
+
+ public static abstract class EuiccProfileInfo.PolicyRule implements java.lang.annotation.Annotation {
+ }
+
+ public static abstract class EuiccProfileInfo.ProfileClass implements java.lang.annotation.Annotation {
+ }
+
+ public static abstract class EuiccProfileInfo.ProfileState implements java.lang.annotation.Annotation {
+ }
+
+ public abstract class EuiccService extends android.app.Service {
+ ctor public EuiccService();
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public abstract int onDeleteSubscription(int, java.lang.String);
+ method public abstract int onDownloadSubscription(int, android.telephony.euicc.DownloadableSubscription, boolean, boolean);
+ method public abstract int onEraseSubscriptions(int);
+ method public abstract android.service.euicc.GetDefaultDownloadableSubscriptionListResult onGetDefaultDownloadableSubscriptionList(int, boolean);
+ method public abstract android.service.euicc.GetDownloadableSubscriptionMetadataResult onGetDownloadableSubscriptionMetadata(int, android.telephony.euicc.DownloadableSubscription, boolean);
+ method public abstract java.lang.String onGetEid(int);
+ method public abstract android.telephony.euicc.EuiccInfo onGetEuiccInfo(int);
+ method public abstract android.service.euicc.GetEuiccProfileInfoListResult onGetEuiccProfileInfoList(int);
+ method public abstract int onGetOtaStatus(int);
+ method public abstract int onRetainSubscriptionsForFactoryReset(int);
+ method public abstract void onStartOtaIfNecessary(int, android.service.euicc.EuiccService.OtaStatusChangedCallback);
+ method public abstract int onSwitchToSubscription(int, java.lang.String, boolean);
+ method public abstract int onUpdateSubscriptionNickname(int, java.lang.String, java.lang.String);
+ field public static final java.lang.String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS = "android.service.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS";
+ field public static final java.lang.String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION = "android.service.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION";
+ field public static final java.lang.String ACTION_RESOLVE_CONFIRMATION_CODE = "android.service.euicc.action.RESOLVE_CONFIRMATION_CODE";
+ field public static final java.lang.String ACTION_RESOLVE_DEACTIVATE_SIM = "android.service.euicc.action.RESOLVE_DEACTIVATE_SIM";
+ field public static final java.lang.String ACTION_RESOLVE_NO_PRIVILEGES = "android.service.euicc.action.RESOLVE_NO_PRIVILEGES";
+ field public static final java.lang.String CATEGORY_EUICC_UI = "android.service.euicc.category.EUICC_UI";
+ field public static final java.lang.String EUICC_SERVICE_INTERFACE = "android.service.euicc.EuiccService";
+ field public static final java.lang.String EXTRA_RESOLUTION_CALLING_PACKAGE = "android.service.euicc.extra.RESOLUTION_CALLING_PACKAGE";
+ field public static final java.lang.String EXTRA_RESOLUTION_CONFIRMATION_CODE = "android.service.euicc.extra.RESOLUTION_CONFIRMATION_CODE";
+ field public static final java.lang.String EXTRA_RESOLUTION_CONFIRMATION_CODE_RETRIED = "android.service.euicc.extra.RESOLUTION_CONFIRMATION_CODE_RETRIED";
+ field public static final java.lang.String EXTRA_RESOLUTION_CONSENT = "android.service.euicc.extra.RESOLUTION_CONSENT";
+ field public static final int RESULT_FIRST_USER = 1; // 0x1
+ field public static final int RESULT_MUST_DEACTIVATE_SIM = -1; // 0xffffffff
+ field public static final int RESULT_NEED_CONFIRMATION_CODE = -2; // 0xfffffffe
+ field public static final int RESULT_OK = 0; // 0x0
+ }
+
+ public static abstract class EuiccService.OtaStatusChangedCallback {
+ ctor public EuiccService.OtaStatusChangedCallback();
+ method public abstract void onOtaStatusChanged(int);
+ }
+
+ public final class GetDefaultDownloadableSubscriptionListResult implements android.os.Parcelable {
+ ctor public GetDefaultDownloadableSubscriptionListResult(int, android.telephony.euicc.DownloadableSubscription[]);
+ method public int describeContents();
+ method public java.util.List<android.telephony.euicc.DownloadableSubscription> getDownloadableSubscriptions();
+ method public int getResult();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.euicc.GetDefaultDownloadableSubscriptionListResult> CREATOR;
+ }
+
+ public final class GetDownloadableSubscriptionMetadataResult implements android.os.Parcelable {
+ ctor public GetDownloadableSubscriptionMetadataResult(int, android.telephony.euicc.DownloadableSubscription);
+ method public int describeContents();
+ method public android.telephony.euicc.DownloadableSubscription getDownloadableSubscription();
+ method public int getResult();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.euicc.GetDownloadableSubscriptionMetadataResult> CREATOR;
+ }
+
+ public final class GetEuiccProfileInfoListResult implements android.os.Parcelable {
+ ctor public GetEuiccProfileInfoListResult(int, android.service.euicc.EuiccProfileInfo[], boolean);
+ method public int describeContents();
+ method public boolean getIsRemovable();
+ method public java.util.List<android.service.euicc.EuiccProfileInfo> getProfiles();
+ method public int getResult();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.euicc.GetEuiccProfileInfoListResult> CREATOR;
+ }
+
+}
+
package android.service.notification {
public final class Adjustment implements android.os.Parcelable {
@@ -4907,8 +5032,14 @@
field public static final int RESULT_SYSTEM_ERROR = 15; // 0xf
}
+ public class SubscriptionInfo implements android.os.Parcelable {
+ method public java.util.List<android.telephony.UiccAccessRule> getAccessRules();
+ }
+
public class SubscriptionManager {
+ method public java.util.List<android.telephony.SubscriptionInfo> getAvailableSubscriptionInfoList();
method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int);
+ method public void requestEmbeddedSubscriptionInfoListRefresh();
method public void setSubscriptionOverrideCongested(int, boolean, long);
method public void setSubscriptionOverrideUnmetered(int, boolean, long);
method public void setSubscriptionPlans(int, java.util.List<android.telephony.SubscriptionPlan>);
@@ -5044,6 +5175,16 @@
field public static final int SIM_STATE_PRESENT = 11; // 0xb
}
+ public final class UiccAccessRule implements android.os.Parcelable {
+ ctor public UiccAccessRule(byte[], java.lang.String, long);
+ method public int describeContents();
+ method public int getCarrierPrivilegeStatus(android.content.pm.PackageInfo);
+ method public int getCarrierPrivilegeStatus(android.content.pm.Signature, java.lang.String);
+ method public java.lang.String getPackageName();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.UiccAccessRule> CREATOR;
+ }
+
public class UiccSlotInfo implements android.os.Parcelable {
ctor public UiccSlotInfo(boolean, boolean, java.lang.String, int, int);
method public int describeContents();
@@ -5154,6 +5295,125 @@
}
+package android.telephony.euicc {
+
+ public final class DownloadableSubscription implements android.os.Parcelable {
+ method public java.util.List<android.telephony.UiccAccessRule> getAccessRules();
+ method public java.lang.String getCarrierName();
+ }
+
+ public static final class DownloadableSubscription.Builder {
+ ctor public DownloadableSubscription.Builder();
+ ctor public DownloadableSubscription.Builder(android.telephony.euicc.DownloadableSubscription);
+ method public android.telephony.euicc.DownloadableSubscription build();
+ method public android.telephony.euicc.DownloadableSubscription.Builder setAccessRules(java.util.List<android.telephony.UiccAccessRule>);
+ method public android.telephony.euicc.DownloadableSubscription.Builder setCarrierName(java.lang.String);
+ method public android.telephony.euicc.DownloadableSubscription.Builder setConfirmationCode(java.lang.String);
+ method public android.telephony.euicc.DownloadableSubscription.Builder setEncodedActivationCode(java.lang.String);
+ }
+
+ public class EuiccCardManager {
+ method public void authenticateServer(java.lang.String, java.lang.String, byte[], byte[], byte[], byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+ method public void cancelSession(java.lang.String, byte[], int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+ method public void deleteProfile(java.lang.String, java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+ method public void disableProfile(java.lang.String, java.lang.String, boolean, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+ method public void listNotifications(java.lang.String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification[]>);
+ method public void loadBoundProfilePackage(java.lang.String, byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+ method public void prepareDownload(java.lang.String, byte[], byte[], byte[], byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+ method public void removeNotificationFromList(java.lang.String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+ method public void requestAllProfiles(java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo[]>);
+ method public void requestDefaultSmdpAddress(java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.String>);
+ method public void requestEuiccChallenge(java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+ method public void requestEuiccInfo1(java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+ method public void requestEuiccInfo2(java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+ method public void requestProfile(java.lang.String, java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo>);
+ method public void requestRulesAuthTable(java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccRulesAuthTable>);
+ method public void requestSmdsAddress(java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.String>);
+ method public void resetMemory(java.lang.String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+ method public void retrieveNotification(java.lang.String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification>);
+ method public void retrieveNotificationList(java.lang.String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification[]>);
+ method public void setDefaultSmdpAddress(java.lang.String, java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+ method public void setNickname(java.lang.String, java.lang.String, java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+ method public void switchToProfile(java.lang.String, java.lang.String, boolean, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo>);
+ field public static final int CANCEL_REASON_END_USER_REJECTED = 0; // 0x0
+ field public static final int CANCEL_REASON_POSTPONED = 1; // 0x1
+ field public static final int CANCEL_REASON_PPR_NOT_ALLOWED = 3; // 0x3
+ field public static final int CANCEL_REASON_TIMEOUT = 2; // 0x2
+ field public static final int RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES = 2; // 0x2
+ field public static final int RESET_OPTION_DELETE_OPERATIONAL_PROFILES = 1; // 0x1
+ field public static final int RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS = 4; // 0x4
+ field public static final int RESULT_OK = 0; // 0x0
+ field public static final int RESULT_UNKNOWN_ERROR = -1; // 0xffffffff
+ }
+
+ public static abstract class EuiccCardManager.CancelReason implements java.lang.annotation.Annotation {
+ }
+
+ public static abstract class EuiccCardManager.ResetOption implements java.lang.annotation.Annotation {
+ }
+
+ public static abstract interface EuiccCardManager.ResultCallback<T> {
+ method public abstract void onComplete(int, T);
+ }
+
+ public class EuiccManager {
+ method public void continueOperation(android.content.Intent, android.os.Bundle);
+ method public void getDefaultDownloadableSubscriptionList(android.app.PendingIntent);
+ method public void getDownloadableSubscriptionMetadata(android.telephony.euicc.DownloadableSubscription, android.app.PendingIntent);
+ method public int getOtaStatus();
+ field public static final java.lang.String ACTION_OTA_STATUS_CHANGED = "android.telephony.euicc.action.OTA_STATUS_CHANGED";
+ field public static final java.lang.String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION = "android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION";
+ field public static final int EUICC_OTA_FAILED = 2; // 0x2
+ field public static final int EUICC_OTA_IN_PROGRESS = 1; // 0x1
+ field public static final int EUICC_OTA_NOT_NEEDED = 4; // 0x4
+ field public static final int EUICC_OTA_STATUS_UNAVAILABLE = 5; // 0x5
+ field public static final int EUICC_OTA_SUCCEEDED = 3; // 0x3
+ field public static final java.lang.String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION";
+ field public static final java.lang.String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS";
+ }
+
+ public static abstract class EuiccManager.OtaStatus implements java.lang.annotation.Annotation {
+ }
+
+ public final class EuiccNotification implements android.os.Parcelable {
+ ctor public EuiccNotification(int, java.lang.String, int, byte[]);
+ method public int describeContents();
+ method public byte[] getData();
+ method public int getEvent();
+ method public int getSeq();
+ method public java.lang.String getTargetAddr();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final int ALL_EVENTS = 15; // 0xf
+ field public static final android.os.Parcelable.Creator<android.telephony.euicc.EuiccNotification> CREATOR;
+ field public static final int EVENT_DELETE = 8; // 0x8
+ field public static final int EVENT_DISABLE = 4; // 0x4
+ field public static final int EVENT_ENABLE = 2; // 0x2
+ field public static final int EVENT_INSTALL = 1; // 0x1
+ }
+
+ public static abstract class EuiccNotification.Event implements java.lang.annotation.Annotation {
+ }
+
+ public final class EuiccRulesAuthTable implements android.os.Parcelable {
+ method public int describeContents();
+ method public int findIndex(int, android.service.carrier.CarrierIdentifier);
+ method public boolean hasPolicyRuleFlag(int, int);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.euicc.EuiccRulesAuthTable> CREATOR;
+ field public static final int POLICY_RULE_FLAG_CONSENT_REQUIRED = 1; // 0x1
+ }
+
+ public static final class EuiccRulesAuthTable.Builder {
+ ctor public EuiccRulesAuthTable.Builder(int);
+ method public android.telephony.euicc.EuiccRulesAuthTable.Builder add(int, java.util.List<android.service.carrier.CarrierIdentifier>, int);
+ method public android.telephony.euicc.EuiccRulesAuthTable build();
+ }
+
+ public static abstract class EuiccRulesAuthTable.PolicyRuleFlag implements java.lang.annotation.Annotation {
+ }
+
+}
+
package android.telephony.ims {
public final class ImsCallForwardInfo implements android.os.Parcelable {
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk
index 8eea944..67b9089 100644
--- a/cmds/statsd/Android.mk
+++ b/cmds/statsd/Android.mk
@@ -19,11 +19,9 @@
../../core/java/android/os/IStatsManager.aidl \
src/stats_log.proto \
src/statsd_config.proto \
- src/statsd_internal.proto \
src/atoms.proto \
- src/field_util.cpp \
+ src/FieldValue.cpp \
src/stats_log_util.cpp \
- src/dimension.cpp \
src/anomaly/AnomalyMonitor.cpp \
src/anomaly/AnomalyTracker.cpp \
src/anomaly/DurationAnomalyTracker.cpp \
@@ -172,7 +170,6 @@
LOCAL_SRC_FILES := \
$(statsd_common_src) \
- tests/dimension_test.cpp \
tests/AnomalyMonitor_test.cpp \
tests/anomaly/AnomalyTracker_test.cpp \
tests/ConfigManager_test.cpp \
@@ -184,6 +181,7 @@
tests/MetricsManager_test.cpp \
tests/StatsLogProcessor_test.cpp \
tests/UidMap_test.cpp \
+ tests/FieldValue_test.cpp \
tests/condition/CombinationConditionTracker_test.cpp \
tests/condition/SimpleConditionTracker_test.cpp \
tests/metrics/OringDurationTracker_test.cpp \
diff --git a/cmds/statsd/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp
new file mode 100644
index 0000000..7b0b69a
--- /dev/null
+++ b/cmds/statsd/src/FieldValue.cpp
@@ -0,0 +1,186 @@
+/*
+ * 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.
+ */
+
+#define DEBUG false
+#include "Log.h"
+#include "FieldValue.h"
+#include "HashableDimensionKey.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+bool Field::matches(const Matcher& matcher) const {
+ if (mTag != matcher.mMatcher.getTag()) {
+ return false;
+ }
+ if ((mField & matcher.mMask) == matcher.mMatcher.getField()) {
+ return true;
+ }
+
+ return false;
+};
+
+void translateFieldMatcher(int tag, const FieldMatcher& matcher, int depth, int* pos, int* mask,
+ std::vector<Matcher>* output) {
+ if (depth > kMaxLogDepth) {
+ ALOGE("depth > 2");
+ return;
+ }
+
+ pos[depth] = matcher.field();
+ mask[depth] = 0x7f;
+
+ if (matcher.has_position()) {
+ depth++;
+ if (depth > 2) {
+ return;
+ }
+ switch (matcher.position()) {
+ case Position::ANY:
+ pos[depth] = 0;
+ mask[depth] = 0;
+ break;
+ case Position::FIRST:
+ pos[depth] = 1;
+ mask[depth] = 0x7f;
+ break;
+ case Position::LAST:
+ pos[depth] = 0x80;
+ mask[depth] = 0x80;
+ break;
+ case Position::POSITION_UNKNOWN:
+ pos[depth] = 0;
+ mask[depth] = 0;
+ break;
+ }
+ }
+
+ if (matcher.child_size() == 0) {
+ output->push_back(Matcher(Field(tag, pos, depth), encodeMatcherMask(mask, depth)));
+ Matcher matcher = Matcher(Field(tag, pos, depth), encodeMatcherMask(mask, depth));
+ } else {
+ for (const auto& child : matcher.child()) {
+ translateFieldMatcher(tag, child, depth + 1, pos, mask, output);
+ }
+ }
+}
+
+void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output) {
+ int pos[] = {1, 1, 1};
+ int mask[] = {0x7f, 0x7f, 0x7f};
+ int tag = matcher.field();
+ for (const auto& child : matcher.child()) {
+ translateFieldMatcher(tag, child, 0, pos, mask, output);
+ }
+}
+
+bool isAttributionUidField(const FieldValue& value) {
+ int field = value.mField.getField() & 0xff007f;
+ if (field == 0x10001 && value.mValue.getType() == INT) {
+ return true;
+ }
+ return false;
+}
+
+bool isAttributionUidField(const Field& field, const Value& value) {
+ int f = field.getField() & 0xff007f;
+ if (f == 0x10001 && value.getType() == INT) {
+ return true;
+ }
+ return false;
+}
+
+Value::Value(const Value& from) {
+ type = from.getType();
+ switch (type) {
+ case INT:
+ int_value = from.int_value;
+ break;
+ case LONG:
+ long_value = from.long_value;
+ break;
+ case FLOAT:
+ float_value = from.float_value;
+ break;
+ case STRING:
+ str_value = from.str_value;
+ break;
+ }
+}
+
+std::string Value::toString() const {
+ switch (type) {
+ case INT:
+ return std::to_string(int_value) + "[I]";
+ case LONG:
+ return std::to_string(long_value) + "[L]";
+ case FLOAT:
+ return std::to_string(float_value) + "[F]";
+ case STRING:
+ return str_value + "[S]";
+ }
+}
+
+bool Value::operator==(const Value& that) const {
+ if (type != that.getType()) return false;
+
+ switch (type) {
+ case INT:
+ return int_value == that.int_value;
+ case LONG:
+ return long_value == that.long_value;
+ case FLOAT:
+ return float_value == that.float_value;
+ case STRING:
+ return str_value == that.str_value;
+ }
+}
+
+bool Value::operator!=(const Value& that) const {
+ if (type != that.getType()) return true;
+ switch (type) {
+ case INT:
+ return int_value != that.int_value;
+ case LONG:
+ return long_value != that.long_value;
+ case FLOAT:
+ return float_value != that.float_value;
+ case STRING:
+ return str_value != that.str_value;
+ }
+}
+
+bool Value::operator<(const Value& that) const {
+ if (type != that.getType()) return type < that.getType();
+
+ switch (type) {
+ case INT:
+ return int_value < that.int_value;
+ case LONG:
+ return long_value < that.long_value;
+ case FLOAT:
+ return float_value < that.float_value;
+ case STRING:
+ return str_value < that.str_value;
+ default:
+ return false;
+ }
+}
+
+} // namespace statsd
+} // namespace os
+} // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h
new file mode 100644
index 0000000..7484108
--- /dev/null
+++ b/cmds/statsd/src/FieldValue.h
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+class HashableDimensionKey;
+struct Matcher;
+struct Field;
+struct FieldValue;
+
+const int32_t kAttributionField = 1;
+const int32_t kMaxLogDepth = 2;
+const int32_t kLastBitMask = 0x80;
+const int32_t kClearLastBitDeco = 0x7f;
+
+enum Type { INT, LONG, FLOAT, STRING };
+
+
+static int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth) {
+ int32_t field = 0;
+ for (int32_t i = 0; i <= depth; i++) {
+ int32_t shiftBits = 8 * (kMaxLogDepth - i);
+ field |= (pos[i] << shiftBits);
+ }
+
+ if (includeDepth) {
+ field |= (depth << 24);
+ }
+ return field;
+}
+
+static int32_t encodeMatcherMask(int32_t mask[], int32_t depth) {
+ return getEncodedField(mask, depth, false) | 0xff000000;
+}
+
+// Get the encoded field for a leaf with a [field] number at depth 0;
+static int32_t getSimpleField(size_t field) {
+ return ((int32_t)field << 8 * 2);
+}
+
+/**
+ * Field is a wrapper class for 2 integers that represents the field of a log element in its Atom
+ * proto.
+ * [mTag]: the atom id.
+ * [mField]: encoded path from the root (atom) to leaf.
+ *
+ * For example:
+ * WakeLockStateChanged {
+ * repeated AttributionNode = 1;
+ * int state = 2;
+ * string tag = 3;
+ * }
+ * Read from logd, the items are structured as below:
+ * [[[1000, "tag"], [2000, "tag2"],], 2,"hello"]
+ *
+ * When we read through the list, we will encode each field in a 32bit integer.
+ * 8bit segments |--------|--------|--------|--------|
+ * Depth field0 [L]field1 [L]field1
+ *
+ * The first 8 bits are the depth of the field. for example, the uid 1000 has depth 2.
+ * The following 3 8-bit are for the item's position at each level.
+ * The first bit of each 8bits field is reserved to mark if the item is the last item at that level
+ * this is to make matching easier later.
+ *
+ * The above wakelock event is translated into FieldValue pairs.
+ * 0x02010101->1000
+ * 0x02010182->tag
+ * 0x02018201->2000
+ * 0x02018282->tag2
+ * 0x00020000->2
+ * 0x00030000->"hello"
+ *
+ * This encoding is the building block for the later operations.
+ * Please see the definition for Matcher below to see how the matching is done.
+ */
+struct Field {
+private:
+ int32_t mTag;
+ int32_t mField;
+
+public:
+ Field(int32_t tag, int32_t pos[], int32_t depth) : mTag(tag) {
+ mField = getEncodedField(pos, depth, true);
+ }
+
+ Field(const Field& from) : mTag(from.getTag()), mField(from.getField()) {
+ }
+
+ Field(int32_t tag, int32_t field) : mTag(tag), mField(field){};
+
+ inline void setField(int32_t field) {
+ mField = field;
+ }
+
+ inline void setTag(int32_t tag) {
+ mTag = tag;
+ }
+
+ inline void decorateLastPos(int32_t depth) {
+ int32_t mask = kLastBitMask << 8 * (kMaxLogDepth - depth);
+ mField |= mask;
+ }
+
+ inline int32_t getTag() const {
+ return mTag;
+ }
+
+ inline int32_t getDepth() const {
+ return (mField >> 24);
+ }
+
+ inline int32_t getPath(int32_t depth) const {
+ if (depth > 2 || depth < 0) return 0;
+
+ int32_t field = (mField & 0x00ffffff);
+ int32_t mask = 0xffffffff;
+ return (field & (mask << 8 * (kMaxLogDepth - depth)));
+ }
+
+ inline int32_t getPrefix(int32_t depth) const {
+ if (depth == 0) return 0;
+ return getPath(depth - 1);
+ }
+
+ inline int32_t getField() const {
+ return mField;
+ }
+
+ inline int32_t getRawPosAtDepth(int32_t depth) const {
+ int32_t field = (mField & 0x00ffffff);
+ int32_t shift = 8 * (kMaxLogDepth - depth);
+ int32_t mask = 0xff << shift;
+
+ return (field & mask) >> shift;
+ }
+
+ inline int32_t getPosAtDepth(int32_t depth) const {
+ return getRawPosAtDepth(depth) & kClearLastBitDeco;
+ }
+
+ // Check if the first bit of the 8-bit segment for depth is 1
+ inline bool isLastPos(int32_t depth) const {
+ int32_t field = (mField & 0x00ffffff);
+ int32_t mask = kLastBitMask << 8 * (kMaxLogDepth - depth);
+ return (field & mask) != 0;
+ }
+
+ // if the 8-bit segment is all 0's
+ inline bool isAnyPosMatcher(int32_t depth) const {
+ return getDepth() >= depth && getRawPosAtDepth(depth) == 0;
+ }
+ // if the 8bit is 0x80 (1000 0000)
+ inline bool isLastPosMatcher(int32_t depth) const {
+ return getDepth() >= depth && getRawPosAtDepth(depth) == kLastBitMask;
+ }
+
+ inline bool operator==(const Field& that) const {
+ return mTag == that.getTag() && mField == that.getField();
+ };
+
+ inline bool operator!=(const Field& that) const {
+ return mTag != that.getTag() || mField != that.getField();
+ };
+
+ bool operator<(const Field& that) const {
+ if (mTag != that.getTag()) {
+ return mTag < that.getTag();
+ }
+
+ if (mField != that.getField()) {
+ return mField < that.getField();
+ }
+
+ return false;
+ }
+ bool matches(const Matcher& that) const;
+};
+
+/**
+ * Matcher represents a leaf matcher in the FieldMatcher in statsd_config.
+ *
+ * It contains all information needed to match one or more leaf node.
+ * All information is encoded in a Field(2 ints) and a bit mask(1 int).
+ *
+ * For example, to match the first/any/last uid field in attribution chain in Atom 10,
+ * we have the following FieldMatcher in statsd_config
+ * FieldMatcher {
+ * field:10
+ * FieldMatcher {
+ * field:1
+ * position: any/last/first
+ * FieldMatcher {
+ * field:1
+ * }
+ * }
+ * }
+ *
+ * We translate the FieldMatcher into a Field, and mask
+ * First: [Matcher Field] 0x02010101 [Mask]0xffff7fff
+ * Last: [Matcher Field] 0x02018001 [Mask]0xffff80ff
+ * Any: [Matcher Field] 0x02010001 [Mask]0xffff00ff
+ *
+ * [To match a log Field with a Matcher] we apply the bit mask to the log Field and check if
+ * the result is equal to the Matcher Field. That's a bit wise AND operation + check if 2 ints are
+ * equal. Nothing can beat the performance of this matching algorithm.
+ *
+ * TODO: ADD EXAMPLE HERE.
+ */
+struct Matcher {
+ Matcher(const Field& matcher, int32_t mask) : mMatcher(matcher), mMask(mask){};
+
+ const Field mMatcher;
+ const int32_t mMask;
+
+ bool hasAnyPositionMatcher(int* prefix) const {
+ if (mMatcher.getDepth() == 2 && mMatcher.getRawPosAtDepth(2) == 0) {
+ (*prefix) = mMatcher.getPrefix(2);
+ return true;
+ }
+ return false;
+ }
+};
+
+/**
+ * A wrapper for a union type to contain multiple types of values.
+ *
+ */
+struct Value {
+ Value(int32_t v) {
+ int_value = v;
+ type = INT;
+ }
+
+ Value(int64_t v) {
+ long_value = v;
+ type = LONG;
+ }
+
+ Value(float v) {
+ float_value = v;
+ type = FLOAT;
+ }
+
+ Value(const std::string& v) {
+ str_value = v;
+ type = STRING;
+ }
+
+ void setInt(int32_t v) {
+ int_value = v;
+ type = INT;
+ }
+
+ void setLong(int64_t v) {
+ long_value = v;
+ type = LONG;
+ }
+
+ union {
+ int32_t int_value;
+ int64_t long_value;
+ float float_value;
+ };
+ std::string str_value;
+
+ Type type;
+
+ std::string toString() const;
+
+ Type getType() const {
+ return type;
+ }
+
+ Value(const Value& from);
+
+ bool operator==(const Value& that) const;
+ bool operator!=(const Value& that) const;
+
+ bool operator<(const Value& that) const;
+
+private:
+ Value(){};
+};
+
+/**
+ * Represents a log item, or a dimension item (They are essentially the same).
+ */
+struct FieldValue {
+ FieldValue(const Field& field, const Value& value) : mField(field), mValue(value) {
+ }
+ bool operator==(const FieldValue& that) const {
+ return mField == that.mField && mValue == that.mValue;
+ }
+ bool operator!=(const FieldValue& that) const {
+ return mField != that.mField || mValue != that.mValue;
+ }
+ bool operator<(const FieldValue& that) const {
+ if (mField != that.mField) {
+ return mField < that.mField;
+ }
+
+ if (mValue != that.mValue) {
+ return mValue < that.mValue;
+ }
+
+ return false;
+ }
+
+ Field mField;
+ Value mValue;
+};
+
+bool isAttributionUidField(const FieldValue& value);
+
+void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output);
+
+bool isAttributionUidField(const Field& field, const Value& value);
+} // namespace statsd
+} // namespace os
+} // namespace android
diff --git a/cmds/statsd/src/HashableDimensionKey.cpp b/cmds/statsd/src/HashableDimensionKey.cpp
index 8483b02..68e2176 100644
--- a/cmds/statsd/src/HashableDimensionKey.cpp
+++ b/cmds/statsd/src/HashableDimensionKey.cpp
@@ -13,177 +13,253 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#define DEBUG false // STOPSHIP if true
+#include "Log.h"
#include "HashableDimensionKey.h"
-#include "dimension.h"
+#include "FieldValue.h"
namespace android {
namespace os {
namespace statsd {
+using std::vector;
-android::hash_t hashDimensionsValue(int64_t seed, const DimensionsValue& value) {
- android::hash_t hash = seed;
- hash = android::JenkinsHashMix(hash, android::hash_type(value.field()));
-
- hash = android::JenkinsHashMix(hash, android::hash_type((int)value.value_case()));
- switch (value.value_case()) {
- case DimensionsValue::ValueCase::kValueStr:
- hash = android::JenkinsHashMix(
- hash,
- static_cast<uint32_t>(std::hash<std::string>()(value.value_str())));
- break;
- case DimensionsValue::ValueCase::kValueInt:
- hash = android::JenkinsHashMix(hash, android::hash_type(value.value_int()));
- break;
- case DimensionsValue::ValueCase::kValueLong:
- hash = android::JenkinsHashMix(
- hash, android::hash_type(static_cast<int64_t>(value.value_long())));
- break;
- case DimensionsValue::ValueCase::kValueBool:
- hash = android::JenkinsHashMix(hash, android::hash_type(value.value_bool()));
- break;
- case DimensionsValue::ValueCase::kValueFloat: {
- float floatVal = value.value_float();
- hash = android::JenkinsHashMixBytes(hash, (uint8_t*)&floatVal, sizeof(float));
- break;
- }
- case DimensionsValue::ValueCase::kValueTuple: {
- hash = android::JenkinsHashMix(hash, android::hash_type(
- value.value_tuple().dimensions_value_size()));
- for (int i = 0; i < value.value_tuple().dimensions_value_size(); ++i) {
- hash = android::JenkinsHashMix(
- hash,
- hashDimensionsValue(value.value_tuple().dimensions_value(i)));
+android::hash_t hashDimension(const HashableDimensionKey& value) {
+ android::hash_t hash = 0;
+ for (const auto& fieldValue : value.getValues()) {
+ hash = android::JenkinsHashMix(hash, android::hash_type((int)fieldValue.mField.getField()));
+ hash = android::JenkinsHashMix(hash, android::hash_type((int)fieldValue.mField.getTag()));
+ hash = android::JenkinsHashMix(hash, android::hash_type((int)fieldValue.mValue.getType()));
+ switch (fieldValue.mValue.getType()) {
+ case INT:
+ hash = android::JenkinsHashMix(hash,
+ android::hash_type(fieldValue.mValue.int_value));
+ break;
+ case LONG:
+ hash = android::JenkinsHashMix(hash,
+ android::hash_type(fieldValue.mValue.long_value));
+ break;
+ case STRING:
+ hash = android::JenkinsHashMix(hash, static_cast<uint32_t>(std::hash<std::string>()(
+ fieldValue.mValue.str_value)));
+ break;
+ case FLOAT: {
+ float floatVal = fieldValue.mValue.float_value;
+ hash = android::JenkinsHashMixBytes(hash, (uint8_t*)&floatVal, sizeof(float));
+ break;
}
- break;
}
- case DimensionsValue::ValueCase::VALUE_NOT_SET:
- break;
}
return JenkinsHashWhiten(hash);
}
-android::hash_t hashDimensionsValue(const DimensionsValue& value) {
- return hashDimensionsValue(0, value);
-}
-
-android::hash_t hashMetricDimensionKey(int64_t seed, const MetricDimensionKey& dimensionKey) {
- android::hash_t hash = seed;
- hash = android::JenkinsHashMix(hash, std::hash<MetricDimensionKey>{}(dimensionKey));
- return JenkinsHashWhiten(hash);
-}
-
-using std::string;
-
-string HashableDimensionKey::toString() const {
- return DimensionsValueToString(getDimensionsValue());
-}
-
-bool EqualsTo(const DimensionsValue& s1, const DimensionsValue& s2) {
- if (s1.field() != s2.field()) {
- return false;
- }
- if (s1.value_case() != s2.value_case()) {
- return false;
- }
- switch (s1.value_case()) {
- case DimensionsValue::ValueCase::kValueStr:
- return (s1.value_str() == s2.value_str());
- case DimensionsValue::ValueCase::kValueInt:
- return s1.value_int() == s2.value_int();
- case DimensionsValue::ValueCase::kValueLong:
- return s1.value_long() == s2.value_long();
- case DimensionsValue::ValueCase::kValueBool:
- return s1.value_bool() == s2.value_bool();
- case DimensionsValue::ValueCase::kValueFloat:
- return s1.value_float() == s2.value_float();
- case DimensionsValue::ValueCase::kValueTuple:
- {
- if (s1.value_tuple().dimensions_value_size() !=
- s2.value_tuple().dimensions_value_size()) {
- return false;
- }
- bool allMatched = true;
- for (int i = 0; allMatched && i < s1.value_tuple().dimensions_value_size(); ++i) {
- allMatched &= EqualsTo(s1.value_tuple().dimensions_value(i),
- s2.value_tuple().dimensions_value(i));
- }
- return allMatched;
+// Filter fields using the matchers and output the results as a HashableDimensionKey.
+// Note: HashableDimensionKey is just a wrapper for vector<FieldValue>
+bool filterValues(const vector<Matcher>& matcherFields, const vector<FieldValue>& values,
+ vector<HashableDimensionKey>* output) {
+ output->push_back(HashableDimensionKey());
+ // Top level is only tag id. Now take the real child matchers
+ int prevAnyMatcherPrefix = 0;
+ size_t prevPrevFanout = 0;
+ size_t prevFanout = 0;
+ // For each matcher get matched results.
+ for (const auto& matcher : matcherFields) {
+ vector<FieldValue> matchedResults;
+ for (const auto& value : values) {
+ // TODO: potential optimization here to break early because all fields are naturally
+ // sorted.
+ int32_t filteredField;
+ if (value.mField.matches(matcher)) {
+ matchedResults.push_back(FieldValue(
+ Field(value.mField.getTag(), (value.mField.getField() & matcher.mMask)),
+ value.mValue));
}
- case DimensionsValue::ValueCase::VALUE_NOT_SET:
- default:
- return true;
- }
-}
+ }
-bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2) {
- if (s1.field() != s2.field()) {
- return s1.field() < s2.field();
- }
- if (s1.value_case() != s2.value_case()) {
- return s1.value_case() < s2.value_case();
- }
- switch (s1.value_case()) {
- case DimensionsValue::ValueCase::kValueStr:
- return s1.value_str() < s2.value_str();
- case DimensionsValue::ValueCase::kValueInt:
- return s1.value_int() < s2.value_int();
- case DimensionsValue::ValueCase::kValueLong:
- return s1.value_long() < s2.value_long();
- case DimensionsValue::ValueCase::kValueBool:
- return (int)s1.value_bool() < (int)s2.value_bool();
- case DimensionsValue::ValueCase::kValueFloat:
- return s1.value_float() < s2.value_float();
- case DimensionsValue::ValueCase::kValueTuple:
- {
- if (s1.value_tuple().dimensions_value_size() !=
- s2.value_tuple().dimensions_value_size()) {
- return s1.value_tuple().dimensions_value_size() <
- s2.value_tuple().dimensions_value_size();
- }
- for (int i = 0; i < s1.value_tuple().dimensions_value_size(); ++i) {
- if (EqualsTo(s1.value_tuple().dimensions_value(i),
- s2.value_tuple().dimensions_value(i))) {
- continue;
- } else {
- return LessThan(s1.value_tuple().dimensions_value(i),
- s2.value_tuple().dimensions_value(i));
- }
- }
+ if (matchedResults.size() == 0) {
+ VLOG("We can't find a dimension value for matcher (%d)%#x.", matcher.mMatcher.getTag(),
+ matcher.mMatcher.getField());
+ continue;
+ }
+
+ if (matchedResults.size() == 1) {
+ for (auto& dimension : *output) {
+ dimension.addValue(matchedResults[0]);
+ }
+ prevAnyMatcherPrefix = 0;
+ prevFanout = 0;
+ continue;
+ }
+
+ // All the complexity below is because we support ANY in dimension.
+ bool createFanout = true;
+ // createFanout is true when the matcher doesn't need to follow the prev matcher's
+ // order.
+ // e.g., get (uid, tag) from any position in attribution. because we have translated
+ // it as 2 matchers, they need to follow the same ordering, we can't create a cross
+ // product of all uid and tags.
+ // However, if the 2 matchers have different prefix, they will create a cross product
+ // e.g., [any uid] [any some other repeated field], we will create a cross product for them
+ if (prevAnyMatcherPrefix != 0) {
+ int anyMatcherPrefix = 0;
+ bool isAnyMatcher = matcher.hasAnyPositionMatcher(&anyMatcherPrefix);
+ if (isAnyMatcher && anyMatcherPrefix == prevAnyMatcherPrefix) {
+ createFanout = false;
+ } else {
+ prevAnyMatcherPrefix = anyMatcherPrefix;
+ }
+ }
+
+ // Each matcher should match exact one field, unless position is ANY
+ // When x number of fields matches a matcher, the returned dimension
+ // size is multiplied by x.
+ int oldSize;
+ if (createFanout) {
+ // First create fanout (fanout size is matchedResults.Size which could be one,
+ // which means we do nothing here)
+ oldSize = output->size();
+ for (size_t i = 1; i < matchedResults.size(); i++) {
+ output->insert(output->end(), output->begin(), output->begin() + oldSize);
+ }
+ prevPrevFanout = oldSize;
+ prevFanout = matchedResults.size();
+ } else {
+ // If we should not create fanout, e.g., uid tag from same position should be remain
+ // together.
+ oldSize = prevPrevFanout;
+ if (prevFanout != matchedResults.size()) {
+ // sanity check.
+ ALOGE("2 Any matcher result in different output");
return false;
}
- case DimensionsValue::ValueCase::VALUE_NOT_SET:
- default:
- return false;
+ }
+ // now add the matched field value to output
+ for (size_t i = 0; i < matchedResults.size(); i++) {
+ for (int j = 0; j < oldSize; j++) {
+ (*output)[i * oldSize + j].addValue(matchedResults[i]);
+ }
+ }
}
+
+ return output->size() > 0 && (*output)[0].getValues().size() > 0;
+}
+
+void filterGaugeValues(const std::vector<Matcher>& matcherFields,
+ const std::vector<FieldValue>& values, std::vector<FieldValue>* output) {
+ for (const auto& field : matcherFields) {
+ for (const auto& value : values) {
+ int filteredField;
+ if (value.mField.matches(field)) {
+ output->push_back(value);
+ }
+ }
+ }
+}
+
+void getDimensionForCondition(const LogEvent& event, Metric2Condition links,
+ vector<HashableDimensionKey>* conditionDimension) {
+ // Get the dimension first by using dimension from what.
+ filterValues(links.metricFields, event.getValues(), conditionDimension);
+
+ // Then replace the field with the dimension from condition.
+ for (auto& dim : *conditionDimension) {
+ size_t count = dim.getValues().size();
+ if (count != links.conditionFields.size()) {
+ // ALOGE("WTF condition link is bad");
+ return;
+ }
+
+ for (size_t i = 0; i < count; i++) {
+ dim.mutableValue(i)->mField.setField(links.conditionFields[i].mMatcher.getField());
+ dim.mutableValue(i)->mField.setTag(links.conditionFields[i].mMatcher.getTag());
+ }
+ }
+}
+
+bool LessThan(const vector<FieldValue>& s1, const vector<FieldValue>& s2) {
+ if (s1.size() != s2.size()) {
+ return s1.size() < s2.size();
+ }
+
+ size_t count = s1.size();
+ for (size_t i = 0; i < count; i++) {
+ if (s1[i] != s2[i]) {
+ return s1[i] < s2[i];
+ }
+ }
+ return false;
}
bool HashableDimensionKey::operator==(const HashableDimensionKey& that) const {
- return EqualsTo(getDimensionsValue(), that.getDimensionsValue());
+ if (mValues.size() != that.getValues().size()) {
+ return false;
+ }
+ size_t count = mValues.size();
+ for (size_t i = 0; i < count; i++) {
+ if (mValues[i] != (that.getValues())[i]) {
+ return false;
+ }
+ }
+ return true;
};
bool HashableDimensionKey::operator<(const HashableDimensionKey& that) const {
- return LessThan(getDimensionsValue(), that.getDimensionsValue());
+ return LessThan(getValues(), that.getValues());
};
-string MetricDimensionKey::toString() const {
- string flattened = mDimensionKeyInWhat.toString();
- flattened += mDimensionKeyInCondition.toString();
- return flattened;
+bool HashableDimensionKey::contains(const HashableDimensionKey& that) const {
+ if (mValues.size() < that.getValues().size()) {
+ return false;
+ }
+
+ if (mValues.size() == that.getValues().size()) {
+ return (*this) == that;
+ }
+
+ for (const auto& value : that.getValues()) {
+ bool found = false;
+ for (const auto& myValue : mValues) {
+ if (value.mField == myValue.mField && value.mValue == myValue.mValue) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+string HashableDimensionKey::toString() const {
+ std::string output;
+ for (const auto& value : mValues) {
+ output += StringPrintf("(%d)%#x->%s ", value.mField.getTag(), value.mField.getField(),
+ value.mValue.toString().c_str());
+ }
+ return output;
}
bool MetricDimensionKey::operator==(const MetricDimensionKey& that) const {
return mDimensionKeyInWhat == that.getDimensionKeyInWhat() &&
- mDimensionKeyInCondition == that.getDimensionKeyInCondition();
+ mDimensionKeyInCondition == that.getDimensionKeyInCondition();
};
+string MetricDimensionKey::toString() const {
+ return mDimensionKeyInWhat.toString() + mDimensionKeyInCondition.toString();
+}
+
bool MetricDimensionKey::operator<(const MetricDimensionKey& that) const {
- return toString().compare(that.toString()) < 0;
-};
+ if (mDimensionKeyInWhat < that.getDimensionKeyInWhat()) {
+ return true;
+ } else if (that.getDimensionKeyInWhat() < mDimensionKeyInWhat) {
+ return false;
+ }
-bool compareDimensionsValue(const DimensionsValue& s1, const DimensionsValue& s2) {
- return EqualsTo(s1, s2);
+ return mDimensionKeyInCondition < that.getDimensionKeyInCondition();
}
+
} // namespace statsd
} // namespace os
} // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/src/HashableDimensionKey.h b/cmds/statsd/src/HashableDimensionKey.h
index a31d7a6..89fe317 100644
--- a/cmds/statsd/src/HashableDimensionKey.h
+++ b/cmds/statsd/src/HashableDimensionKey.h
@@ -17,44 +17,66 @@
#pragma once
#include <utils/JenkinsHash.h>
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
+#include <vector>
+#include "FieldValue.h"
+#include "android-base/stringprintf.h"
+#include "logd/LogEvent.h"
namespace android {
namespace os {
namespace statsd {
+using android::base::StringPrintf;
+
+struct Metric2Condition {
+ int64_t conditionId;
+ std::vector<Matcher> metricFields;
+ std::vector<Matcher> conditionFields;
+};
+
class HashableDimensionKey {
public:
- explicit HashableDimensionKey(const DimensionsValue& dimensionsValue)
- : mDimensionsValue(dimensionsValue){};
+ explicit HashableDimensionKey(const std::vector<FieldValue>& values) {
+ mValues = values;
+ }
HashableDimensionKey(){};
- HashableDimensionKey(const HashableDimensionKey& that)
- : mDimensionsValue(that.getDimensionsValue()){};
+ HashableDimensionKey(const HashableDimensionKey& that) : mValues(that.getValues()){};
- HashableDimensionKey& operator=(const HashableDimensionKey& from) = default;
+ inline void addValue(const FieldValue& value) {
+ mValues.push_back(value);
+ }
+
+ inline const std::vector<FieldValue>& getValues() const {
+ return mValues;
+ }
+
+ inline std::vector<FieldValue>* mutableValues() {
+ return &mValues;
+ }
+
+ inline FieldValue* mutableValue(size_t i) {
+ if (i >= 0 && i < mValues.size()) {
+ return &(mValues[i]);
+ }
+ return nullptr;
+ }
std::string toString() const;
- inline const DimensionsValue& getDimensionsValue() const {
- return mDimensionsValue;
- }
-
- inline DimensionsValue* getMutableDimensionsValue() {
- return &mDimensionsValue;
+ inline const char* c_str() const {
+ return toString().c_str();
}
bool operator==(const HashableDimensionKey& that) const;
bool operator<(const HashableDimensionKey& that) const;
- inline const char* c_str() const {
- return toString().c_str();
- }
+ bool contains(const HashableDimensionKey& that) const;
private:
- DimensionsValue mDimensionsValue;
+ std::vector<FieldValue> mValues;
};
class MetricDimensionKey {
@@ -83,7 +105,7 @@
}
bool hasDimensionKeyInCondition() const {
- return mDimensionKeyInCondition.getDimensionsValue().has_field();
+ return mDimensionKeyInCondition.getValues().size() > 0;
}
bool operator==(const MetricDimensionKey& that) const;
@@ -98,11 +120,32 @@
HashableDimensionKey mDimensionKeyInCondition;
};
-bool compareDimensionsValue(const DimensionsValue& s1, const DimensionsValue& s2);
+android::hash_t hashDimension(const HashableDimensionKey& key);
-android::hash_t hashDimensionsValue(int64_t seed, const DimensionsValue& value);
-android::hash_t hashDimensionsValue(const DimensionsValue& value);
-android::hash_t hashMetricDimensionKey(int64_t see, const MetricDimensionKey& dimensionKey);
+/**
+ * Creating HashableDimensionKeys from FieldValues using matcher.
+ *
+ * This function may make modifications to the Field if the matcher has Position=LAST or ANY in
+ * it. This is because: for example, when we create dimension from last uid in attribution chain,
+ * In one event, uid 1000 is at position 5 and it's the last
+ * In another event, uid 1000 is at position 6, and it's the last
+ * these 2 events should be mapped to the same dimension. So we will remove the original position
+ * from the dimension key for the uid field (by applying 0x80 bit mask).
+ */
+bool filterValues(const std::vector<Matcher>& matcherFields, const std::vector<FieldValue>& values,
+ std::vector<HashableDimensionKey>* output);
+
+/**
+ * Filter the values from FieldValues using the matchers.
+ *
+ * In contrast to the above function, this function will not do any modification to the original
+ * data. Considering it as taking a snapshot on the atom event.
+ */
+void filterGaugeValues(const std::vector<Matcher>& matchers, const std::vector<FieldValue>& values,
+ std::vector<FieldValue>* output);
+
+void getDimensionForCondition(const LogEvent& event, Metric2Condition links,
+ std::vector<HashableDimensionKey>* conditionDimension);
} // namespace statsd
} // namespace os
@@ -116,17 +159,15 @@
template <>
struct hash<HashableDimensionKey> {
std::size_t operator()(const HashableDimensionKey& key) const {
- return hashDimensionsValue(key.getDimensionsValue());
+ return hashDimension(key);
}
};
template <>
struct hash<MetricDimensionKey> {
std::size_t operator()(const MetricDimensionKey& key) const {
- android::hash_t hash = hashDimensionsValue(
- key.getDimensionKeyInWhat().getDimensionsValue());
- hash = android::JenkinsHashMix(hash,
- hashDimensionsValue(key.getDimensionKeyInCondition().getDimensionsValue()));
+ android::hash_t hash = hashDimension(key.getDimensionKeyInWhat());
+ hash = android::JenkinsHashMix(hash, hashDimension(key.getDimensionKeyInCondition()));
return android::JenkinsHashWhiten(hash);
}
};
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 7662c40..3a20b12 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define DEBUG false // STOPSHIP if true
+#define DEBUG true // STOPSHIP if true
#include "Log.h"
#include "statslog.h"
@@ -25,8 +25,6 @@
#include "guardrail/StatsdStats.h"
#include "metrics/CountMetricProducer.h"
#include "external/StatsPullerManager.h"
-#include "dimension.h"
-#include "field_util.h"
#include "stats_util.h"
#include "storage/StorageManager.h"
@@ -74,9 +72,6 @@
mAnomalyMonitor(anomalyMonitor),
mSendBroadcast(sendBroadcast),
mTimeBaseSec(timeBaseSec) {
- // On each initialization of StatsLogProcessor, check stats-data directory to see if there is
- // any left over data to be read.
- StorageManager::sendBroadcast(STATS_DATA_DIR, mSendBroadcast);
StatsPullerManager statsPullerManager;
statsPullerManager.SetTimeBaseSec(mTimeBaseSec);
}
@@ -93,27 +88,31 @@
}
}
+void updateUid(Value* value, int hostUid) {
+ int uid = value->int_value;
+ if (uid != hostUid) {
+ value->setInt(hostUid);
+ }
+}
+
void StatsLogProcessor::mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const {
- std::set<Field, FieldCmp> uidFields;
if (android::util::kAtomsWithAttributionChain.find(event->GetTagId()) !=
android::util::kAtomsWithAttributionChain.end()) {
- FieldMatcher matcher;
- buildAttributionUidFieldMatcher(event->GetTagId(), Position::ANY, &matcher);
- findFields(event->getFieldValueMap(), matcher, &uidFields);
- } else if (android::util::kAtomsWithUidField.find(event->GetTagId()) !=
- android::util::kAtomsWithUidField.end()) {
- FieldMatcher matcher;
- buildSimpleAtomFieldMatcher(
- event->GetTagId(), 1 /* uid is always the 1st field. */, &matcher);
- findFields(event->getFieldValueMap(), matcher, &uidFields);
- }
-
- for (const auto& uidField : uidFields) {
- DimensionsValue* value = event->findFieldValueOrNull(uidField);
- if (value != nullptr && value->value_case() == DimensionsValue::ValueCase::kValueInt) {
- const int uid = mUidMap->getHostUidOrSelf(value->value_int());
- value->set_value_int(uid);
+ for (auto& value : *(event->getMutableValues())) {
+ if (value.mField.getPosAtDepth(0) > kAttributionField) {
+ break;
+ }
+ if (isAttributionUidField(value)) {
+ const int hostUid = mUidMap->getHostUidOrSelf(value.mValue.int_value);
+ updateUid(&value.mValue, hostUid);
+ }
}
+ } else if (android::util::kAtomsWithUidField.find(event->GetTagId()) !=
+ android::util::kAtomsWithUidField.end() &&
+ event->getValues().size() > 0 && (event->getValues())[0].mValue.getType() == INT) {
+ Value& value = (*event->getMutableValues())[0].mValue;
+ const int hostUid = mUidMap->getHostUidOrSelf(value.int_value);
+ updateUid(&value, hostUid);
}
}
@@ -212,27 +211,14 @@
}
}
-void StatsLogProcessor::onDumpReport(const ConfigKey& key, const uint64_t& dumpTimeStampNs,
- ConfigMetricsReportList* report) {
+void StatsLogProcessor::onDumpReport(const ConfigKey& key, const uint64_t dumpTimeStampNs,
+ vector<uint8_t>* outData) {
std::lock_guard<std::mutex> lock(mMetricsMutex);
- auto it = mMetricsManagers.find(key);
- if (it == mMetricsManagers.end()) {
- ALOGW("Config source %s does not exist", key.ToString().c_str());
- return;
- }
- report->mutable_config_key()->set_uid(key.GetUid());
- report->mutable_config_key()->set_id(key.GetId());
- ConfigMetricsReport* configMetricsReport = report->add_reports();
- it->second->onDumpReport(dumpTimeStampNs, configMetricsReport);
- // TODO: dump uid mapping.
+ onDumpReportLocked(key, dumpTimeStampNs, outData);
}
-void StatsLogProcessor::onDumpReport(const ConfigKey& key, vector<uint8_t>* outData) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- onDumpReportLocked(key, outData);
-}
-
-void StatsLogProcessor::onDumpReportLocked(const ConfigKey& key, vector<uint8_t>* outData) {
+void StatsLogProcessor::onDumpReportLocked(const ConfigKey& key, const uint64_t dumpTimeStampNs,
+ vector<uint8_t>* outData) {
auto it = mMetricsManagers.find(key);
if (it == mMetricsManagers.end()) {
ALOGW("Config source %s does not exist", key.ToString().c_str());
@@ -258,7 +244,7 @@
// First, fill in ConfigMetricsReport using current data on memory, which
// starts from filling in StatsLogReport's.
- it->second->onDumpReport(&proto);
+ it->second->onDumpReport(dumpTimeStampNs, &proto);
// Fill in UidMap.
auto uidMap = mUidMap->getOutput(key);
@@ -292,6 +278,7 @@
iter.rp()->move(toRead);
}
}
+
StatsdStats::getInstance().noteMetricsReportSent(key);
}
@@ -327,7 +314,7 @@
StatsdStats::kMaxMetricsBytesPerConfig) { // Too late. We need to start clearing data.
// TODO(b/70571383): By 12/15/2017 add API to drop data directly
ProtoOutputStream proto;
- metricsManager.onDumpReport(&proto);
+ metricsManager.onDumpReport(time(nullptr) * NS_PER_SEC, &proto);
StatsdStats::getInstance().noteDataDropped(key);
VLOG("StatsD had to toss out metrics for %s", key.ToString().c_str());
} else if (totalBytes > .9 * StatsdStats::kMaxMetricsBytesPerConfig) {
@@ -351,7 +338,7 @@
for (auto& pair : mMetricsManagers) {
const ConfigKey& key = pair.first;
vector<uint8_t> data;
- onDumpReportLocked(key, &data);
+ onDumpReportLocked(key, time(nullptr) * NS_PER_SEC, &data);
// TODO: Add a guardrail to prevent accumulation of file on disk.
string file_name = StringPrintf("%s/%ld_%d_%lld", STATS_DATA_DIR, time(nullptr),
key.GetUid(), (long long)key.GetId());
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index 8bbcd75..1444306 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -46,9 +46,7 @@
size_t GetMetricsSize(const ConfigKey& key) const;
- void onDumpReport(const ConfigKey& key, vector<uint8_t>* outData);
- void onDumpReport(const ConfigKey& key, const uint64_t& dumpTimeStampNs,
- ConfigMetricsReportList* report);
+ void onDumpReport(const ConfigKey& key, const uint64_t dumpTimeNs, vector<uint8_t>* outData);
/* Tells MetricsManager that the alarms in anomalySet have fired. Modifies anomalySet. */
void onAnomalyAlarmFired(
@@ -80,7 +78,8 @@
sp<AnomalyMonitor> mAnomalyMonitor;
- void onDumpReportLocked(const ConfigKey& key, vector<uint8_t>* outData);
+ void onDumpReportLocked(const ConfigKey& key, const uint64_t dumpTimeNs,
+ vector<uint8_t>* outData);
/* Check if we should send a broadcast if approaching memory limits and if we're over, we
* actually delete the data. */
@@ -105,9 +104,14 @@
FRIEND_TEST(StatsLogProcessorTest, TestRateLimitBroadcast);
FRIEND_TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge);
FRIEND_TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge);
- FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration);
- FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration);
- FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks);
+ FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1);
+ FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2);
+ FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration3);
+ FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration1);
+ FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration2);
+ FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration3);
+ FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks1);
+ FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks2);
FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSlice);
FRIEND_TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent);
FRIEND_TEST(DimensionInConditionE2eTest, TestCountMetricNoLink);
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index c24efec..ee38667 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -492,7 +492,8 @@
}
if (good) {
vector<uint8_t> data;
- mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), &data);
+ mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), time(nullptr) * NS_PER_SEC,
+ &data);
// TODO: print the returned StatsLogReport to file instead of printing to logcat.
if (proto) {
for (size_t i = 0; i < data.size(); i ++) {
@@ -668,11 +669,18 @@
"Only system uid can call informAnomalyAlarmFired");
}
- VLOG("StatsService::informAnomalyAlarmFired succeeded");
+ // TODO: This may be a bug. time(nullptr) can be off (wrt AlarmManager's time) and cause us to
+ // miss the alarm! Eventually we will switch to using elapsedRealTime everywhere,
+ // which may hopefully fix the problem, so we'll leave this alone for now.
uint64_t currentTimeSec = time(nullptr);
std::unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>> anomalySet =
mAnomalyMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
- mProcessor->onAnomalyAlarmFired(currentTimeSec * NS_PER_SEC, anomalySet);
+ if (anomalySet.size() > 0) {
+ VLOG("Found an anomaly alarm that fired.");
+ mProcessor->onAnomalyAlarmFired(currentTimeSec * NS_PER_SEC, anomalySet);
+ } else {
+ VLOG("Cannot find an anomaly alarm that fired. Perhaps it was recently cancelled.");
+ }
return Status::ok();
}
@@ -780,7 +788,7 @@
VLOG("StatsService::getData with Pid %i, Uid %i", ipc->getCallingPid(), ipc->getCallingUid());
if (checkCallingPermission(String16(kPermissionDump))) {
ConfigKey configKey(ipc->getCallingUid(), key);
- mProcessor->onDumpReport(configKey, output);
+ mProcessor->onDumpReport(configKey, time(nullptr) * NS_PER_SEC, output);
return Status::ok();
} else {
return Status::fromExceptionCode(binder::Status::EX_SECURITY);
diff --git a/cmds/statsd/src/anomaly/AnomalyMonitor.cpp b/cmds/statsd/src/anomaly/AnomalyMonitor.cpp
index 72d29d0..ca34dc6 100644
--- a/cmds/statsd/src/anomaly/AnomalyMonitor.cpp
+++ b/cmds/statsd/src/anomaly/AnomalyMonitor.cpp
@@ -96,7 +96,7 @@
std::lock_guard<std::mutex> lock(mLock);
for (sp<const AnomalyAlarm> t = mPq.top(); t != nullptr && t->timestampSec <= timestampSec;
- t = mPq.top()) {
+ t = mPq.top()) {
oldAlarms.insert(t);
mPq.pop(); // remove t
}
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.cpp b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
index ba16ec83..443d33d 100644
--- a/cmds/statsd/src/anomaly/AnomalyTracker.cpp
+++ b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
@@ -92,6 +92,9 @@
void AnomalyTracker::addPastBucket(const MetricDimensionKey& key, const int64_t& bucketValue,
const int64_t& bucketNum) {
+ if (mNumOfPastBuckets == 0) {
+ return;
+ }
flushPastBuckets(bucketNum);
auto& bucket = mPastBuckets[index(bucketNum)];
@@ -106,6 +109,9 @@
void AnomalyTracker::addPastBucket(std::shared_ptr<DimToValMap> bucketValues,
const int64_t& bucketNum) {
VLOG("addPastBucket() called.");
+ if (mNumOfPastBuckets == 0) {
+ return;
+ }
flushPastBuckets(bucketNum);
// Replace the oldest bucket with the new bucket we are adding.
mPastBuckets[index(bucketNum)] = bucketValues;
diff --git a/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp b/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp
index fa0bc0c..3ba943c 100644
--- a/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp
+++ b/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp
@@ -53,10 +53,11 @@
void DurationAnomalyTracker::startAlarm(const MetricDimensionKey& dimensionKey,
const uint64_t& timestampNs) {
- uint32_t timestampSec = static_cast<uint32_t>(timestampNs / NS_PER_SEC);
+ // Alarms are stored in secs. Must round up, since if it fires early, it is ignored completely.
+ uint32_t timestampSec = static_cast<uint32_t>((timestampNs -1)/ NS_PER_SEC) + 1; // round up
if (isInRefractoryPeriod(timestampNs, dimensionKey)) {
- VLOG("Skipping setting anomaly alarm since it'd fall in the refractory period");
- return;
+ VLOG("Setting a delayed anomaly alarm lest it fall in the refractory period");
+ timestampSec = getRefractoryPeriodEndsSec(dimensionKey) + 1;
}
sp<const AnomalyAlarm> alarm = new AnomalyAlarm{timestampSec};
mAlarms.insert({dimensionKey, alarm});
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.cpp b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
index 4c20ccb..13a2b7b 100644
--- a/cmds/statsd/src/condition/CombinationConditionTracker.cpp
+++ b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
@@ -106,11 +106,9 @@
}
void CombinationConditionTracker::isConditionMet(
- const ConditionKey& conditionParameters,
- const vector<sp<ConditionTracker>>& allConditions,
- const FieldMatcher& dimensionFields,
- vector<ConditionState>& conditionCache,
- std::unordered_set<HashableDimensionKey> &dimensionsKeySet) const {
+ const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions,
+ const std::vector<Matcher>& dimensionFields, vector<ConditionState>& conditionCache,
+ std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const {
// So far, this is fine as there is at most one child having sliced output.
for (const int childIndex : mChildren) {
if (conditionCache[childIndex] == ConditionState::kNotEvaluated) {
@@ -169,8 +167,8 @@
ConditionState CombinationConditionTracker::getMetConditionDimension(
const std::vector<sp<ConditionTracker>>& allConditions,
- const FieldMatcher& dimensionFields,
- std::unordered_set<HashableDimensionKey> &dimensionsKeySet) const {
+ const std::vector<Matcher>& dimensionFields,
+ std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const {
vector<ConditionState> conditionCache(allConditions.size(), ConditionState::kNotEvaluated);
// So far, this is fine as there is at most one child having sliced output.
for (const int childIndex : mChildren) {
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.h b/cmds/statsd/src/condition/CombinationConditionTracker.h
index 0b7f949..ba185f6 100644
--- a/cmds/statsd/src/condition/CombinationConditionTracker.h
+++ b/cmds/statsd/src/condition/CombinationConditionTracker.h
@@ -41,17 +41,17 @@
std::vector<ConditionState>& conditionCache,
std::vector<bool>& changedCache) override;
- void isConditionMet(
- const ConditionKey& conditionParameters,
- const std::vector<sp<ConditionTracker>>& allConditions,
- const FieldMatcher& dimensionFields,
- std::vector<ConditionState>& conditionCache,
- std::unordered_set<HashableDimensionKey> &dimensionsKeySet) const override;
+ void isConditionMet(const ConditionKey& conditionParameters,
+ const std::vector<sp<ConditionTracker>>& allConditions,
+ const vector<Matcher>& dimensionFields,
+ std::vector<ConditionState>& conditionCache,
+ std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override;
ConditionState getMetConditionDimension(
const std::vector<sp<ConditionTracker>>& allConditions,
- const FieldMatcher& dimensionFields,
- std::unordered_set<HashableDimensionKey> &dimensionsKeySet) const override;
+ const vector<Matcher>& dimensionFields,
+ std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override;
+
private:
LogicalOperation mLogicalOperation;
diff --git a/cmds/statsd/src/condition/ConditionTracker.h b/cmds/statsd/src/condition/ConditionTracker.h
index 81abbdb..2612a9a 100644
--- a/cmds/statsd/src/condition/ConditionTracker.h
+++ b/cmds/statsd/src/condition/ConditionTracker.h
@@ -90,14 +90,13 @@
virtual void isConditionMet(
const ConditionKey& conditionParameters,
const std::vector<sp<ConditionTracker>>& allConditions,
- const FieldMatcher& dimensionFields,
- std::vector<ConditionState>& conditionCache,
- std::unordered_set<HashableDimensionKey> &dimensionsKeySet) const = 0;
+ const vector<Matcher>& dimensionFields, std::vector<ConditionState>& conditionCache,
+ std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const = 0;
virtual ConditionState getMetConditionDimension(
const std::vector<sp<ConditionTracker>>& allConditions,
- const FieldMatcher& dimensionFields,
- std::unordered_set<HashableDimensionKey> &dimensionsKeySet) const = 0;
+ const vector<Matcher>& dimensionFields,
+ std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const = 0;
// return the list of LogMatchingTracker index that this ConditionTracker uses.
virtual const std::set<int>& getLogTrackerIndex() const {
diff --git a/cmds/statsd/src/condition/ConditionWizard.cpp b/cmds/statsd/src/condition/ConditionWizard.cpp
index 0427700..c8722c3 100644
--- a/cmds/statsd/src/condition/ConditionWizard.cpp
+++ b/cmds/statsd/src/condition/ConditionWizard.cpp
@@ -24,11 +24,9 @@
using std::string;
using std::vector;
-ConditionState ConditionWizard::query(
- const int index, const ConditionKey& parameters,
- const FieldMatcher& dimensionFields,
- std::unordered_set<HashableDimensionKey> *dimensionKeySet) {
-
+ConditionState ConditionWizard::query(const int index, const ConditionKey& parameters,
+ const vector<Matcher>& dimensionFields,
+ std::unordered_set<HashableDimensionKey>* dimensionKeySet) {
vector<ConditionState> cache(mAllConditions.size(), ConditionState::kNotEvaluated);
mAllConditions[index]->isConditionMet(
@@ -37,9 +35,8 @@
}
ConditionState ConditionWizard::getMetConditionDimension(
- const int index, const FieldMatcher& dimensionFields,
- std::unordered_set<HashableDimensionKey> *dimensionsKeySet) const {
-
+ const int index, const vector<Matcher>& dimensionFields,
+ std::unordered_set<HashableDimensionKey>* dimensionsKeySet) const {
return mAllConditions[index]->getMetConditionDimension(mAllConditions, dimensionFields,
*dimensionsKeySet);
}
diff --git a/cmds/statsd/src/condition/ConditionWizard.h b/cmds/statsd/src/condition/ConditionWizard.h
index b38b59f..4831d56 100644
--- a/cmds/statsd/src/condition/ConditionWizard.h
+++ b/cmds/statsd/src/condition/ConditionWizard.h
@@ -39,16 +39,13 @@
// condition.
// The ConditionTracker at [conditionIndex] can be a CombinationConditionTracker. In this case,
// the conditionParameters contains the parameters for it's children SimpleConditionTrackers.
- virtual ConditionState query(
- const int conditionIndex,
- const ConditionKey& conditionParameters,
- const FieldMatcher& dimensionFields,
- std::unordered_set<HashableDimensionKey> *dimensionKeySet);
+ virtual ConditionState query(const int conditionIndex, const ConditionKey& conditionParameters,
+ const vector<Matcher>& dimensionFields,
+ std::unordered_set<HashableDimensionKey>* dimensionKeySet);
virtual ConditionState getMetConditionDimension(
- const int index,
- const FieldMatcher& dimensionFields,
- std::unordered_set<HashableDimensionKey> *dimensionsKeySet) const;
+ const int index, const vector<Matcher>& dimensionFields,
+ std::unordered_set<HashableDimensionKey>* dimensionsKeySet) const;
private:
std::vector<sp<ConditionTracker>> mAllConditions;
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.cpp b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
index 25265d5..624119f3 100644
--- a/cmds/statsd/src/condition/SimpleConditionTracker.cpp
+++ b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
@@ -19,7 +19,6 @@
#include "SimpleConditionTracker.h"
#include "guardrail/StatsdStats.h"
-#include "dimension.h"
#include <log/logprint.h>
@@ -77,10 +76,12 @@
mStopAllLogMatcherIndex = -1;
}
- mOutputDimensions = simplePredicate.dimensions();
-
- if (mOutputDimensions.child_size() > 0) {
- mSliced = true;
+ if (simplePredicate.has_dimensions()) {
+ translateFieldMatcher(simplePredicate.dimensions(), &mOutputDimensions);
+ if (mOutputDimensions.size() > 0) {
+ mSliced = true;
+ mDimensionTag = mOutputDimensions[0].mMatcher.getTag();
+ }
}
if (simplePredicate.initial_value() == SimplePredicate_InitialValue_FALSE) {
@@ -104,13 +105,10 @@
vector<bool>& stack) {
// SimpleConditionTracker does not have dependency on other conditions, thus we just return
// if the initialization was successful.
- if (mOutputDimensions.has_field() || mOutputDimensions.child_size() > 0) {
- setSliced(true);
- }
return mInitialized;
}
-void print(map<HashableDimensionKey, int>& conditions, const int64_t& id) {
+void print(const map<HashableDimensionKey, int>& conditions, const int64_t& id) {
VLOG("%lld DUMP:", (long long)id);
for (const auto& pair : conditions) {
VLOG("\t%s : %d", pair.first.c_str(), pair.second);
@@ -151,24 +149,15 @@
}
void SimpleConditionTracker::handleConditionEvent(const HashableDimensionKey& outputKey,
- bool matchStart,
- std::vector<ConditionState>& conditionCache,
- std::vector<bool>& conditionChangedCache) {
- if ((int)conditionChangedCache.size() <= mIndex) {
- ALOGE("handleConditionEvent: param conditionChangedCache not initialized.");
- return;
- }
- if ((int)conditionCache.size() <= mIndex) {
- ALOGE("handleConditionEvent: param conditionCache not initialized.");
- return;
- }
+ bool matchStart, ConditionState* conditionCache,
+ bool* conditionChangedCache) {
bool changed = false;
auto outputIt = mSlicedConditionState.find(outputKey);
ConditionState newCondition;
if (hitGuardRail(outputKey)) {
- conditionChangedCache[mIndex] = false;
+ (*conditionChangedCache) = false;
// Tells the caller it's evaluated.
- conditionCache[mIndex] = ConditionState::kUnknown;
+ (*conditionCache) = ConditionState::kUnknown;
return;
}
if (outputIt == mSlicedConditionState.end()) {
@@ -230,9 +219,8 @@
print(mSlicedConditionState, mConditionId);
}
- conditionChangedCache[mIndex] = changed;
- conditionCache[mIndex] = newCondition;
-
+ (*conditionChangedCache) = changed;
+ (*conditionCache) = newCondition;
VLOG("SimplePredicate %lld nonSlicedChange? %d", (long long)mConditionId,
conditionChangedCache[mIndex] == true);
}
@@ -292,42 +280,42 @@
return;
}
- // outputKey is the output values. e.g, uid:1234
- std::vector<DimensionsValue> outputValues;
- getDimensionKeys(event, mOutputDimensions, &outputValues);
- if (outputValues.size() == 0) {
- // The original implementation would generate an empty string dimension hash when condition
- // is not sliced.
- handleConditionEvent(
- DEFAULT_DIMENSION_KEY, matchedState == 1, conditionCache, conditionChangedCache);
- } else if (outputValues.size() == 1) {
- handleConditionEvent(HashableDimensionKey(outputValues[0]), matchedState == 1,
- conditionCache, conditionChangedCache);
+ ConditionState overallState = mInitialValue;
+ bool overallChanged = false;
+
+ if (mOutputDimensions.size() == 0) {
+ handleConditionEvent(DEFAULT_DIMENSION_KEY, matchedState == 1, &overallState,
+ &overallChanged);
} else {
+ std::vector<HashableDimensionKey> outputValues;
+ filterValues(mOutputDimensions, event.getValues(), &outputValues);
+
// If this event has multiple nodes in the attribution chain, this log event probably will
// generate multiple dimensions. If so, we will find if the condition changes for any
// dimension and ask the corresponding metric producer to verify whether the actual sliced
// condition has changed or not.
// A high level assumption is that a predicate is either sliced or unsliced. We will never
// have both sliced and unsliced version of a predicate.
- for (const DimensionsValue& outputValue : outputValues) {
- vector<ConditionState> dimensionalConditionCache(conditionCache.size(),
- ConditionState::kNotEvaluated);
- vector<bool> dimensionalConditionChangedCache(conditionChangedCache.size(), false);
- handleConditionEvent(HashableDimensionKey(outputValue), matchedState == 1,
- dimensionalConditionCache, dimensionalConditionChangedCache);
- OrConditionState(dimensionalConditionCache, &conditionCache);
- OrBooleanVector(dimensionalConditionChangedCache, &conditionChangedCache);
+ for (const HashableDimensionKey& outputValue : outputValues) {
+ // For sliced conditions, the value in the cache is not used. We don't need to update
+ // the overall condition state.
+ ConditionState tempState = ConditionState::kUnknown;
+ bool tempChanged = false;
+ handleConditionEvent(outputValue, matchedState == 1, &tempState, &tempChanged);
+ if (tempChanged) {
+ overallChanged = true;
+ }
}
}
+ conditionCache[mIndex] = overallState;
+ conditionChangedCache[mIndex] = overallChanged;
}
void SimpleConditionTracker::isConditionMet(
- const ConditionKey& conditionParameters,
- const vector<sp<ConditionTracker>>& allConditions,
- const FieldMatcher& dimensionFields,
- vector<ConditionState>& conditionCache,
- std::unordered_set<HashableDimensionKey> &dimensionsKeySet) const {
+ const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions,
+ const vector<Matcher>& dimensionFields, vector<ConditionState>& conditionCache,
+ std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const {
+
if (conditionCache[mIndex] != ConditionState::kNotEvaluated) {
// it has been evaluated.
VLOG("Yes, already evaluated, %lld %d",
@@ -338,8 +326,7 @@
if (pair == conditionParameters.end()) {
ConditionState conditionState = ConditionState::kNotEvaluated;
- if (dimensionFields.has_field() && dimensionFields.child_size() > 0 &&
- dimensionFields.field() == mOutputDimensions.field()) {
+ if (dimensionFields.size() > 0 && dimensionFields[0].mMatcher.getTag() == mDimensionTag) {
conditionState = conditionState | getMetConditionDimension(
allConditions, dimensionFields, dimensionsKeySet);
} else {
@@ -368,12 +355,10 @@
ConditionState sliceState =
startedCountIt->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
conditionState = conditionState | sliceState;
- if (sliceState == ConditionState::kTrue && dimensionFields.has_field()) {
- HashableDimensionKey dimensionKey;
- if (getSubDimension(startedCountIt->first.getDimensionsValue(), dimensionFields,
- dimensionKey.getMutableDimensionsValue())) {
- dimensionsKeySet.insert(dimensionKey);
- }
+ if (sliceState == ConditionState::kTrue && dimensionFields.size() > 0) {
+ vector<HashableDimensionKey> dimensionKeys;
+ filterValues(dimensionFields, startedCountIt->first.getValues(), &dimensionKeys);
+ dimensionsKeySet.insert(dimensionKeys.begin(), dimensionKeys.end());
}
} else {
// For unseen key, check whether the require dimensions are subset of sliced condition
@@ -382,31 +367,29 @@
for (const auto& slice : mSlicedConditionState) {
ConditionState sliceState =
slice.second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
- if (IsSubDimension(slice.first.getDimensionsValue(), key.getDimensionsValue())) {
+ if (slice.first.contains(key)) {
conditionState = conditionState | sliceState;
- if (sliceState == ConditionState::kTrue && dimensionFields.has_field()) {
- HashableDimensionKey dimensionKey;
- if (getSubDimension(slice.first.getDimensionsValue(),
- dimensionFields, dimensionKey.getMutableDimensionsValue())) {
- dimensionsKeySet.insert(dimensionKey);
- }
+ if (sliceState == ConditionState::kTrue && dimensionFields.size() > 0) {
+ vector<HashableDimensionKey> dimensionKeys;
+ filterValues(dimensionFields, slice.first.getValues(), &dimensionKeys);
+
+ dimensionsKeySet.insert(dimensionKeys.begin(), dimensionKeys.end());
+ }
}
}
}
}
- }
conditionCache[mIndex] = conditionState;
VLOG("Predicate %lld return %d", (long long)mConditionId, conditionCache[mIndex]);
}
ConditionState SimpleConditionTracker::getMetConditionDimension(
const std::vector<sp<ConditionTracker>>& allConditions,
- const FieldMatcher& dimensionFields,
- std::unordered_set<HashableDimensionKey> &dimensionsKeySet) const {
+ const vector<Matcher>& dimensionFields,
+ std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const {
ConditionState conditionState = mInitialValue;
- if (!dimensionFields.has_field() ||
- !mOutputDimensions.has_field() ||
- dimensionFields.field() != mOutputDimensions.field()) {
+ if (dimensionFields.size() == 0 || mOutputDimensions.size() == 0 ||
+ dimensionFields[0].mMatcher.getTag() != mOutputDimensions[0].mMatcher.getTag()) {
const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY);
if (itr != mSlicedConditionState.end()) {
ConditionState sliceState =
@@ -419,13 +402,13 @@
for (const auto& slice : mSlicedConditionState) {
ConditionState sliceState =
slice.second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
- DimensionsValue dimensionsValue;
conditionState = conditionState | sliceState;
- HashableDimensionKey dimensionKey;
- if (sliceState == ConditionState::kTrue &&
- getSubDimension(slice.first.getDimensionsValue(), dimensionFields,
- dimensionKey.getMutableDimensionsValue())) {
- dimensionsKeySet.insert(dimensionKey);
+
+ if (sliceState == ConditionState::kTrue && dimensionFields.size() > 0) {
+ vector<HashableDimensionKey> dimensionKeys;
+ filterValues(dimensionFields, slice.first.getValues(), &dimensionKeys);
+
+ dimensionsKeySet.insert(dimensionKeys.begin(), dimensionKeys.end());
}
}
return conditionState;
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.h b/cmds/statsd/src/condition/SimpleConditionTracker.h
index ce9a02d..c565129 100644
--- a/cmds/statsd/src/condition/SimpleConditionTracker.h
+++ b/cmds/statsd/src/condition/SimpleConditionTracker.h
@@ -48,14 +48,14 @@
void isConditionMet(const ConditionKey& conditionParameters,
const std::vector<sp<ConditionTracker>>& allConditions,
- const FieldMatcher& dimensionFields,
+ const vector<Matcher>& dimensionFields,
std::vector<ConditionState>& conditionCache,
- std::unordered_set<HashableDimensionKey> &dimensionsKeySet) const override;
+ std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override;
ConditionState getMetConditionDimension(
const std::vector<sp<ConditionTracker>>& allConditions,
- const FieldMatcher& dimensionFields,
- std::unordered_set<HashableDimensionKey> &dimensionsKeySet) const override;
+ const vector<Matcher>& dimensionFields,
+ std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override;
private:
const ConfigKey mConfigKey;
@@ -73,17 +73,17 @@
ConditionState mInitialValue;
- FieldMatcher mOutputDimensions;
+ std::vector<Matcher> mOutputDimensions;
+
+ int mDimensionTag;
std::map<HashableDimensionKey, int> mSlicedConditionState;
void handleStopAll(std::vector<ConditionState>& conditionCache,
std::vector<bool>& changedCache);
- void handleConditionEvent(const HashableDimensionKey& outputKey,
- bool matchStart,
- std::vector<ConditionState>& conditionCache,
- std::vector<bool>& changedCache);
+ void handleConditionEvent(const HashableDimensionKey& outputKey, bool matchStart,
+ ConditionState* conditionCache, bool* changedCache);
bool hitGuardRail(const HashableDimensionKey& newKey);
diff --git a/cmds/statsd/src/condition/condition_util.cpp b/cmds/statsd/src/condition/condition_util.cpp
index 0ab33cf..691356b 100644
--- a/cmds/statsd/src/condition/condition_util.cpp
+++ b/cmds/statsd/src/condition/condition_util.cpp
@@ -27,7 +27,6 @@
#include "ConditionTracker.h"
#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
#include "stats_util.h"
-#include "dimension.h"
namespace android {
namespace os {
@@ -97,109 +96,6 @@
ConditionState operator|(ConditionState l, ConditionState r) {
return l >= r ? l : r;
}
-
-void OrConditionState(const std::vector<ConditionState>& ref, vector<ConditionState> * ored) {
- if (ref.size() != ored->size()) {
- return;
- }
- for (size_t i = 0; i < ored->size(); ++i) {
- ored->at(i) = ored->at(i) | ref.at(i);
- }
-}
-
-void OrBooleanVector(const std::vector<bool>& ref, vector<bool> * ored) {
- if (ref.size() != ored->size()) {
- return;
- }
- for (size_t i = 0; i < ored->size(); ++i) {
- ored->at(i) = ored->at(i) | ref.at(i);
- }
-}
-
-void getFieldsFromFieldMatcher(const FieldMatcher& matcher, Field* rootField, Field* leafField,
- std::vector<Field> *allFields) {
- if (matcher.has_position()) {
- leafField->set_position_index(0);
- }
- if (matcher.child_size() == 0) {
- allFields->push_back(*rootField);
- return;
- }
- for (int i = 0; i < matcher.child_size(); ++i) {
- Field* newLeafField = leafField->add_child();
- newLeafField->set_field(matcher.child(i).field());
- getFieldsFromFieldMatcher(matcher.child(i), rootField, newLeafField, allFields);
- }
-}
-
-void getFieldsFromFieldMatcher(const FieldMatcher& matcher, std::vector<Field> *allFields) {
- if (!matcher.has_field()) {
- return;
- }
- Field rootField;
- rootField.set_field(matcher.field());
- getFieldsFromFieldMatcher(matcher, &rootField, &rootField, allFields);
-}
-
-void flattenValueLeaves(const DimensionsValue& value,
- std::vector<const DimensionsValue*> *allLaves) {
- switch (value.value_case()) {
- case DimensionsValue::ValueCase::kValueStr:
- case DimensionsValue::ValueCase::kValueInt:
- case DimensionsValue::ValueCase::kValueLong:
- case DimensionsValue::ValueCase::kValueBool:
- case DimensionsValue::ValueCase::kValueFloat:
- case DimensionsValue::ValueCase::VALUE_NOT_SET:
- allLaves->push_back(&value);
- break;
- case DimensionsValue::ValueCase::kValueTuple:
- for (int i = 0; i < value.value_tuple().dimensions_value_size(); ++i) {
- flattenValueLeaves(value.value_tuple().dimensions_value(i), allLaves);
- }
- break;
- }
-}
-
-void getDimensionKeysForCondition(
- const LogEvent& event, const MetricConditionLink& link,
- std::vector<HashableDimensionKey> *hashableDimensionKeys) {
- std::vector<Field> whatFields;
- getFieldsFromFieldMatcher(link.fields_in_what(), &whatFields);
- std::vector<Field> conditionFields;
- getFieldsFromFieldMatcher(link.fields_in_condition(), &conditionFields);
-
- // TODO(yanglu): here we could simplify the logic to get the leaf value node in what and
- // directly construct the full condition value tree.
- std::vector<DimensionsValue> whatValues;
- getDimensionKeys(event, link.fields_in_what(), &whatValues);
-
- for (size_t i = 0; i < whatValues.size(); ++i) {
- std::vector<const DimensionsValue*> whatLeaves;
- flattenValueLeaves(whatValues[i], &whatLeaves);
- if (whatLeaves.size() != whatFields.size() ||
- whatLeaves.size() != conditionFields.size()) {
- ALOGE("Dimensions between what and condition not equal.");
- return;
- }
- FieldValueMap conditionValueMap;
- for (size_t j = 0; j < whatLeaves.size(); ++j) {
- DimensionsValue* conditionValue = &conditionValueMap[conditionFields[j]];
- *conditionValue = *whatLeaves[i];
- if (!setFieldInLeafValueProto(conditionFields[j], conditionValue)) {
- ALOGE("Not able to reset the field for condition leaf value.");
- return;
- }
- }
- std::vector<DimensionsValue> conditionValueTrees;
- findDimensionsValues(conditionValueMap, link.fields_in_condition(), &conditionValueTrees);
- if (conditionValueTrees.size() != 1) {
- ALOGE("Not able to find unambiguous field value in condition atom.");
- continue;
- }
- hashableDimensionKeys->push_back(HashableDimensionKey(conditionValueTrees[0]));
- }
-}
-
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/condition/condition_util.h b/cmds/statsd/src/condition/condition_util.h
index a7288be..fed90ec 100644
--- a/cmds/statsd/src/condition/condition_util.h
+++ b/cmds/statsd/src/condition/condition_util.h
@@ -33,16 +33,10 @@
};
ConditionState operator|(ConditionState l, ConditionState r);
-void OrConditionState(const std::vector<ConditionState>& ref, vector<ConditionState> * ored);
-void OrBooleanVector(const std::vector<bool>& ref, vector<bool> * ored);
ConditionState evaluateCombinationCondition(const std::vector<int>& children,
const LogicalOperation& operation,
const std::vector<ConditionState>& conditionCache);
-
-void getDimensionKeysForCondition(
- const LogEvent& event, const MetricConditionLink& link,
- std::vector<HashableDimensionKey> *dimensionKeys);
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/dimension.cpp b/cmds/statsd/src/dimension.cpp
deleted file mode 100644
index 8a2e871..0000000
--- a/cmds/statsd/src/dimension.cpp
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Log.h"
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_internal.pb.h"
-#include "dimension.h"
-
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const DimensionsValue* getSingleLeafValue(const DimensionsValue* value) {
- if (value->value_case() == DimensionsValue::ValueCase::kValueTuple) {
- return getSingleLeafValue(&value->value_tuple().dimensions_value(0));
- } else {
- return value;
- }
-}
-
-DimensionsValue getSingleLeafValue(const DimensionsValue& value) {
- const DimensionsValue* leafValue = getSingleLeafValue(&value);
- return *leafValue;
-}
-
-void appendLeafNodeToTree(const Field& field,
- const DimensionsValue& value,
- DimensionsValue* parentValue) {
- if (field.child_size() <= 0) {
- *parentValue = value;
- parentValue->set_field(field.field());
- return;
- }
- parentValue->set_field(field.field());
- int idx = -1;
- for (int i = 0; i < parentValue->mutable_value_tuple()->dimensions_value_size(); ++i) {
- if (parentValue->mutable_value_tuple()->dimensions_value(i).field() ==
- field.child(0).field()) {
- idx = i;
- }
- }
- if (idx < 0) {
- parentValue->mutable_value_tuple()->add_dimensions_value();
- idx = parentValue->mutable_value_tuple()->dimensions_value_size() - 1;
- }
- appendLeafNodeToTree(
- field.child(0), value,
- parentValue->mutable_value_tuple()->mutable_dimensions_value(idx));
-}
-
-void appendLeafNodeToTrees(const Field& field,
- const DimensionsValue& node,
- std::vector<DimensionsValue>* rootTrees) {
- if (rootTrees == nullptr) {
- return;
- }
- if (rootTrees->empty()) {
- DimensionsValue tree;
- appendLeafNodeToTree(field, node, &tree);
- rootTrees->push_back(tree);
- } else {
- for (size_t i = 0; i < rootTrees->size(); ++i) {
- appendLeafNodeToTree(field, node, &rootTrees->at(i));
- }
- }
-}
-
-namespace {
-
-void findDimensionsValues(
- const FieldValueMap& fieldValueMap,
- const FieldMatcher& matcher,
- Field* rootField,
- Field* leafField,
- std::vector<DimensionsValue>* rootDimensionsValues);
-
-void findNonRepeatedDimensionsValues(
- const FieldValueMap& fieldValueMap,
- const FieldMatcher& matcher,
- Field* rootField,
- Field* leafField,
- std::vector<DimensionsValue>* rootValues) {
- if (matcher.child_size() > 0) {
- Field* newLeafField = leafField->add_child();
- for (const auto& childMatcher : matcher.child()) {
- newLeafField->set_field(childMatcher.field());
- findDimensionsValues(fieldValueMap, childMatcher, rootField, newLeafField, rootValues);
- }
- leafField->clear_child();
- } else {
- auto ret = fieldValueMap.equal_range(*rootField);
- int found = 0;
- for (auto it = ret.first; it != ret.second; ++it) {
- found++;
- }
- // Not found.
- if (found <= 0) {
- return;
- }
- if (found > 1) {
- ALOGE("Found multiple values for optional field.");
- return;
- }
- appendLeafNodeToTrees(*rootField, ret.first->second, rootValues);
- }
-}
-
-void findRepeatedDimensionsValues(const FieldValueMap& fieldValueMap,
- const FieldMatcher& matcher,
- Field* rootField,
- Field* leafField,
- std::vector<DimensionsValue>* rootValues) {
- if (matcher.position() == Position::FIRST) {
- leafField->set_position_index(0);
- findNonRepeatedDimensionsValues(fieldValueMap, matcher, rootField, leafField, rootValues);
- leafField->clear_position_index();
- } else {
- auto itLower = fieldValueMap.lower_bound(*rootField);
- if (itLower == fieldValueMap.end()) {
- return;
- }
- const int leafFieldNum = leafField->field();
- leafField->set_field(leafFieldNum + 1);
- auto itUpper = fieldValueMap.lower_bound(*rootField);
- // Resets the field number.
- leafField->set_field(leafFieldNum);
-
- switch (matcher.position()) {
- case Position::LAST:
- {
- itUpper--;
- if (itUpper != fieldValueMap.end()) {
- int last_index = getPositionByReferenceField(*rootField, itUpper->first);
- if (last_index < 0) {
- return;
- }
- leafField->set_position_index(last_index);
- findNonRepeatedDimensionsValues(
- fieldValueMap, matcher, rootField, leafField, rootValues);
- leafField->clear_position_index();
- }
- }
- break;
- case Position::ANY:
- {
- std::set<int> indexes;
- for (auto it = itLower; it != itUpper; ++it) {
- int index = getPositionByReferenceField(*rootField, it->first);
- if (index >= 0) {
- indexes.insert(index);
- }
- }
- if (!indexes.empty()) {
- std::vector<DimensionsValue> allValues;
- for (const int index : indexes) {
- leafField->set_position_index(index);
- std::vector<DimensionsValue> newValues = *rootValues;
- findNonRepeatedDimensionsValues(
- fieldValueMap, matcher, rootField, leafField, &newValues);
- allValues.insert(allValues.end(), newValues.begin(), newValues.end());
- leafField->clear_position_index();
- }
- rootValues->clear();
- rootValues->insert(rootValues->end(), allValues.begin(), allValues.end());
- }
- }
- break;
- default:
- break;
- }
- }
-}
-
-void findDimensionsValues(
- const FieldValueMap& fieldValueMap,
- const FieldMatcher& matcher,
- Field* rootField,
- Field* leafField,
- std::vector<DimensionsValue>* rootDimensionsValues) {
- if (!matcher.has_position()) {
- findNonRepeatedDimensionsValues(fieldValueMap, matcher, rootField, leafField,
- rootDimensionsValues);
- } else {
- findRepeatedDimensionsValues(fieldValueMap, matcher, rootField, leafField,
- rootDimensionsValues);
- }
-}
-
-} // namespace
-
-void findDimensionsValues(
- const FieldValueMap& fieldValueMap,
- const FieldMatcher& matcher,
- std::vector<DimensionsValue>* rootDimensionsValues) {
- Field rootField;
- buildSimpleAtomField(matcher.field(), &rootField);
- findDimensionsValues(fieldValueMap, matcher, &rootField, &rootField, rootDimensionsValues);
-}
-
-void buildSimpleAtomFieldMatcher(const int tagId, FieldMatcher* matcher) {
- matcher->set_field(tagId);
-}
-
-void buildSimpleAtomFieldMatcher(const int tagId, const int fieldNum, FieldMatcher* matcher) {
- matcher->set_field(tagId);
- matcher->add_child()->set_field(fieldNum);
-}
-
-constexpr int ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO = 1;
-constexpr int UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO = 1;
-constexpr int TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO = 2;
-
-void buildAttributionUidFieldMatcher(const int tagId, const Position position,
- FieldMatcher* matcher) {
- matcher->set_field(tagId);
- auto child = matcher->add_child();
- child->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
- child->set_position(position);
- child->add_child()->set_field(UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
-}
-
-void buildAttributionTagFieldMatcher(const int tagId, const Position position,
- FieldMatcher* matcher) {
- matcher->set_field(tagId);
- FieldMatcher* child = matcher->add_child();
- child->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
- child->set_position(position);
- child->add_child()->set_field(TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
-}
-
-void buildAttributionFieldMatcher(const int tagId, const Position position, FieldMatcher* matcher) {
- matcher->set_field(tagId);
- FieldMatcher* child = matcher->add_child();
- child->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
- child->set_position(position);
- child->add_child()->set_field(UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
- child->add_child()->set_field(TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
-}
-
-void DimensionsValueToString(const DimensionsValue& value, std::string *flattened) {
- if (!value.has_field()) {
- return;
- }
- *flattened += std::to_string(value.field());
- *flattened += ":";
- switch (value.value_case()) {
- case DimensionsValue::ValueCase::kValueStr:
- *flattened += value.value_str();
- break;
- case DimensionsValue::ValueCase::kValueInt:
- *flattened += std::to_string(value.value_int());
- break;
- case DimensionsValue::ValueCase::kValueLong:
- *flattened += std::to_string(value.value_long());
- break;
- case DimensionsValue::ValueCase::kValueBool:
- *flattened += std::to_string(value.value_bool());
- break;
- case DimensionsValue::ValueCase::kValueFloat:
- *flattened += std::to_string(value.value_float());
- break;
- case DimensionsValue::ValueCase::kValueTuple:
- {
- *flattened += "{";
- for (int i = 0; i < value.value_tuple().dimensions_value_size(); ++i) {
- DimensionsValueToString(value.value_tuple().dimensions_value(i), flattened);
- *flattened += "|";
- }
- *flattened += "}";
- }
- break;
- case DimensionsValue::ValueCase::VALUE_NOT_SET:
- break;
- }
-}
-
-std::string DimensionsValueToString(const DimensionsValue& value) {
- std::string flatten;
- DimensionsValueToString(value, &flatten);
- return flatten;
-}
-
-bool IsSubDimension(const DimensionsValue& dimension, const DimensionsValue& sub) {
- if (dimension.field() != sub.field()) {
- return false;
- }
- if (dimension.value_case() != sub.value_case()) {
- return false;
- }
- switch (dimension.value_case()) {
- case DimensionsValue::ValueCase::kValueStr:
- return dimension.value_str() == sub.value_str();
- case DimensionsValue::ValueCase::kValueInt:
- return dimension.value_int() == sub.value_int();
- case DimensionsValue::ValueCase::kValueLong:
- return dimension.value_long() == sub.value_long();
- case DimensionsValue::ValueCase::kValueBool:
- return dimension.value_bool() == sub.value_bool();
- case DimensionsValue::ValueCase::kValueFloat:
- return dimension.value_float() == sub.value_float();
- case DimensionsValue::ValueCase::kValueTuple: {
- if (dimension.value_tuple().dimensions_value_size() <
- sub.value_tuple().dimensions_value_size()) {
- return false;
- }
- bool allSub = true;
- for (int i = 0; allSub && i < sub.value_tuple().dimensions_value_size(); ++i) {
- bool isSub = false;
- for (int j = 0; !isSub &&
- j < dimension.value_tuple().dimensions_value_size(); ++j) {
- isSub |= IsSubDimension(dimension.value_tuple().dimensions_value(j),
- sub.value_tuple().dimensions_value(i));
- }
- allSub &= isSub;
- }
- return allSub;
- }
- break;
- case DimensionsValue::ValueCase::VALUE_NOT_SET:
- return false;
- default:
- return false;
- }
-}
-
-long getLongFromDimenValue(const DimensionsValue& dimensionValue) {
- switch (dimensionValue.value_case()) {
- case DimensionsValue::ValueCase::kValueInt:
- return dimensionValue.value_int();
- case DimensionsValue::ValueCase::kValueLong:
- return dimensionValue.value_long();
- case DimensionsValue::ValueCase::kValueBool:
- return dimensionValue.value_bool() ? 1 : 0;
- case DimensionsValue::ValueCase::kValueFloat:
- return (int64_t)dimensionValue.value_float();
- case DimensionsValue::ValueCase::kValueTuple:
- case DimensionsValue::ValueCase::kValueStr:
- case DimensionsValue::ValueCase::VALUE_NOT_SET:
- return 0;
- }
-}
-
-bool getSubDimension(const DimensionsValue& dimension, const FieldMatcher& matcher,
- DimensionsValue* subDimension) {
- if (!matcher.has_field()) {
- return false;
- }
- if (matcher.field() != dimension.field()) {
- return false;
- }
- if (matcher.child_size() <= 0) {
- if (dimension.value_case() == DimensionsValue::ValueCase::kValueTuple ||
- dimension.value_case() == DimensionsValue::ValueCase::VALUE_NOT_SET) {
- return false;
- }
- *subDimension = dimension;
- return true;
- } else {
- if (dimension.value_case() != DimensionsValue::ValueCase::kValueTuple) {
- return false;
- }
- bool found_value = true;
- auto value_tuple = dimension.value_tuple();
- subDimension->set_field(dimension.field());
- for (int i = 0; found_value && i < matcher.child_size(); ++i) {
- int j = 0;
- for (; j < value_tuple.dimensions_value_size(); ++j) {
- if (value_tuple.dimensions_value(j).field() == matcher.child(i).field()) {
- break;
- }
- }
- if (j < value_tuple.dimensions_value_size()) {
- found_value &= getSubDimension(value_tuple.dimensions_value(j), matcher.child(i),
- subDimension->mutable_value_tuple()->add_dimensions_value());
- } else {
- found_value = false;
- }
- }
- return found_value;
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/dimension.h b/cmds/statsd/src/dimension.h
deleted file mode 100644
index 138c6e9..0000000
--- a/cmds/statsd/src/dimension.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <log/logprint.h>
-#include <set>
-#include <vector>
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "field_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Returns the leaf node from the DimensionsValue proto. It assume that the input has only one
-// leaf node at most.
-const DimensionsValue* getSingleLeafValue(const DimensionsValue* value);
-DimensionsValue getSingleLeafValue(const DimensionsValue& value);
-
-// Appends the leaf node to the parent tree.
-void appendLeafNodeToTree(const Field& field, const DimensionsValue& value, DimensionsValue* tree);
-
-// Constructs the DimensionsValue protos from the FieldMatcher. Each DimensionsValue proto
-// represents a tree. When the input proto has repeated fields and the input "dimensions" wants
-// "ANY" locations, it will return multiple trees.
-void findDimensionsValues(
- const FieldValueMap& fieldValueMap,
- const FieldMatcher& matcher,
- std::vector<DimensionsValue>* rootDimensionsValues);
-
-// Utils to build FieldMatcher proto for simple one-depth atoms.
-void buildSimpleAtomFieldMatcher(const int tagId, const int atomFieldNum, FieldMatcher* matcher);
-void buildSimpleAtomFieldMatcher(const int tagId, FieldMatcher* matcher);
-
-// Utils to build FieldMatcher proto for attribution nodes.
-void buildAttributionUidFieldMatcher(const int tagId, const Position position,
- FieldMatcher* matcher);
-void buildAttributionTagFieldMatcher(const int tagId, const Position position,
- FieldMatcher* matcher);
-void buildAttributionFieldMatcher(const int tagId, const Position position,
- FieldMatcher* matcher);
-
-// Utils to print pretty string for DimensionsValue proto.
-std::string DimensionsValueToString(const DimensionsValue& value);
-void DimensionsValueToString(const DimensionsValue& value, std::string *flattened);
-
-bool IsSubDimension(const DimensionsValue& dimension, const DimensionsValue& sub);
-
-// Helper function to get long value from the DimensionsValue proto.
-long getLongFromDimenValue(const DimensionsValue& dimensionValue);
-
-bool getSubDimension(const DimensionsValue& dimension, const FieldMatcher& matcher,
- DimensionsValue* subDimension);
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/puller_util.cpp b/cmds/statsd/src/external/puller_util.cpp
index 7cfc1d48..0b0c5c4 100644
--- a/cmds/statsd/src/external/puller_util.cpp
+++ b/cmds/statsd/src/external/puller_util.cpp
@@ -18,7 +18,6 @@
#include "Log.h"
#include "StatsPullerManagerImpl.h"
-#include "field_util.h"
#include "puller_util.h"
#include "statslog.h"
@@ -30,125 +29,136 @@
using std::shared_ptr;
using std::vector;
-DimensionsValue* getFieldValue(shared_ptr<LogEvent> event, int tagId, int fieldNum) {
- Field field;
- buildSimpleAtomField(tagId, fieldNum, &field);
- return event->findFieldValueOrNull(field);
-}
-
+namespace {
bool shouldMerge(shared_ptr<LogEvent>& lhs, shared_ptr<LogEvent>& rhs,
- const vector<int>& nonAdditiveFields, int tagId) {
- for (int f : nonAdditiveFields) {
- DimensionsValue* lValue = getFieldValue(lhs, tagId, f);
- DimensionsValue* rValue = getFieldValue(rhs, tagId, f);
- if (!compareDimensionsValue(*lValue, *rValue)) {
- return false;
+ const vector<int>& nonAdditiveFields) {
+ const auto& l_values = lhs->getValues();
+ const auto& r_values = rhs->getValues();
+
+ for (size_t i : nonAdditiveFields) {
+ // We store everything starting from index 0, so we need to use i-1
+ if (!(l_values.size() > i - 1 && r_values.size() > i - 1 &&
+ l_values[i - 1].mValue == r_values[i - 1].mValue)) {
+ return false;
+ }
}
- }
- return true;
+ return true;
}
// merge rhs to lhs
-void mergeEvent(shared_ptr<LogEvent>& lhs, shared_ptr<LogEvent>& rhs,
- const vector<int>& additiveFields, int tagId) {
- for (int f : additiveFields) {
- DimensionsValue* lValue = getFieldValue(lhs, tagId, f);
- DimensionsValue* rValue = getFieldValue(rhs, tagId, f);
- if (lValue->has_value_int()) {
- lValue->set_value_int(lValue->value_int() + rValue->value_int());
- } else if (lValue->has_value_long()) {
- lValue->set_value_long(lValue->value_long() + rValue->value_long());
+// when calling this function, all sanity check should be done already.
+// e.g., index boundary, nonAdditiveFields matching etc.
+bool mergeEvent(shared_ptr<LogEvent>& lhs, shared_ptr<LogEvent>& rhs,
+ const vector<int>& additiveFields) {
+ vector<FieldValue>* host_values = lhs->getMutableValues();
+ const auto& child_values = rhs->getValues();
+ for (int i : additiveFields) {
+ Value& host = (*host_values)[i - 1].mValue;
+ const Value& child = (child_values[i - 1]).mValue;
+ if (child.getType() != host.getType()) {
+ return false;
+ }
+ switch (child.getType()) {
+ case INT:
+ host.setInt(host.int_value + child.int_value);
+ break;
+ case LONG:
+ host.setLong(host.long_value + child.long_value);
+ break;
+ default:
+ ALOGE("Tried to merge 2 fields with unsupported type");
+ return false;
+ }
}
- }
+ return true;
}
-// process all data and merge isolated with host if necessary
-void mergeIsolatedUidsToHostUid(vector<shared_ptr<LogEvent>>& data,
- const sp<UidMap>& uidMap, int tagId) {
- if (StatsPullerManagerImpl::kAllPullAtomInfo.find(tagId) ==
- StatsPullerManagerImpl::kAllPullAtomInfo.end()) {
- VLOG("Unknown pull atom id %d", tagId);
- return;
- }
- if (android::util::kAtomsWithUidField.find(tagId) ==
- android::util::kAtomsWithUidField.end()) {
- VLOG("No uid to merge for atom %d", tagId);
- return;
- }
- const vector<int>& additiveFields =
- StatsPullerManagerImpl::kAllPullAtomInfo.find(tagId)
- ->second.additiveFields;
- const vector<int>& nonAdditiveFields =
- StatsPullerManagerImpl::kAllPullAtomInfo.find(tagId)
- ->second.nonAdditiveFields;
-
- // map of host uid to isolated uid data index in the original vector.
- // because of non additive fields, there could be multiple of them that can't
- // be merged into one
- map<int, vector<int>> hostToIsolated;
- // map of host uid to their position in the original vector
- map<int, vector<int>> hostPosition;
- vector<int> isolatedUidPos;
- // all uids in the original vector
- vector<int> allUids;
- for (size_t i = 0; i < data.size(); i++) {
- // uid field is always first primitive filed, if present
- DimensionsValue* uidField = getFieldValue(data[i], tagId, 1);
- if (!uidField) {
- VLOG("Bad data for %d, %s", tagId, data[i]->ToString().c_str());
- return;
- }
- int uid = uidField->value_int();
- allUids.push_back(uid);
- const int hostUid = uidMap->getHostUidOrSelf(uid);
- if (hostUid != uid) {
- uidField->set_value_int(hostUid);
- hostToIsolated[hostUid].push_back(i);
- isolatedUidPos.push_back(i);
- }
- }
- vector<shared_ptr<LogEvent>> mergedData;
- for (size_t i = 0; i < allUids.size(); i++) {
- if (hostToIsolated.find(allUids[i]) != hostToIsolated.end()) {
- hostPosition[allUids[i]].push_back(i);
- } else if (std::find(isolatedUidPos.begin(), isolatedUidPos.end(), i) != isolatedUidPos.end()) {
- continue;
- } else {
- mergedData.push_back(data[i]);
- }
- }
- for (auto iter = hostToIsolated.begin(); iter != hostToIsolated.end();
- iter++) {
- int uid = iter->first;
- vector<int>& isolated = hostToIsolated[uid];
- vector<int> toBeMerged;
- toBeMerged.insert(toBeMerged.begin(), isolated.begin(), isolated.end());
- if (hostPosition.find(uid) != hostPosition.end()) {
- vector<int>& host = hostPosition[uid];
- toBeMerged.insert(toBeMerged.end(), host.begin(), host.end());
- }
- vector<bool> used(toBeMerged.size());
- for (size_t i = 0; i < toBeMerged.size(); i++) {
- if (used[i] == true) {
- continue;
- }
- for (size_t j = i + 1; j < toBeMerged.size(); j++) {
- shared_ptr<LogEvent>& lhs = data[toBeMerged[i]];
- shared_ptr<LogEvent>& rhs = data[toBeMerged[j]];
- if (shouldMerge(lhs, rhs, nonAdditiveFields, tagId)) {
- mergeEvent(lhs, rhs, additiveFields, tagId);
- used[j] = true;
+bool tryMerge(vector<shared_ptr<LogEvent>>& data, int child_pos, const vector<int>& host_pos,
+ const vector<int>& nonAdditiveFields, const vector<int>& additiveFields) {
+ for (const auto& pos : host_pos) {
+ if (shouldMerge(data[pos], data[child_pos], nonAdditiveFields) &&
+ mergeEvent(data[pos], data[child_pos], additiveFields)) {
+ return true;
}
- }
}
- for (size_t i = 0; i < toBeMerged.size(); i++) {
- if (used[i] == false) {
- mergedData.push_back(data[i]);
+ return false;
+}
+
+} // namespace
+
+/**
+ * Process all data and merge isolated with host if necessary.
+ * For example:
+ * NetworkBytesAtom {
+ * int uid = 1;
+ * State process_state = 2;
+ * int byte_send = 3;
+ * int byte_recv = 4;
+ * }
+ * additive fields are {3, 4}, non-additive field is {2}
+ * If we pulled the following events (uid1_child is an isolated uid which maps to uid1):
+ * [uid1, fg, 100, 200]
+ * [uid1_child, fg, 100, 200]
+ * [uid1, bg, 100, 200]
+ *
+ * We want to merge them and results should be:
+ * [uid1, fg, 200, 400]
+ * [uid1, bg, 100, 200]
+ */
+void mergeIsolatedUidsToHostUid(vector<shared_ptr<LogEvent>>& data, const sp<UidMap>& uidMap,
+ int tagId) {
+ if (StatsPullerManagerImpl::kAllPullAtomInfo.find(tagId) ==
+ StatsPullerManagerImpl::kAllPullAtomInfo.end()) {
+ VLOG("Unknown pull atom id %d", tagId);
+ return;
}
+ if (android::util::kAtomsWithUidField.find(tagId) == android::util::kAtomsWithUidField.end()) {
+ VLOG("No uid to merge for atom %d", tagId);
+ return;
}
- }
- data.clear();
- data = mergedData;
+ const vector<int>& additiveFields =
+ StatsPullerManagerImpl::kAllPullAtomInfo.find(tagId)->second.additiveFields;
+ const vector<int>& nonAdditiveFields =
+ StatsPullerManagerImpl::kAllPullAtomInfo.find(tagId)->second.nonAdditiveFields;
+
+ // map of host uid to their position in the original vector
+ map<int, vector<int>> hostPosition;
+ vector<bool> toRemove = vector<bool>(data.size(), false);
+
+ for (size_t i = 0; i < data.size(); i++) {
+ vector<FieldValue>* valueList = data[i]->getMutableValues();
+
+ int err = 0;
+ int uid = data[i]->GetInt(1, &err);
+ if (err != 0) {
+ VLOG("Bad uid field for %s", data[i]->ToString().c_str());
+ return;
+ }
+
+ const int hostUid = uidMap->getHostUidOrSelf(uid);
+
+ if (hostUid != uid) {
+ (*valueList)[0].mValue.setInt(hostUid);
+ }
+ if (hostPosition.find(hostUid) == hostPosition.end()) {
+ hostPosition[hostUid].push_back(i);
+ } else {
+ if (tryMerge(data, i, hostPosition[hostUid], nonAdditiveFields, additiveFields)) {
+ toRemove[i] = true;
+ } else {
+ hostPosition[hostUid].push_back(i);
+ }
+ }
+ }
+
+ vector<shared_ptr<LogEvent>> mergedData;
+ for (size_t i = 0; i < toRemove.size(); i++) {
+ if (!toRemove[i]) {
+ mergedData.push_back(data[i]);
+ }
+ }
+ data.clear();
+ data = mergedData;
}
} // namespace statsd
diff --git a/cmds/statsd/src/external/puller_util.h b/cmds/statsd/src/external/puller_util.h
index 70d5321..fd4a4a2 100644
--- a/cmds/statsd/src/external/puller_util.h
+++ b/cmds/statsd/src/external/puller_util.h
@@ -17,7 +17,6 @@
#pragma once
#include <vector>
-#include "HashableDimensionKey.h"
#include "StatsPuller.h"
#include "logd/LogEvent.h"
#include "packages/UidMap.h"
diff --git a/cmds/statsd/src/field_util.cpp b/cmds/statsd/src/field_util.cpp
deleted file mode 100644
index acf64fe..0000000
--- a/cmds/statsd/src/field_util.cpp
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Log.h"
-#include "field_util.h"
-
-#include <set>
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// This function is to compare two Field trees where each node has at most one child.
-bool CompareField(const Field& a, const Field& b) {
- if (a.field() < b.field()) {
- return true;
- }
- if (a.field() > b.field()) {
- return false;
- }
- if (a.position_index() < b.position_index()) {
- return true;
- }
- if (a.position_index() > b.position_index()) {
- return false;
- }
- if (a.child_size() < b.child_size()) {
- return true;
- }
- if (a.child_size() > b.child_size()) {
- return false;
- }
- if (a.child_size() == 0 && b.child_size() == 0) {
- return false;
- }
- return CompareField(a.child(0), b.child(0));
-}
-
-const Field* getSingleLeaf(const Field* field) {
- if (field->child_size() <= 0) {
- return field;
- } else {
- return getSingleLeaf(&field->child(0));
- }
-}
-
-Field* getSingleLeaf(Field* field) {
- if (field->child_size() <= 0) {
- return field;
- } else {
- return getSingleLeaf(field->mutable_child(0));
- }
-}
-
-void FieldToString(const Field& field, std::string *flattened) {
- *flattened += std::to_string(field.field());
- if (field.has_position_index()) {
- *flattened += "[";
- *flattened += std::to_string(field.position_index());
- *flattened += "]";
- }
- if (field.child_size() <= 0) {
- return;
- }
- *flattened += ".";
- *flattened += "{";
- for (int i = 0 ; i < field.child_size(); ++i) {
- *flattened += FieldToString(field.child(i));
- }
- *flattened += "},";
-}
-
-std::string FieldToString(const Field& field) {
- std::string flatten;
- FieldToString(field, &flatten);
- return flatten;
-}
-
-bool setFieldInLeafValueProto(const Field &field, DimensionsValue* leafValue) {
- if (field.child_size() <= 0) {
- leafValue->set_field(field.field());
- return true;
- } else if (field.child_size() == 1) {
- return setFieldInLeafValueProto(field.child(0), leafValue);
- } else {
- ALOGE("Not able to set the 'field' in leaf value for multiple children.");
- return false;
- }
-}
-
-void buildSimpleAtomField(const int tagId, const int atomFieldNum, Field *field) {
- field->set_field(tagId);
- field->add_child()->set_field(atomFieldNum);
-}
-
-void buildSimpleAtomField(const int tagId, Field *field) {
- field->set_field(tagId);
-}
-
-void appendLeaf(Field *parent, int node_field_num) {
- if (!parent->has_field()) {
- parent->set_field(node_field_num);
- } else if (parent->child_size() <= 0) {
- parent->add_child()->set_field(node_field_num);
- } else {
- appendLeaf(parent->mutable_child(0), node_field_num);
- }
-}
-
-void appendLeaf(Field *parent, int node_field_num, int position) {
- if (!parent->has_field()) {
- parent->set_field(node_field_num);
- parent->set_position_index(position);
- } else if (parent->child_size() <= 0) {
- auto child = parent->add_child();
- child->set_field(node_field_num);
- child->set_position_index(position);
- } else {
- appendLeaf(parent->mutable_child(0), node_field_num, position);
- }
-}
-
-void increasePosition(Field *field) {
- if (!field->has_position_index()) {
- field->set_position_index(0);
- } else {
- field->set_position_index(field->position_index() + 1);
- }
-}
-
-int getPositionByReferenceField(const Field& ref, const Field& field_with_index) {
- if (ref.child_size() <= 0) {
- return field_with_index.position_index();
- }
- if (ref.child_size() != 1 ||
- field_with_index.child_size() != 1) {
- return -1;
- }
- return getPositionByReferenceField(ref.child(0), field_with_index.child(0));
-}
-
-namespace {
-
-void findFields(
- const FieldValueMap& fieldValueMap,
- const FieldMatcher& matcher,
- Field* rootField,
- Field* leafField,
- std::set<Field, FieldCmp>* rootFields);
-
-void findNonRepeatedFields(
- const FieldValueMap& fieldValueMap,
- const FieldMatcher& matcher,
- Field* rootField,
- Field* leafField,
- std::set<Field, FieldCmp>* rootFields) {
- if (matcher.child_size() > 0) {
- Field* newLeafField = leafField->add_child();
- for (const auto& childMatcher : matcher.child()) {
- newLeafField->set_field(childMatcher.field());
- findFields(fieldValueMap, childMatcher, rootField, newLeafField, rootFields);
- }
- leafField->clear_child();
- } else {
- auto ret = fieldValueMap.equal_range(*rootField);
- int found = 0;
- for (auto it = ret.first; it != ret.second; ++it) {
- found++;
- }
- // Not found.
- if (found <= 0) {
- return;
- }
- if (found > 1) {
- ALOGE("Found multiple values for optional field.");
- return;
- }
- rootFields->insert(ret.first->first);
- }
-}
-
-void findRepeatedFields(const FieldValueMap& fieldValueMap, const FieldMatcher& matcher,
- Field* rootField, Field* leafField,
- std::set<Field, FieldCmp>* rootFields) {
- if (matcher.position() == Position::FIRST) {
- leafField->set_position_index(0);
- findNonRepeatedFields(fieldValueMap, matcher, rootField, leafField, rootFields);
- leafField->clear_position_index();
- } else {
- auto itLower = fieldValueMap.lower_bound(*rootField);
- if (itLower == fieldValueMap.end()) {
- return;
- }
-
- const int leafFieldNum = leafField->field();
- leafField->set_field(leafFieldNum + 1);
- auto itUpper = fieldValueMap.lower_bound(*rootField);
- // Resets the field number.
- leafField->set_field(leafFieldNum);
-
- switch (matcher.position()) {
- case Position::LAST:
- {
- itUpper--;
- if (itUpper != fieldValueMap.end()) {
- int last_index = getPositionByReferenceField(*rootField, itUpper->first);
- if (last_index < 0) {
- return;
- }
- leafField->set_position_index(last_index);
- findNonRepeatedFields(
- fieldValueMap, matcher, rootField, leafField, rootFields);
- leafField->clear_position_index();
- }
- }
- break;
- case Position::ANY:
- {
- std::set<int> indexes;
- for (auto it = itLower; it != itUpper; ++it) {
- int index = getPositionByReferenceField(*rootField, it->first);
- if (index >= 0) {
- indexes.insert(index);
- }
- }
- if (!indexes.empty()) {
- for (const int index : indexes) {
- leafField->set_position_index(index);
- findNonRepeatedFields(
- fieldValueMap, matcher, rootField, leafField, rootFields);
- leafField->clear_position_index();
- }
- }
- }
- break;
- default:
- break;
- }
- }
-}
-
-void findFields(
- const FieldValueMap& fieldValueMap,
- const FieldMatcher& matcher,
- Field* rootField,
- Field* leafField,
- std::set<Field, FieldCmp>* rootFields) {
- if (!matcher.has_position()) {
- findNonRepeatedFields(fieldValueMap, matcher, rootField, leafField, rootFields);
- } else {
- findRepeatedFields(fieldValueMap, matcher, rootField, leafField, rootFields);
- }
-}
-
-} // namespace
-
-void findFields(
- const FieldValueMap& fieldValueMap,
- const FieldMatcher& matcher,
- std::set<Field, FieldCmp>* rootFields) {
- if (!matcher.has_field() || fieldValueMap.empty()) {
- return;
- }
- Field rootField;
- buildSimpleAtomField(matcher.field(), &rootField);
- return findFields(fieldValueMap, matcher, &rootField, &rootField, rootFields);
-}
-
-void filterFields(const FieldMatcher& matcher, FieldValueMap* fieldValueMap) {
- if (!matcher.has_field()) {
- return;
- }
- std::set<Field, FieldCmp> rootFields;
- findFields(*fieldValueMap, matcher, &rootFields);
- auto it = fieldValueMap->begin();
- while (it != fieldValueMap->end()) {
- if (rootFields.find(it->first) == rootFields.end()) {
- it = fieldValueMap->erase(it);
- } else {
- it++;
- }
- }
-}
-
-bool hasLeafNode(const FieldMatcher& matcher) {
- if (!matcher.has_field()) {
- return false;
- }
- for (int i = 0; i < matcher.child_size(); ++i) {
- if (hasLeafNode(matcher.child(i))) {
- return true;
- }
- }
- return true;
-}
-
-bool IsAttributionUidField(const Field& field) {
- return field.child_size() == 1 && field.child(0).field() == 1
- && field.child(0).child_size() == 1 && field.child(0).child(0).field() == 1;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/field_util.h b/cmds/statsd/src/field_util.h
deleted file mode 100644
index b04465d..0000000
--- a/cmds/statsd/src/field_util.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_internal.pb.h"
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
-
-#include <map>
-#include <set>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Function to sort the Field protos.
-bool CompareField(const Field& a, const Field& b);
-struct FieldCmp {
- bool operator()(const Field& a, const Field& b) const {
- return CompareField(a, b);
- }
-};
-
-// Flattened dimensions value map. To save space, usually the key contains the tree structure info
-// and value field is only leaf node.
-typedef std::map<Field, DimensionsValue, FieldCmp> FieldValueMap;
-
-// Util function to print the Field proto.
-std::string FieldToString(const Field& field);
-
-// Util function to find the leaf node from the input Field proto and set it in the corresponding
-// value proto.
-bool setFieldInLeafValueProto(const Field &field, DimensionsValue* leafValue);
-
-// Returns the leaf node from the Field proto. It assume that the input has only one
-// leaf node at most.
-const Field* getSingleLeaf(const Field* field);
-Field* getSingleLeaf(Field* field);
-
-// Append a node to the current leaf. It assumes that the input "parent" has one leaf node at most.
-void appendLeaf(Field *parent, int node_field_num);
-void appendLeaf(Field *parent, int node_field_num, int position);
-
-// Increase the position index for the node. If the "position_index" is not set, set it as 0.
-void increasePosition(Field *field);
-
-// Returns true if the matcher has specified at least one leaf node.
-bool hasLeafNode(const FieldMatcher& matcher);
-
-// The two input Field proto are describing the same tree structure. Both contain one leaf node at
-// most. This is find the position index info for the leaf node at "reference" stored in the
-// "field_with_index" tree.
-int getPositionByReferenceField(const Field& reference, const Field& field_with_index);
-
-// Utils to build the Field proto for simple atom fields.
-void buildSimpleAtomField(const int tagId, const int atomFieldNum, Field* field);
-void buildSimpleAtomField(const int tagId, Field* field);
-
-// Find out all the fields specified by the matcher.
-void findFields(
- const FieldValueMap& fieldValueMap, const FieldMatcher& matcher,
- std::set<Field, FieldCmp>* rootFields);
-
-// Filter out the fields not in the field matcher.
-void filterFields(const FieldMatcher& matcher, FieldValueMap* fieldValueMap);
-
-// Returns if the field is attribution node uid field.
-bool IsAttributionUidField(const Field& field);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index e1ab5d5..909b74f 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -17,13 +17,8 @@
#define DEBUG false // STOPSHIP if true
#include "logd/LogEvent.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-#include <set>
#include <sstream>
-#include "field_util.h"
-#include "dimension.h"
#include "stats_log_util.h"
namespace android {
@@ -152,9 +147,6 @@
if (android_log_write_string8(mContext, node.tag().c_str()) < 0) {
return false;
}
- if (android_log_write_int32(mContext, node.uid()) < 0) {
- return false;
- }
if (android_log_write_list_end(mContext) < 0) {
return false;
}
@@ -163,47 +155,23 @@
return false;
}
-namespace {
-
-void increaseField(Field *field, bool is_child) {
- if (is_child) {
- if (field->child_size() <= 0) {
- field->add_child();
- }
- } else {
- field->clear_child();
- }
- Field* curr = is_child ? field->mutable_child(0) : field;
- if (!curr->has_field()) {
- curr->set_field(1);
- } else {
- curr->set_field(curr->field() + 1);
- }
-}
-
-} // namespace
-
/**
* The elements of each log event are stored as a vector of android_log_list_elements.
* The goal is to do as little preprocessing as possible, because we read a tiny fraction
* of the elements that are written to the log.
+ *
+ * The idea here is to read through the log items once, we get as much information we need for
+ * matching as possible. Because this log will be matched against lots of matchers.
*/
void LogEvent::init(android_log_context context) {
- if (!context) {
- return;
- }
android_log_list_element elem;
- // TODO: The log is actually structured inside one list. This is convenient
- // because we'll be able to use it to put the attribution (WorkSource) block first
- // without doing our own tagging scheme. Until that change is in, just drop the
- // list-related log elements and the order we get there is our index-keyed data
- // structure.
int i = 0;
int seenListStart = 0;
- Field fieldTree;
- Field* atomField = fieldTree.add_child();
+ int32_t field = 0;
+ int depth = -1;
+ int pos[] = {1, 1, 1};
do {
elem = android_log_read_next(context);
switch ((int)elem.type) {
@@ -211,55 +179,81 @@
// elem at [0] is EVENT_TYPE_LIST, [1] is the tag id.
if (i == 1) {
mTagId = elem.data.int32;
- fieldTree.set_field(mTagId);
} else {
- increaseField(atomField, seenListStart > 0/* is_child */);
- mFieldValueMap[fieldTree].set_value_int(elem.data.int32);
- }
- break;
- case EVENT_TYPE_FLOAT:
- {
- increaseField(atomField, seenListStart > 0/* is_child */);
- mFieldValueMap[fieldTree].set_value_float(elem.data.float32);
- }
- break;
- case EVENT_TYPE_STRING:
- {
- increaseField(atomField, seenListStart > 0/* is_child */);
- mFieldValueMap[fieldTree].set_value_str(
- string(elem.data.string, elem.len).c_str());
- }
- break;
- case EVENT_TYPE_LONG:
- {
- increaseField(atomField, seenListStart > 0 /* is_child */);
- mFieldValueMap[fieldTree].set_value_long(elem.data.int64);
- }
- break;
- case EVENT_TYPE_LIST:
- if (i >= 1) {
- if (seenListStart > 0) {
- increasePosition(atomField);
- } else {
- increaseField(atomField, false /* is_child */);
- }
- seenListStart++;
- if (seenListStart >= 3) {
- ALOGE("Depth > 2. Not supported!");
+ if (depth < 0 || depth > 2) {
return;
}
+
+ mValues.push_back(
+ FieldValue(Field(mTagId, pos, depth), Value((int32_t)elem.data.int32)));
+
+ pos[depth]++;
}
break;
- case EVENT_TYPE_LIST_STOP:
- seenListStart--;
- if (seenListStart == 0) {
- atomField->clear_position_index();
- } else {
- if (atomField->child_size() > 0) {
- atomField->mutable_child(0)->clear_field();
+ case EVENT_TYPE_FLOAT: {
+ if (depth < 0 || depth > 2) {
+ ALOGE("Depth > 2. Not supported!");
+ return;
+ }
+
+ mValues.push_back(FieldValue(Field(mTagId, pos, depth), Value(elem.data.float32)));
+
+ pos[depth]++;
+
+ } break;
+ case EVENT_TYPE_STRING: {
+ if (depth < 0 || depth > 2) {
+ ALOGE("Depth > 2. Not supported!");
+ return;
+ }
+
+ mValues.push_back(FieldValue(Field(mTagId, pos, depth),
+ Value(string(elem.data.string, elem.len))));
+
+ pos[depth]++;
+
+ } break;
+ case EVENT_TYPE_LONG: {
+ if (depth < 0 || depth > 2) {
+ ALOGE("Depth > 2. Not supported!");
+ return;
+ }
+ mValues.push_back(
+ FieldValue(Field(mTagId, pos, depth), Value((int64_t)elem.data.int64)));
+
+ pos[depth]++;
+
+ } break;
+ case EVENT_TYPE_LIST:
+ depth++;
+ if (depth > 2) {
+ ALOGE("Depth > 2. Not supported!");
+ return;
+ }
+ pos[depth] = 1;
+
+ break;
+ case EVENT_TYPE_LIST_STOP: {
+ int prevDepth = depth;
+ depth--;
+ if (depth >= 0 && depth < 2) {
+ // Now go back to decorate the previous items that are last at prevDepth.
+ // So that we can later easily match them with Position=Last matchers.
+ pos[prevDepth]--;
+ int path = getEncodedField(pos, prevDepth, false);
+ for (size_t j = mValues.size() - 1; j >= 0; j--) {
+ if (mValues[j].mField.getDepth() >= prevDepth &&
+ mValues[j].mField.getPath(prevDepth) == path) {
+ mValues[j].mField.decorateLastPos(prevDepth);
+ } else {
+ // Safe to break, because the items are in DFS order.
+ break;
+ }
}
+ pos[depth]++;
}
break;
+ }
case EVENT_TYPE_UNKNOWN:
break;
default:
@@ -270,162 +264,115 @@
}
int64_t LogEvent::GetLong(size_t key, status_t* err) const {
- DimensionsValue value;
- if (!GetSimpleAtomDimensionsValueProto(key, &value)) {
- *err = BAD_INDEX;
- return 0;
- }
- const DimensionsValue* leafValue = getSingleLeafValue(&value);
- switch (leafValue->value_case()) {
- case DimensionsValue::ValueCase::kValueInt:
- return (int64_t)leafValue->value_int();
- case DimensionsValue::ValueCase::kValueLong:
- return leafValue->value_long();
- case DimensionsValue::ValueCase::kValueBool:
- return leafValue->value_bool() ? 1 : 0;
- case DimensionsValue::ValueCase::kValueFloat:
- return (int64_t)leafValue->value_float();
- case DimensionsValue::ValueCase::kValueTuple:
- case DimensionsValue::ValueCase::kValueStr:
- case DimensionsValue::ValueCase::VALUE_NOT_SET: {
- *err = BAD_TYPE;
- return 0;
+ // TODO: encapsulate the magical operations all in Field struct as a static function.
+ int field = getSimpleField(key);
+ for (const auto& value : mValues) {
+ if (value.mField.getField() == field) {
+ if (value.mValue.getType() == INT) {
+ return value.mValue.int_value;
+ } else {
+ *err = BAD_TYPE;
+ return 0;
+ }
+ }
+ if ((size_t)value.mField.getPosAtDepth(0) > key) {
+ break;
}
}
+
+ *err = BAD_INDEX;
+ return 0;
}
int LogEvent::GetInt(size_t key, status_t* err) const {
- DimensionsValue value;
- if (!GetSimpleAtomDimensionsValueProto(key, &value)) {
+ int field = getSimpleField(key);
+ for (const auto& value : mValues) {
+ if (value.mField.getField() == field) {
+ if (value.mValue.getType() == INT) {
+ return value.mValue.int_value;
+ } else {
+ *err = BAD_TYPE;
+ return 0;
+ }
+ }
+ if ((size_t)value.mField.getPosAtDepth(0) > key) {
+ break;
+ }
+ }
+
*err = BAD_INDEX;
return 0;
- }
- const DimensionsValue* leafValue = getSingleLeafValue(&value);
- switch (leafValue->value_case()) {
- case DimensionsValue::ValueCase::kValueInt:
- return leafValue->value_int();
- case DimensionsValue::ValueCase::kValueLong:
- case DimensionsValue::ValueCase::kValueBool:
- case DimensionsValue::ValueCase::kValueFloat:
- case DimensionsValue::ValueCase::kValueTuple:
- case DimensionsValue::ValueCase::kValueStr:
- case DimensionsValue::ValueCase::VALUE_NOT_SET: {
- *err = BAD_TYPE;
- return 0;
- }
- }
}
const char* LogEvent::GetString(size_t key, status_t* err) const {
- DimensionsValue value;
- if (!GetSimpleAtomDimensionsValueProto(key, &value)) {
- *err = BAD_INDEX;
- return 0;
- }
- const DimensionsValue* leafValue = getSingleLeafValue(&value);
- switch (leafValue->value_case()) {
- case DimensionsValue::ValueCase::kValueStr:
- return leafValue->value_str().c_str();
- case DimensionsValue::ValueCase::kValueInt:
- case DimensionsValue::ValueCase::kValueLong:
- case DimensionsValue::ValueCase::kValueBool:
- case DimensionsValue::ValueCase::kValueFloat:
- case DimensionsValue::ValueCase::kValueTuple:
- case DimensionsValue::ValueCase::VALUE_NOT_SET: {
- *err = BAD_TYPE;
- return 0;
+ int field = getSimpleField(key);
+ for (const auto& value : mValues) {
+ if (value.mField.getField() == field) {
+ if (value.mValue.getType() == STRING) {
+ return value.mValue.str_value.c_str();
+ } else {
+ *err = BAD_TYPE;
+ return 0;
+ }
+ }
+ if ((size_t)value.mField.getPosAtDepth(0) > key) {
+ break;
}
}
+
+ *err = BAD_INDEX;
+ return NULL;
}
bool LogEvent::GetBool(size_t key, status_t* err) const {
- DimensionsValue value;
- if (!GetSimpleAtomDimensionsValueProto(key, &value)) {
- *err = BAD_INDEX;
- return 0;
- }
- const DimensionsValue* leafValue = getSingleLeafValue(&value);
- switch (leafValue->value_case()) {
- case DimensionsValue::ValueCase::kValueInt:
- return leafValue->value_int() != 0;
- case DimensionsValue::ValueCase::kValueLong:
- return leafValue->value_long() != 0;
- case DimensionsValue::ValueCase::kValueBool:
- return leafValue->value_bool();
- case DimensionsValue::ValueCase::kValueFloat:
- return leafValue->value_float() != 0;
- case DimensionsValue::ValueCase::kValueTuple:
- case DimensionsValue::ValueCase::kValueStr:
- case DimensionsValue::ValueCase::VALUE_NOT_SET: {
- *err = BAD_TYPE;
- return 0;
+ int field = getSimpleField(key);
+ for (const auto& value : mValues) {
+ if (value.mField.getField() == field) {
+ if (value.mValue.getType() == INT) {
+ return value.mValue.int_value != 0;
+ } else if (value.mValue.getType() == LONG) {
+ return value.mValue.long_value != 0;
+ } else {
+ *err = BAD_TYPE;
+ return false;
+ }
+ }
+ if ((size_t)value.mField.getPosAtDepth(0) > key) {
+ break;
}
}
+
+ *err = BAD_INDEX;
+ return false;
}
float LogEvent::GetFloat(size_t key, status_t* err) const {
- DimensionsValue value;
- if (!GetSimpleAtomDimensionsValueProto(key, &value)) {
- *err = BAD_INDEX;
- return 0;
- }
- const DimensionsValue* leafValue = getSingleLeafValue(&value);
- switch (leafValue->value_case()) {
- case DimensionsValue::ValueCase::kValueInt:
- return (float)leafValue->value_int();
- case DimensionsValue::ValueCase::kValueLong:
- return (float)leafValue->value_long();
- case DimensionsValue::ValueCase::kValueBool:
- return leafValue->value_bool() ? 1.0f : 0.0f;
- case DimensionsValue::ValueCase::kValueFloat:
- return leafValue->value_float();
- case DimensionsValue::ValueCase::kValueTuple:
- case DimensionsValue::ValueCase::kValueStr:
- case DimensionsValue::ValueCase::VALUE_NOT_SET: {
- *err = BAD_TYPE;
- return 0;
+ int field = getSimpleField(key);
+ for (const auto& value : mValues) {
+ if (value.mField.getField() == field) {
+ if (value.mValue.getType() == FLOAT) {
+ return value.mValue.float_value;
+ } else {
+ *err = BAD_TYPE;
+ return 0.0;
+ }
+ }
+ if ((size_t)value.mField.getPosAtDepth(0) > key) {
+ break;
}
}
-}
-void LogEvent::GetAtomDimensionsValueProtos(const FieldMatcher& matcher,
- std::vector<DimensionsValue> *dimensionsValues) const {
- findDimensionsValues(mFieldValueMap, matcher, dimensionsValues);
-}
-
-bool LogEvent::GetAtomDimensionsValueProto(const FieldMatcher& matcher,
- DimensionsValue* dimensionsValue) const {
- std::vector<DimensionsValue> rootDimensionsValues;
- findDimensionsValues(mFieldValueMap, matcher, &rootDimensionsValues);
- if (rootDimensionsValues.size() != 1) {
- return false;
- }
- *dimensionsValue = rootDimensionsValues.front();
- return true;
-}
-
-bool LogEvent::GetSimpleAtomDimensionsValueProto(size_t atomField,
- DimensionsValue* dimensionsValue) const {
- FieldMatcher matcher;
- buildSimpleAtomFieldMatcher(mTagId, atomField, &matcher);
- return GetAtomDimensionsValueProto(matcher, dimensionsValue);
-}
-
-DimensionsValue* LogEvent::findFieldValueOrNull(const Field& field) {
- auto it = mFieldValueMap.find(field);
- if (it == mFieldValueMap.end()) {
- return nullptr;
- }
- return &it->second;
+ *err = BAD_INDEX;
+ return 0.0;
}
string LogEvent::ToString() const {
ostringstream result;
result << "{ " << mTimestampNs << " (" << mTagId << ")";
- for (const auto& itr : mFieldValueMap) {
- result << FieldToString(itr.first);
+ for (const auto& value : mValues) {
+ result << StringPrintf("%#x", value.mField.getField());
result << "->";
- result << DimensionsValueToString(itr.second);
+ result << value.mValue.toString();
result << " ";
}
result << " }";
@@ -433,7 +380,7 @@
}
void LogEvent::ToProto(ProtoOutputStream& protoOutput) const {
- writeFieldValueTreeToStream(getFieldValueMap(), &protoOutput);
+ writeFieldValueTreeToStream(mTagId, getValues(), &protoOutput);
}
} // namespace statsd
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index d521e09..0895daa 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -16,7 +16,7 @@
#pragma once
-#include "field_util.h"
+#include "FieldValue.h"
#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
#include <android/util/ProtoOutputStream.h>
@@ -24,11 +24,8 @@
#include <log/log_read.h>
#include <private/android_logger.h>
#include <utils/Errors.h>
-#include <utils/JenkinsHash.h>
-#include <memory>
#include <string>
-#include <map>
#include <vector>
namespace android {
@@ -37,7 +34,6 @@
using std::string;
using std::vector;
-
/**
* Wrapper for the log_msg structure.
*/
@@ -81,19 +77,6 @@
bool GetBool(size_t key, status_t* err) const;
float GetFloat(size_t key, status_t* err) const;
- /*
- * Get DimensionsValue proto objects from FieldMatcher.
- */
- void GetAtomDimensionsValueProtos(
- const FieldMatcher& matcher, std::vector<DimensionsValue> *dimensionsValues) const;
- bool GetAtomDimensionsValueProto(
- const FieldMatcher& matcher, DimensionsValue* dimensionsValue) const;
-
- /*
- * Get a DimensionsValue proto objects from Field.
- */
- bool GetSimpleAtomDimensionsValueProto(size_t field, DimensionsValue* dimensionsValue) const;
-
/**
* Write test data to the LogEvent. This can only be used when the LogEvent is constructed
* using LogEvent(tagId, timestampNs). You need to call init() before you can read from it.
@@ -129,15 +112,16 @@
void setTimestampNs(uint64_t timestampNs) {mTimestampNs = timestampNs;}
inline int size() const {
- return mFieldValueMap.size();
+ return mValues.size();
}
- /**
- * Returns the mutable DimensionsValue proto for the specific the field.
- */
- DimensionsValue* findFieldValueOrNull(const Field& field);
+ const std::vector<FieldValue>& getValues() const {
+ return mValues;
+ }
- inline const FieldValueMap& getFieldValueMap() const { return mFieldValueMap; }
+ std::vector<FieldValue>* getMutableValues() {
+ return &mValues;
+ }
private:
/**
@@ -151,7 +135,9 @@
*/
void init(android_log_context context);
- FieldValueMap mFieldValueMap;
+ // The items are naturally sorted in DFS order as we read them. this allows us to do fast
+ // matching.
+ std::vector<FieldValue> mValues;
// This field is used when statsD wants to create log event object and write fields to it. After
// calling init() function, this object would be destroyed to save memory usage.
diff --git a/cmds/statsd/src/matchers/matcher_util.cpp b/cmds/statsd/src/matchers/matcher_util.cpp
index fae9172..944764b 100644
--- a/cmds/statsd/src/matchers/matcher_util.cpp
+++ b/cmds/statsd/src/matchers/matcher_util.cpp
@@ -13,23 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+#define DEBUG false // STOPSHIP if true
#include "Log.h"
#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
#include "matchers/LogMatchingTracker.h"
#include "matchers/matcher_util.h"
-#include "dimension.h"
#include "stats_util.h"
-#include "field_util.h"
-
-#include <log/event_tag_map.h>
-#include <log/log_event_list.h>
-#include <log/logprint.h>
-#include <utils/Errors.h>
-
-#include <sstream>
-#include <unordered_map>
using std::ostringstream;
using std::set;
@@ -93,198 +83,224 @@
return matched;
}
-namespace {
-
-bool matchFieldSimple(const UidMap& uidMap, const FieldValueMap& fieldMap,
- const FieldValueMatcher&matcher, Field* rootField, Field* leafField);
-
-bool matchesNonRepeatedField(const UidMap& uidMap, const FieldValueMap& fieldMap,
- const FieldValueMatcher&matcher, Field* rootField, Field* leafField) {
- if (matcher.value_matcher_case() ==
- FieldValueMatcher::ValueMatcherCase::VALUE_MATCHER_NOT_SET) {
- return !fieldMap.empty() && fieldMap.begin()->first.field() == matcher.field();
- } else if (matcher.value_matcher_case() == FieldValueMatcher::ValueMatcherCase::kMatchesTuple) {
- bool allMatched = true;
- Field* newLeafField = leafField->add_child();
- for (int i = 0; allMatched && i < matcher.matches_tuple().field_value_matcher_size(); ++i) {
- const auto& childMatcher = matcher.matches_tuple().field_value_matcher(i);
- newLeafField->set_field(childMatcher.field());
- allMatched &= matchFieldSimple(uidMap, fieldMap, childMatcher, rootField, newLeafField);
- }
- leafField->clear_child();
- return allMatched;
- } else {
- auto ret = fieldMap.equal_range(*rootField);
- int found = 0;
- for (auto it = ret.first; it != ret.second; ++it) {
- found++;
- }
- // Not found.
- if (found <= 0) {
- return false;
- }
- if (found > 1) {
- ALOGE("Found multiple values for optional field.");
- return false;
- }
- bool matched = false;
- switch (matcher.value_matcher_case()) {
- case FieldValueMatcher::ValueMatcherCase::kEqBool: {
- // Logd does not support bool, it is int instead.
- matched = ((ret.first->second.value_int() > 0) == matcher.eq_bool());
- break;
- }
- case FieldValueMatcher::ValueMatcherCase::kEqString: {
- if (IsAttributionUidField(*rootField)) {
- const int uid = ret.first->second.value_int();
- std::set<string> packageNames =
- uidMap.getAppNamesFromUid(uid, true /* normalize*/);
- matched = packageNames.find(matcher.eq_string()) != packageNames.end();
- } else {
- matched = (ret.first->second.value_str() == matcher.eq_string());
- }
- break;
- }
- case FieldValueMatcher::ValueMatcherCase::kEqInt: {
- int64_t val = ret.first->second.has_value_int() ?
- ret.first->second.value_int() : ret.first->second.value_long();
- matched = (val == matcher.eq_int());
- break;
- }
- case FieldValueMatcher::ValueMatcherCase::kLtInt: {
- int64_t val = ret.first->second.has_value_int() ?
- ret.first->second.value_int() : ret.first->second.value_long();
- matched = (val < matcher.lt_int());
- break;
- }
- case FieldValueMatcher::ValueMatcherCase::kGtInt: {
- int64_t val = ret.first->second.has_value_int() ?
- ret.first->second.value_int() : ret.first->second.value_long();
- matched = (val > matcher.gt_int());
- break;
- }
- case FieldValueMatcher::ValueMatcherCase::kLtFloat: {
- matched = (ret.first->second.value_float() < matcher.lt_float());
- break;
- }
- case FieldValueMatcher::ValueMatcherCase::kGtFloat: {
- matched = (ret.first->second.value_float() > matcher.gt_float());
- break;
- }
- case FieldValueMatcher::ValueMatcherCase::kLteInt: {
- int64_t val = ret.first->second.has_value_int() ?
- ret.first->second.value_int() : ret.first->second.value_long();
- matched = (val <= matcher.lte_int());
- break;
- }
- case FieldValueMatcher::ValueMatcherCase::kGteInt: {
- int64_t val = ret.first->second.has_value_int() ?
- ret.first->second.value_int() : ret.first->second.value_long();
- matched = (val >= matcher.gte_int());
- break;
- }
- default:
- break;
- }
- return matched;
+bool tryMatchString(const UidMap& uidMap, const Field& field, const Value& value,
+ const string& str_match) {
+ if (isAttributionUidField(field, value)) {
+ int uid = value.int_value;
+ std::set<string> packageNames = uidMap.getAppNamesFromUid(uid, true /* normalize*/);
+ return packageNames.find(str_match) != packageNames.end();
+ } else if (value.getType() == STRING) {
+ return value.str_value == str_match;
}
+ return false;
}
-bool matchesRepeatedField(const UidMap& uidMap, const FieldValueMap& fieldMap,
- const FieldValueMatcher&matcher,
- Field* rootField, Field* leafField) {
- if (matcher.position() == Position::FIRST) {
- leafField->set_position_index(0);
- bool res = matchesNonRepeatedField(uidMap, fieldMap, matcher, rootField, leafField);
- leafField->clear_position_index();
- return res;
- } else {
- auto itLower = fieldMap.lower_bound(*rootField);
- if (itLower == fieldMap.end()) {
+bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher,
+ const vector<FieldValue>& values, int start, int end, int depth) {
+ if (depth > 2) {
+ ALOGE("Depth > 3 not supported");
+ return false;
+ }
+
+ if (start >= end) {
+ return false;
+ }
+
+ // Filter by entry field first
+ int newStart = -1;
+ int newEnd = end;
+ // because the fields are naturally sorted in the DFS order. we can safely
+ // break when pos is larger than the one we are searching for.
+ for (int i = start; i < end; i++) {
+ int pos = values[i].mField.getPosAtDepth(depth);
+ if (pos == matcher.field()) {
+ if (newStart == -1) {
+ newStart = i;
+ }
+ newEnd = i + 1;
+ } else if (pos > matcher.field()) {
+ break;
+ }
+ }
+
+ // Now we have zoomed in to a new range
+ start = newStart;
+ end = newEnd;
+
+ if (start == -1) {
+ // No such field found.
+ return false;
+ }
+
+ vector<pair<int, int>> ranges; // the ranges are for matching ANY position
+ if (matcher.has_position()) {
+ // Repeated fields position is stored as a node in the path.
+ depth++;
+ if (depth > 2) {
return false;
}
-
- const int leafFieldNum = leafField->field();
- leafField->set_field(leafFieldNum + 1);
- auto itUpper = fieldMap.lower_bound(*rootField);
- // Resets the field number.
- leafField->set_field(leafFieldNum);
-
switch (matcher.position()) {
- case Position::LAST:
- {
- itUpper--;
- if (itUpper == fieldMap.end()) {
- return false;
- } else {
- int last_index = getPositionByReferenceField(*rootField, itUpper->first);
- if (last_index < 0) {
- return false;
- }
- leafField->set_position_index(last_index);
- bool res = matchesNonRepeatedField(uidMap, fieldMap, matcher, rootField, leafField);
- leafField->clear_position_index();
- return res;
- }
- }
- break;
- case Position::ANY:
- {
- bool matched = false;
- for (auto it = itLower; it != itUpper; ++it) {
- int index = getPositionByReferenceField(*rootField, it->first);
- if (index >= 0) {
- leafField->set_position_index(index);
- matched |= matchesNonRepeatedField(uidMap, fieldMap, matcher, rootField, leafField);
- leafField->clear_position_index();
- if (matched) {
- break;
- }
- }
+ case Position::FIRST: {
+ for (int i = start; i < end; i++) {
+ int pos = values[i].mField.getPosAtDepth(depth);
+ if (pos != 1) {
+ // Again, the log elements are stored in sorted order. so
+ // once the position is > 1, we break;
+ end = i;
+ break;
}
- return matched;
- }
- default:
- return false;
- }
- }
-
-}
-
-bool matchFieldSimple(const UidMap& uidMap, const FieldValueMap& fieldMap,
- const FieldValueMatcher&matcher, Field* rootField, Field* leafField) {
- if (!matcher.has_position()) {
- return matchesNonRepeatedField(uidMap, fieldMap, matcher, rootField, leafField);
+ }
+ ranges.push_back(std::make_pair(start, end));
+ break;
+ }
+ case Position::LAST: {
+ // move the starting index to the first LAST field at the depth.
+ for (int i = start; i < end; i++) {
+ if (values[i].mField.isLastPos(depth)) {
+ start = i;
+ break;
+ }
+ }
+ ranges.push_back(std::make_pair(start, end));
+ break;
+ }
+ case Position::ANY: {
+ // ANY means all the children matchers match in any of the sub trees, it's a match
+ newStart = start;
+ newEnd = end;
+ // Here start is guaranteed to be a valid index.
+ int currentPos = values[start].mField.getPosAtDepth(depth);
+ // Now find all sub trees ranges.
+ for (int i = start; i < end; i++) {
+ int newPos = values[i].mField.getPosAtDepth(depth);
+ if (newPos != currentPos) {
+ ranges.push_back(std::make_pair(newStart, i));
+ newStart = i;
+ currentPos = newPos;
+ }
+ }
+ ranges.push_back(std::make_pair(newStart, end));
+ break;
+ }
+ case Position::POSITION_UNKNOWN:
+ break;
+ }
} else {
- return matchesRepeatedField(uidMap, fieldMap, matcher, rootField, leafField);
+ // No position
+ ranges.push_back(std::make_pair(start, end));
+ }
+ // start and end are still pointing to the matched range.
+ switch (matcher.value_matcher_case()) {
+ case FieldValueMatcher::kMatchesTuple: {
+ ++depth;
+ // If any range matches all matchers, good.
+ for (const auto& range : ranges) {
+ bool matched = true;
+ for (const auto& subMatcher : matcher.matches_tuple().field_value_matcher()) {
+ if (!matchesSimple(uidMap, subMatcher, values, range.first, range.second,
+ depth)) {
+ matched = false;
+ break;
+ }
+ }
+ if (matched) return true;
+ }
+ return false;
+ }
+ case FieldValueMatcher::ValueMatcherCase::kEqBool: {
+ for (int i = start; i < end; i++) {
+ if ((values[i].mValue.getType() == INT &&
+ (values[i].mValue.int_value != 0) == matcher.eq_bool()) ||
+ (values[i].mValue.getType() == LONG &&
+ (values[i].mValue.long_value != 0) == matcher.eq_bool())) {
+ return true;
+ }
+ }
+ return false;
+ }
+ case FieldValueMatcher::ValueMatcherCase::kEqString: {
+ for (int i = start; i < end; i++) {
+ if (tryMatchString(uidMap, values[i].mField, values[i].mValue,
+ matcher.eq_string())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ case FieldValueMatcher::ValueMatcherCase::kEqInt:
+ for (int i = start; i < end; i++) {
+ if (values[i].mValue.getType() == INT &&
+ (matcher.eq_int() == values[i].mValue.int_value)) {
+ return true;
+ }
+ }
+ return false;
+ case FieldValueMatcher::ValueMatcherCase::kLtInt:
+ for (int i = start; i < end; i++) {
+ if (values[i].mValue.getType() == INT &&
+ (values[i].mValue.int_value < matcher.lt_int())) {
+ return true;
+ }
+ }
+ return false;
+ case FieldValueMatcher::ValueMatcherCase::kGtInt:
+ for (int i = start; i < end; i++) {
+ if (values[i].mValue.getType() == INT &&
+ (values[i].mValue.int_value > matcher.gt_int())) {
+ return true;
+ }
+ }
+ return false;
+ case FieldValueMatcher::ValueMatcherCase::kLtFloat:
+ for (int i = start; i < end; i++) {
+ if (values[i].mValue.getType() == FLOAT &&
+ (values[i].mValue.float_value < matcher.lt_float())) {
+ return true;
+ }
+ }
+ return false;
+ case FieldValueMatcher::ValueMatcherCase::kGtFloat:
+ for (int i = start; i < end; i++) {
+ if (values[i].mValue.getType() == FLOAT &&
+ (values[i].mValue.float_value > matcher.gt_float())) {
+ return true;
+ }
+ }
+ return false;
+ case FieldValueMatcher::ValueMatcherCase::kLteInt:
+ for (int i = start; i < end; i++) {
+ if (values[i].mValue.getType() == INT &&
+ (values[i].mValue.int_value <= matcher.lte_int())) {
+ return true;
+ }
+ }
+ return false;
+ case FieldValueMatcher::ValueMatcherCase::kGteInt:
+ for (int i = start; i < end; i++) {
+ if (values[i].mValue.getType() == INT &&
+ (values[i].mValue.int_value >= matcher.gte_int())) {
+ return true;
+ }
+ }
+ return false;
+ default:
+ return false;
}
}
-} // namespace
-
bool matchesSimple(const UidMap& uidMap, const SimpleAtomMatcher& simpleMatcher,
const LogEvent& event) {
if (simpleMatcher.field_value_matcher_size() <= 0) {
return event.GetTagId() == simpleMatcher.atom_id();
}
- Field root_field;
- root_field.set_field(simpleMatcher.atom_id());
- FieldValueMatcher root_field_matcher;
- root_field_matcher.set_field(simpleMatcher.atom_id());
- for (int i = 0; i < simpleMatcher.field_value_matcher_size(); i++) {
- *root_field_matcher.mutable_matches_tuple()->add_field_value_matcher() =
- simpleMatcher.field_value_matcher(i);
+ for (const auto& matcher : simpleMatcher.field_value_matcher()) {
+ if (!matchesSimple(uidMap, matcher, event.getValues(), 0, event.getValues().size(), 0)) {
+ return false;
+ }
}
- return matchFieldSimple(
- uidMap, event.getFieldValueMap(), root_field_matcher, &root_field, &root_field);
+ return true;
}
-void getDimensionKeys(const LogEvent& event, const FieldMatcher& matcher,
- std::vector<DimensionsValue> *dimensionKeys) {
- if (matcher.has_field()) {
- findDimensionsValues(event.getFieldValueMap(), matcher, dimensionKeys);
- }
-}
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/matchers/matcher_util.h b/cmds/statsd/src/matchers/matcher_util.h
index a45a9fb..872cd8e 100644
--- a/cmds/statsd/src/matchers/matcher_util.h
+++ b/cmds/statsd/src/matchers/matcher_util.h
@@ -45,9 +45,6 @@
bool matchesSimple(const UidMap& uidMap,
const SimpleAtomMatcher& simpleMatcher, const LogEvent& wrapper);
-void getDimensionKeys(const LogEvent& event, const FieldMatcher& matcher,
- std::vector<DimensionsValue> *dimensionKeys);
-
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index 5a042b6..bd2674b 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -21,7 +21,6 @@
#include "guardrail/StatsdStats.h"
#include "stats_util.h"
#include "stats_log_util.h"
-#include "dimension.h"
#include <limits.h>
#include <stdlib.h>
@@ -69,16 +68,26 @@
mBucketSizeNs = LLONG_MAX;
}
- // TODO: use UidMap if uid->pkg_name is required
- mDimensionsInWhat = metric.dimensions_in_what();
- mDimensionsInCondition = metric.dimensions_in_condition();
+ if (metric.has_dimensions_in_what()) {
+ translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
+ }
+
+ if (metric.has_dimensions_in_condition()) {
+ translateFieldMatcher(metric.dimensions_in_condition(), &mDimensionsInCondition);
+ }
if (metric.links().size() > 0) {
- mConditionLinks.insert(mConditionLinks.begin(), metric.links().begin(),
- metric.links().end());
+ for (const auto& link : metric.links()) {
+ Metric2Condition mc;
+ mc.conditionId = link.condition();
+ translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
+ translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
+ mMetric2ConditionLinks.push_back(mc);
+ }
+ mConditionSliced = true;
}
- mConditionSliced = (metric.links().size() > 0)||
- (mDimensionsInCondition.has_field() && mDimensionsInCondition.child_size() > 0);
+
+ mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0);
VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
(long long)mBucketSizeNs, (long long)mStartTimeNs);
@@ -92,26 +101,6 @@
VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
}
-void CountMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs, StatsLogReport* report) {
- flushIfNeededLocked(dumpTimeNs);
- report->set_metric_id(mMetricId);
-
- auto count_metrics = report->mutable_count_metrics();
- for (const auto& counter : mPastBuckets) {
- CountMetricData* metricData = count_metrics->add_data();
- *metricData->mutable_dimensions_in_what() =
- counter.first.getDimensionKeyInWhat().getDimensionsValue();
- *metricData->mutable_dimensions_in_condition() =
- counter.first.getDimensionKeyInCondition().getDimensionsValue();
- for (const auto& bucket : counter.second) {
- CountBucketInfo* bucketInfo = metricData->add_bucket_info();
- bucketInfo->set_start_bucket_nanos(bucket.mBucketStartNs);
- bucketInfo->set_end_bucket_nanos(bucket.mBucketEndNs);
- bucketInfo->set_count(bucket.mCount);
- }
- }
-}
-
void CountMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
ProtoOutputStream* protoOutput) {
flushIfNeededLocked(dumpTimeNs);
@@ -122,8 +111,6 @@
protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
long long protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_COUNT_METRICS);
- VLOG("metric %lld dump report now...",(long long)mMetricId);
-
for (const auto& counter : mPastBuckets) {
const MetricDimensionKey& dimensionKey = counter.first;
VLOG(" dimension key %s", dimensionKey.c_str());
@@ -134,15 +121,13 @@
// First fill dimension.
long long dimensionInWhatToken = protoOutput->start(
FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
- writeDimensionsValueProtoToStream(
- dimensionKey.getDimensionKeyInWhat().getDimensionsValue(), protoOutput);
+ writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), protoOutput);
protoOutput->end(dimensionInWhatToken);
if (dimensionKey.hasDimensionKeyInCondition()) {
long long dimensionInConditionToken = protoOutput->start(
FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_CONDITION);
- writeDimensionsValueProtoToStream(
- dimensionKey.getDimensionKeyInCondition().getDimensionsValue(), protoOutput);
+ writeDimensionToProto(dimensionKey.getDimensionKeyInCondition(), protoOutput);
protoOutput->end(dimensionInConditionToken);
}
@@ -200,7 +185,6 @@
const ConditionKey& conditionKey, bool condition,
const LogEvent& event) {
uint64_t eventTimeNs = event.GetTimestampNs();
-
flushIfNeededLocked(eventTimeNs);
if (condition == false) {
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index b06c77b..0c4291d 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -57,7 +57,6 @@
private:
void onDumpReportLocked(const uint64_t dumpTimeNs,
android::util::ProtoOutputStream* protoOutput) override;
- void onDumpReportLocked(const uint64_t dumpTimeNs, StatsLogReport* report) override;
// Internal interface to handle condition change.
void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 65cbc4a..6b321e1 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -21,7 +21,6 @@
#include "guardrail/StatsdStats.h"
#include "stats_util.h"
#include "stats_log_util.h"
-#include "dimension.h"
#include <limits.h>
#include <stdlib.h>
@@ -68,8 +67,7 @@
mStartIndex(startIndex),
mStopIndex(stopIndex),
mStopAllIndex(stopAllIndex),
- mNested(nesting),
- mInternalDimensions(internalDimensions) {
+ mNested(nesting) {
// TODO: The following boiler plate code appears in all MetricProducers, but we can't abstract
// them in the base class, because the proto generated CountMetric, and DurationMetric are
// not related. Maybe we should add a template in the future??
@@ -79,16 +77,28 @@
mBucketSizeNs = LLONG_MAX;
}
- // TODO: use UidMap if uid->pkg_name is required
- mDimensionsInWhat = metric.dimensions_in_what();
- mDimensionsInCondition = metric.dimensions_in_condition();
+ if (metric.has_dimensions_in_what()) {
+ translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
+ }
+
+ if (internalDimensions.has_field()) {
+ translateFieldMatcher(internalDimensions, &mInternalDimensions);
+ }
+
+ if (metric.has_dimensions_in_condition()) {
+ translateFieldMatcher(metric.dimensions_in_condition(), &mDimensionsInCondition);
+ }
if (metric.links().size() > 0) {
- mConditionLinks.insert(mConditionLinks.begin(), metric.links().begin(),
- metric.links().end());
+ for (const auto& link : metric.links()) {
+ Metric2Condition mc;
+ mc.conditionId = link.condition();
+ translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
+ translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
+ mMetric2ConditionLinks.push_back(mc);
+ }
}
- mConditionSliced = (metric.links().size() > 0)||
- (mDimensionsInCondition.has_field() && mDimensionsInCondition.child_size() > 0);
+ mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0);
VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
(long long)mBucketSizeNs, (long long)mStartTimeNs);
@@ -174,37 +184,18 @@
}
}
-void DurationMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs, StatsLogReport* report) {
- flushIfNeededLocked(dumpTimeNs);
- report->set_metric_id(mMetricId);
-
- auto duration_metrics = report->mutable_duration_metrics();
- for (const auto& pair : mPastBuckets) {
- DurationMetricData* metricData = duration_metrics->add_data();
- *metricData->mutable_dimensions_in_what() =
- pair.first.getDimensionKeyInWhat().getDimensionsValue();
- *metricData->mutable_dimensions_in_condition() =
- pair.first.getDimensionKeyInCondition().getDimensionsValue();
- for (const auto& bucket : pair.second) {
- auto bucketInfo = metricData->add_bucket_info();
- bucketInfo->set_start_bucket_nanos(bucket.mBucketStartNs);
- bucketInfo->set_end_bucket_nanos(bucket.mBucketEndNs);
- bucketInfo->set_duration_nanos(bucket.mDuration);
- }
- }
-}
-
void DurationMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
ProtoOutputStream* protoOutput) {
flushIfNeededLocked(dumpTimeNs);
if (mPastBuckets.empty()) {
+ VLOG(" Duration metric, empty return");
return;
}
protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
long long protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DURATION_METRICS);
- VLOG("metric %lld dump report now...", (long long)mMetricId);
+ VLOG("Duration metric %lld dump report now...", (long long)mMetricId);
for (const auto& pair : mPastBuckets) {
const MetricDimensionKey& dimensionKey = pair.first;
@@ -216,15 +207,13 @@
// First fill dimension.
long long dimensionToken = protoOutput->start(
FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
- writeDimensionsValueProtoToStream(
- dimensionKey.getDimensionKeyInWhat().getDimensionsValue(), protoOutput);
+ writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), protoOutput);
protoOutput->end(dimensionToken);
if (dimensionKey.hasDimensionKeyInCondition()) {
long long dimensionInConditionToken = protoOutput->start(
FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_CONDITION);
- writeDimensionsValueProtoToStream(
- dimensionKey.getDimensionKeyInCondition().getDimensionsValue(), protoOutput);
+ writeDimensionToProto(dimensionKey.getDimensionKeyInCondition(), protoOutput);
protoOutput->end(dimensionInConditionToken);
}
@@ -339,8 +328,8 @@
auto it = mCurrentSlicedDurationTrackerMap.find(eventKey);
- std::vector<DimensionsValue> values;
- getDimensionKeys(event, mInternalDimensions, &values);
+ std::vector<HashableDimensionKey> values;
+ filterValues(mInternalDimensions, event.getValues(), &values);
if (values.empty()) {
if (matcherIndex == mStartIndex) {
it->second->noteStart(DEFAULT_DIMENSION_KEY, condition,
@@ -349,13 +338,11 @@
it->second->noteStop(DEFAULT_DIMENSION_KEY, event.GetTimestampNs(), false);
}
} else {
- for (const DimensionsValue& value : values) {
+ for (const auto& value : values) {
if (matcherIndex == mStartIndex) {
- it->second->noteStart(
- HashableDimensionKey(value), condition, event.GetTimestampNs(), conditionKeys);
+ it->second->noteStart(value, condition, event.GetTimestampNs(), conditionKeys);
} else if (matcherIndex == mStopIndex) {
- it->second->noteStop(
- HashableDimensionKey(value), event.GetTimestampNs(), false);
+ it->second->noteStop(value, event.GetTimestampNs(), false);
}
}
}
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index a496016..5f29281 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -57,7 +57,6 @@
private:
void onDumpReportLocked(const uint64_t dumpTimeNs,
android::util::ProtoOutputStream* protoOutput) override;
- void onDumpReportLocked(const uint64_t dumpTimeNs, StatsLogReport* report) override;
// Internal interface to handle condition change.
void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
@@ -90,7 +89,7 @@
const bool mNested;
// The dimension from the atom predicate. e.g., uid, wakelock name.
- const FieldMatcher mInternalDimensions;
+ vector<Matcher> mInternalDimensions;
// Save the past buckets and we can clear when the StatsLogReport is dumped.
// TODO: Add a lock to mPastBuckets.
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index 936a2ef1..ed7e44d 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -55,8 +55,13 @@
const uint64_t startTimeNs)
: MetricProducer(metric.id(), key, startTimeNs, conditionIndex, wizard) {
if (metric.links().size() > 0) {
- mConditionLinks.insert(mConditionLinks.begin(), metric.links().begin(),
- metric.links().end());
+ for (const auto& link : metric.links()) {
+ Metric2Condition mc;
+ mc.conditionId = link.condition();
+ translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
+ translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
+ mMetric2ConditionLinks.push_back(mc);
+ }
mConditionSliced = true;
}
mProto = std::make_unique<ProtoOutputStream>();
@@ -88,10 +93,6 @@
return buffer;
}
-void EventMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs, StatsLogReport* report) {
-
-}
-
void EventMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
ProtoOutputStream* protoOutput) {
if (mProto->size() <= 0) {
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.h b/cmds/statsd/src/metrics/EventMetricProducer.h
index 394ed23..3f2c5a5 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.h
+++ b/cmds/statsd/src/metrics/EventMetricProducer.h
@@ -48,7 +48,6 @@
void onDumpReportLocked(const uint64_t dumpTimeNs,
android::util::ProtoOutputStream* protoOutput) override;
- void onDumpReportLocked(const uint64_t dumpTimeNs, StatsLogReport* report) override;
// Internal interface to handle condition change.
void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index 62ee6ef..da0cafe 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -19,7 +19,6 @@
#include "GaugeMetricProducer.h"
#include "guardrail/StatsdStats.h"
-#include "dimension.h"
#include "stats_log_util.h"
#include <cutils/log.h>
@@ -77,18 +76,29 @@
mBucketSizeNs = bucketSizeMills * 1000000;
mSamplingType = metric.sampling_type();
- mFieldFilter = metric.gauge_fields_filter();
+ if (!metric.gauge_fields_filter().include_all()) {
+ translateFieldMatcher(metric.gauge_fields_filter().fields(), &mFieldMatchers);
+ }
// TODO: use UidMap if uid->pkg_name is required
- mDimensionsInWhat = metric.dimensions_in_what();
- mDimensionsInCondition = metric.dimensions_in_condition();
+ if (metric.has_dimensions_in_what()) {
+ translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
+ }
+
+ if (metric.has_dimensions_in_condition()) {
+ translateFieldMatcher(metric.dimensions_in_condition(), &mDimensionsInCondition);
+ }
if (metric.links().size() > 0) {
- mConditionLinks.insert(mConditionLinks.begin(), metric.links().begin(),
- metric.links().end());
+ for (const auto& link : metric.links()) {
+ Metric2Condition mc;
+ mc.conditionId = link.condition();
+ translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
+ translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
+ mMetric2ConditionLinks.push_back(mc);
+ }
}
- mConditionSliced = (metric.links().size() > 0)||
- (mDimensionsInCondition.has_field() && mDimensionsInCondition.child_size() > 0);
+ mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0);
// Kicks off the puller immediately.
if (mPullTagId != -1 && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
@@ -115,13 +125,6 @@
}
}
-void GaugeMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs, StatsLogReport* report) {
- flushIfNeededLocked(dumpTimeNs);
- ProtoOutputStream pbOutput;
- onDumpReportLocked(dumpTimeNs, &pbOutput);
- parseProtoOutputStream(pbOutput, report);
-}
-
void GaugeMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
ProtoOutputStream* protoOutput) {
VLOG("gauge metric %lld report now...", (long long)mMetricId);
@@ -144,15 +147,13 @@
// First fill dimension.
long long dimensionToken = protoOutput->start(
FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
- writeDimensionsValueProtoToStream(
- dimensionKey.getDimensionKeyInWhat().getDimensionsValue(), protoOutput);
+ writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), protoOutput);
protoOutput->end(dimensionToken);
if (dimensionKey.hasDimensionKeyInCondition()) {
long long dimensionInConditionToken = protoOutput->start(
FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_CONDITION);
- writeDimensionsValueProtoToStream(
- dimensionKey.getDimensionKeyInCondition().getDimensionsValue(), protoOutput);
+ writeDimensionToProto(dimensionKey.getDimensionKeyInCondition(), protoOutput);
protoOutput->end(dimensionInConditionToken);
}
@@ -169,7 +170,7 @@
long long atomsToken =
protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_ATOM);
for (const auto& atom : bucket.mGaugeAtoms) {
- writeFieldValueTreeToStream(*atom.mFields, protoOutput);
+ writeFieldValueTreeToStream(mTagId, *(atom.mFields), protoOutput);
}
protoOutput->end(atomsToken);
@@ -246,13 +247,14 @@
VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
}
-std::shared_ptr<FieldValueMap> GaugeMetricProducer::getGaugeFields(const LogEvent& event) {
- std::shared_ptr<FieldValueMap> gaugeFields =
- std::make_shared<FieldValueMap>(event.getFieldValueMap());
- if (!mFieldFilter.include_all()) {
- filterFields(mFieldFilter.fields(), gaugeFields.get());
+std::shared_ptr<vector<FieldValue>> GaugeMetricProducer::getGaugeFields(const LogEvent& event) {
+ if (mFieldMatchers.size() > 0) {
+ std::shared_ptr<vector<FieldValue>> gaugeFields = std::make_shared<vector<FieldValue>>();
+ filterGaugeValues(mFieldMatchers, event.getValues(), gaugeFields.get());
+ return gaugeFields;
+ } else {
+ return std::make_shared<vector<FieldValue>>(event.getValues());
}
- return gaugeFields;
}
void GaugeMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& allData) {
@@ -292,6 +294,7 @@
return;
}
uint64_t eventTimeNs = event.GetTimestampNs();
+ mTagId = event.GetTagId();
if (eventTimeNs < mCurrentBucketStartTimeNs) {
VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
(long long)mCurrentBucketStartTimeNs);
@@ -308,20 +311,18 @@
if (hitGuardRailLocked(eventKey)) {
return;
}
- GaugeAtom gaugeAtom;
- gaugeAtom.mFields = getGaugeFields(event);
- gaugeAtom.mTimestamps = eventTimeNs;
+ GaugeAtom gaugeAtom(getGaugeFields(event), eventTimeNs);
(*mCurrentSlicedBucket)[eventKey].push_back(gaugeAtom);
// Anomaly detection on gauge metric only works when there is one numeric
// field specified.
if (mAnomalyTrackers.size() > 0) {
if (gaugeAtom.mFields->size() == 1) {
- const DimensionsValue& dimensionsValue = gaugeAtom.mFields->begin()->second;
+ const Value& value = gaugeAtom.mFields->begin()->mValue;
long gaugeVal = 0;
- if (dimensionsValue.has_value_int()) {
- gaugeVal = (long)dimensionsValue.value_int();
- } else if (dimensionsValue.has_value_long()) {
- gaugeVal = dimensionsValue.value_long();
+ if (value.getType() == INT) {
+ gaugeVal = (long)value.int_value;
+ } else if (value.getType() == LONG) {
+ gaugeVal = value.long_value;
}
for (auto& tracker : mAnomalyTrackers) {
tracker->detectAndDeclareAnomaly(eventTimeNs, mCurrentBucketNum, eventKey,
@@ -334,15 +335,15 @@
void GaugeMetricProducer::updateCurrentSlicedBucketForAnomaly() {
status_t err = NO_ERROR;
for (const auto& slice : *mCurrentSlicedBucket) {
- if (slice.second.empty() || slice.second.front().mFields->empty()) {
+ if (slice.second.empty()) {
continue;
}
- const DimensionsValue& dimensionsValue = slice.second.front().mFields->begin()->second;
+ const Value& value = slice.second.front().mFields->front().mValue;
long gaugeVal = 0;
- if (dimensionsValue.has_value_int()) {
- gaugeVal = (long)dimensionsValue.value_int();
- } else if (dimensionsValue.has_value_long()) {
- gaugeVal = dimensionsValue.value_long();
+ if (value.getType() == INT) {
+ gaugeVal = (long)value.int_value;
+ } else if (value.getType() == LONG) {
+ gaugeVal = value.long_value;
}
(*mCurrentSlicedBucketForAnomaly)[slice.first] = gaugeVal;
}
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index d5d34be..c3ae6ce 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -33,7 +33,10 @@
namespace statsd {
struct GaugeAtom {
- std::shared_ptr<FieldValueMap> mFields;
+ GaugeAtom(std::shared_ptr<vector<FieldValue>> fields, int64_t timeNs)
+ : mFields(fields), mTimestamps(timeNs) {
+ }
+ std::shared_ptr<vector<FieldValue>> mFields;
int64_t mTimestamps;
};
@@ -87,7 +90,6 @@
private:
void onDumpReportLocked(const uint64_t dumpTimeNs,
android::util::ProtoOutputStream* protoOutput) override;
- void onDumpReportLocked(const uint64_t dumpTimeNs, StatsLogReport* report) override;
// for testing
GaugeMetricProducer(const ConfigKey& key, const GaugeMetric& gaugeMetric,
@@ -113,6 +115,8 @@
void pullLocked();
+ int mTagId;
+
std::shared_ptr<StatsPullerManager> mStatsPullerManager;
// tagId for pulled data. -1 if this is not pulled
const int mPullTagId;
@@ -133,12 +137,12 @@
void updateCurrentSlicedBucketForAnomaly();
// Whitelist of fields to report. Empty means all are reported.
- FieldFilter mFieldFilter;
+ std::vector<Matcher> mFieldMatchers;
GaugeMetric::SamplingType mSamplingType;
// apply a whitelist on the original input
- std::shared_ptr<FieldValueMap> getGaugeFields(const LogEvent& event);
+ std::shared_ptr<vector<FieldValue>> getGaugeFields(const LogEvent& event);
// Util function to check whether the specified dimension hits the guardrail.
bool hitGuardRailLocked(const MetricDimensionKey& newKey);
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
index 85e655b..beb9015 100644
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ b/cmds/statsd/src/metrics/MetricProducer.cpp
@@ -13,9 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "MetricProducer.h"
-#include "dimension.h"
+#define DEBUG true // STOPSHIP if true
+#include "Log.h"
+#include "MetricProducer.h"
namespace android {
namespace os {
@@ -35,9 +36,10 @@
std::unordered_set<HashableDimensionKey> dimensionKeysInCondition;
if (mConditionSliced) {
- for (const auto& link : mConditionLinks) {
- getDimensionKeysForCondition(event, link, &conditionKey[link.condition()]);
+ for (const auto& link : mMetric2ConditionLinks) {
+ getDimensionForCondition(event, link, &conditionKey[link.conditionId]);
}
+
auto conditionState =
mWizard->query(mConditionTrackerIndex, conditionKey, mDimensionsInCondition,
&dimensionKeysInCondition);
@@ -46,20 +48,19 @@
condition = mCondition;
}
- vector<DimensionsValue> dimensionInWhatValues;
- if (mDimensionsInWhat.has_field() && mDimensionsInWhat.child_size() > 0) {
- getDimensionKeys(event, mDimensionsInWhat, &dimensionInWhatValues);
+ vector<HashableDimensionKey> dimensionInWhatValues;
+ if (mDimensionsInWhat.size() > 0) {
+ filterValues(mDimensionsInWhat, event.getValues(), &dimensionInWhatValues);
}
if (dimensionInWhatValues.empty() && dimensionKeysInCondition.empty()) {
onMatchedLogEventInternalLocked(
matcherIndex, DEFAULT_METRIC_DIMENSION_KEY, conditionKey, condition, event);
} else if (dimensionKeysInCondition.empty()) {
- for (const DimensionsValue& whatValue : dimensionInWhatValues) {
- onMatchedLogEventInternalLocked(
- matcherIndex,
- MetricDimensionKey(HashableDimensionKey(whatValue), DEFAULT_DIMENSION_KEY),
- conditionKey, condition, event);
+ for (const HashableDimensionKey& whatValue : dimensionInWhatValues) {
+ onMatchedLogEventInternalLocked(matcherIndex,
+ MetricDimensionKey(whatValue, DEFAULT_DIMENSION_KEY),
+ conditionKey, condition, event);
}
} else if (dimensionInWhatValues.empty()) {
for (const auto& conditionDimensionKey : dimensionKeysInCondition) {
@@ -69,12 +70,11 @@
conditionKey, condition, event);
}
} else {
- for (const DimensionsValue& whatValue : dimensionInWhatValues) {
+ for (const auto& whatValue : dimensionInWhatValues) {
for (const auto& conditionDimensionKey : dimensionKeysInCondition) {
onMatchedLogEventInternalLocked(
- matcherIndex,
- MetricDimensionKey(HashableDimensionKey(whatValue), conditionDimensionKey),
- conditionKey, condition, event);
+ matcherIndex, MetricDimensionKey(whatValue, conditionDimensionKey),
+ conditionKey, condition, event);
}
}
}
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 542dd8a..e8f8299 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -19,6 +19,7 @@
#include <shared_mutex>
+#include "HashableDimensionKey.h"
#include "anomaly/AnomalyTracker.h"
#include "condition/ConditionWizard.h"
#include "config/ConfigKey.h"
@@ -109,11 +110,6 @@
std::lock_guard<std::mutex> lock(mMutex);
return onDumpReportLocked(dumpTimeNs, protoOutput);
}
- // This method does not clear the past buckets.
- void onDumpReport(const uint64_t dumpTimeNs, StatsLogReport* report) {
- std::lock_guard<std::mutex> lock(mMutex);
- return onDumpReportLocked(dumpTimeNs, report);
- }
void dumpStates(FILE* out, bool verbose) const {
std::lock_guard<std::mutex> lock(mMutex);
@@ -150,7 +146,6 @@
virtual void onSlicedConditionMayChangeLocked(const uint64_t eventTime) = 0;
virtual void onDumpReportLocked(const uint64_t dumpTimeNs,
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;
@@ -203,10 +198,10 @@
int mConditionTrackerIndex;
- FieldMatcher mDimensionsInWhat; // The dimensions_in_what defined in statsd_config
- FieldMatcher mDimensionsInCondition; // The dimensions_in_condition defined in statsd_config
+ vector<Matcher> mDimensionsInWhat; // The dimensions_in_what defined in statsd_config
+ vector<Matcher> mDimensionsInCondition; // The dimensions_in_condition defined in statsd_config
- std::vector<MetricConditionLink> mConditionLinks;
+ std::vector<Metric2Condition> mMetric2ConditionLinks;
std::vector<sp<AnomalyTracker>> mAnomalyTrackers;
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 6c21b05..dd6735b 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#define DEBUG false // STOPSHIP if true
+#define DEBUG true // STOPSHIP if true
#include "Log.h"
#include "MetricsManager.h"
#include "statslog.h"
@@ -151,14 +151,6 @@
initLogSourceWhiteList();
}
-void MetricsManager::onDumpReport(const uint64_t& dumpTimeStampNs, ConfigMetricsReport* report) {
- for (const auto& producer : mAllMetricProducers) {
- if (mNoReportMetricIds.find(producer->getMetricId()) == mNoReportMetricIds.end()) {
- producer->onDumpReport(dumpTimeStampNs, report->add_metrics());
- }
- }
-}
-
void MetricsManager::dumpStates(FILE* out, bool verbose) {
fprintf(out, "ConfigKey %s, allowed source:", mConfigKey.ToString().c_str());
{
@@ -173,9 +165,8 @@
}
}
-void MetricsManager::onDumpReport(ProtoOutputStream* protoOutput) {
+void MetricsManager::onDumpReport(const uint64_t dumpTimeStampNs, ProtoOutputStream* protoOutput) {
VLOG("=========================Metric Reports Start==========================");
- uint64_t dumpTimeStampNs = time(nullptr) * NS_PER_SEC;
// one StatsLogReport per MetricProduer
for (const auto& producer : mAllMetricProducers) {
if (mNoReportMetricIds.find(producer->getMetricId()) == mNoReportMetricIds.end()) {
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index 2b30f44..d4f844f 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -70,8 +70,8 @@
};
// 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);
+ virtual void onDumpReport(const uint64_t dumpTimeNs,
+ android::util::ProtoOutputStream* protoOutput);
// Computes the total byte size of all metrics managed by a single config source.
// Does not change the state.
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 7b1944c..45b4ac0 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -17,7 +17,6 @@
#define DEBUG false // STOPSHIP if true
#include "Log.h"
-#include "dimension.h"
#include "ValueMetricProducer.h"
#include "guardrail/StatsdStats.h"
#include "stats_log_util.h"
@@ -79,15 +78,28 @@
}
mBucketSizeNs = bucketSizeMills * 1000000;
- mDimensionsInWhat = metric.dimensions_in_what();
- mDimensionsInCondition = metric.dimensions_in_condition();
+ if (metric.has_dimensions_in_what()) {
+ translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
+ }
+
+ if (metric.has_dimensions_in_condition()) {
+ translateFieldMatcher(metric.dimensions_in_condition(), &mDimensionsInCondition);
+ }
if (metric.links().size() > 0) {
- mConditionLinks.insert(mConditionLinks.begin(), metric.links().begin(),
- metric.links().end());
+ for (const auto& link : metric.links()) {
+ Metric2Condition mc;
+ mc.conditionId = link.condition();
+ translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
+ translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
+ mMetric2ConditionLinks.push_back(mc);
+ }
}
- mConditionSliced = (metric.links().size() > 0)||
- (mDimensionsInCondition.has_field() && mDimensionsInCondition.child_size() > 0);
+
+ if (mValueField.child_size()) {
+ mField = mValueField.child(0).field();
+ }
+ mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0);
if (!metric.has_condition() && mPullTagId != -1) {
VLOG("Setting up periodic pulling for %d", mPullTagId);
@@ -117,25 +129,6 @@
VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
}
-void ValueMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs, StatsLogReport* report) {
- flushIfNeededLocked(dumpTimeNs);
- report->set_metric_id(mMetricId);
- auto value_metrics = report->mutable_value_metrics();
- for (const auto& pair : mPastBuckets) {
- ValueMetricData* metricData = value_metrics->add_data();
- *metricData->mutable_dimensions_in_what() =
- pair.first.getDimensionKeyInWhat().getDimensionsValue();
- *metricData->mutable_dimensions_in_condition() =
- pair.first.getDimensionKeyInCondition().getDimensionsValue();
- for (const auto& bucket : pair.second) {
- ValueBucketInfo* bucketInfo = metricData->add_bucket_info();
- bucketInfo->set_start_bucket_nanos(bucket.mBucketStartNs);
- bucketInfo->set_end_bucket_nanos(bucket.mBucketEndNs);
- bucketInfo->set_value(bucket.mValue);
- }
- }
-}
-
void ValueMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
ProtoOutputStream* protoOutput) {
VLOG("metric %lld dump report now...", (long long)mMetricId);
@@ -155,14 +148,12 @@
// First fill dimension.
long long dimensionToken = protoOutput->start(
FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
- writeDimensionsValueProtoToStream(
- dimensionKey.getDimensionKeyInWhat().getDimensionsValue(), protoOutput);
+ writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), protoOutput);
protoOutput->end(dimensionToken);
if (dimensionKey.hasDimensionKeyInCondition()) {
long long dimensionInConditionToken = protoOutput->start(
FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_CONDITION);
- writeDimensionsValueProtoToStream(
- dimensionKey.getDimensionKeyInCondition().getDimensionsValue(), protoOutput);
+ writeDimensionToProto(dimensionKey.getDimensionKeyInCondition(), protoOutput);
protoOutput->end(dimensionInConditionToken);
}
@@ -284,11 +275,11 @@
}
Interval& interval = mCurrentSlicedBucket[eventKey];
- std::shared_ptr<FieldValueMap> valueFieldMap = getValueFields(event);
- if (valueFieldMap->empty() || valueFieldMap->size() > 1) {
+ int error = 0;
+ const long value = event.GetLong(mField, &error);
+ if (error < 0) {
return;
}
- const long value = getLongFromDimenValue(valueFieldMap->begin()->second);
if (mPullTagId != -1) { // for pulled events
if (mCondition == true) {
@@ -324,13 +315,6 @@
}
}
-std::shared_ptr<FieldValueMap> ValueMetricProducer::getValueFields(const LogEvent& event) {
- std::shared_ptr<FieldValueMap> valueFields =
- std::make_shared<FieldValueMap>(event.getFieldValueMap());
- filterFields(mValueField, valueFields.get());
- return valueFields;
-}
-
void ValueMetricProducer::flushIfNeededLocked(const uint64_t& eventTimeNs) {
uint64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index bf5b7df..6701a46 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -89,7 +89,6 @@
private:
void onDumpReportLocked(const uint64_t dumpTimeNs,
android::util::ProtoOutputStream* protoOutput) override;
- void onDumpReportLocked(const uint64_t dumpTimeNs, StatsLogReport* report) override;
// Internal interface to handle condition change.
void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
@@ -120,6 +119,8 @@
// tagId for pulled data. -1 if this is not pulled
const int mPullTagId;
+ int mField;
+
// internal state of a bucket.
typedef struct {
// Pulled data always come in pair of <start, end>. This holds the value
@@ -142,8 +143,6 @@
// TODO: Add a lock to mPastBuckets.
std::unordered_map<MetricDimensionKey, std::vector<ValueBucket>> mPastBuckets;
- std::shared_ptr<FieldValueMap> getValueFields(const LogEvent& event);
-
// Util function to check whether the specified dimension hits the guardrail.
bool hitGuardRailLocked(const MetricDimensionKey& newKey);
diff --git a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
index 356a81c..8f236fa 100644
--- a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
@@ -62,7 +62,7 @@
public:
DurationTracker(const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
sp<ConditionWizard> wizard, int conditionIndex,
- const FieldMatcher& dimensionInCondition, bool nesting,
+ const std::vector<Matcher>& dimensionInCondition, bool nesting,
uint64_t currentBucketStartNs, uint64_t currentBucketNum, uint64_t startTimeNs,
uint64_t bucketSizeNs, bool conditionSliced,
const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers)
@@ -182,7 +182,7 @@
const int64_t mBucketSizeNs;
- const FieldMatcher mDimensionInCondition;
+ const std::vector<Matcher>& mDimensionInCondition;
const bool mNested;
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
index c3bafc6..c29876b 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
@@ -27,7 +27,7 @@
MaxDurationTracker::MaxDurationTracker(const ConfigKey& key, const int64_t& id,
const MetricDimensionKey& eventKey,
sp<ConditionWizard> wizard, int conditionIndex,
- const FieldMatcher& dimensionInCondition, bool nesting,
+ const vector<Matcher>& dimensionInCondition, bool nesting,
uint64_t currentBucketStartNs, uint64_t currentBucketNum,
uint64_t startTimeNs, uint64_t bucketSizeNs,
bool conditionSliced,
@@ -55,9 +55,7 @@
// 1. Report the tuple count if the tuple count > soft limit
if (mInfos.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
size_t newTupleCount = mInfos.size() + 1;
- StatsdStats::getInstance().noteMetricDimensionSize(
- mConfigKey, hashMetricDimensionKey(mTrackerId, mEventKey),
- newTupleCount);
+ StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mTrackerId, newTupleCount);
// 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
ALOGE("MaxDurTracker %lld dropping data for dimension key %s",
@@ -229,10 +227,11 @@
ConditionState conditionState = mWizard->query(
mConditionTrackerIndex, pair.second.conditionKeys, mDimensionInCondition,
&conditionDimensionKeySet);
- bool conditionMet = (conditionState == ConditionState::kTrue) &&
- (!mDimensionInCondition.has_field() ||
- conditionDimensionKeySet.find(mEventKey.getDimensionKeyInCondition()) !=
- conditionDimensionKeySet.end());
+ bool conditionMet =
+ (conditionState == ConditionState::kTrue) &&
+ (mDimensionInCondition.size() == 0 ||
+ conditionDimensionKeySet.find(mEventKey.getDimensionKeyInCondition()) !=
+ conditionDimensionKeySet.end());
VLOG("key: %s, condition: %d", pair.first.c_str(), conditionMet);
noteConditionChanged(pair.first, conditionMet, timestamp);
}
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
index fba4119..95863b6 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
@@ -30,7 +30,7 @@
public:
MaxDurationTracker(const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
sp<ConditionWizard> wizard, int conditionIndex,
- const FieldMatcher& dimensionInCondition, bool nesting,
+ const std::vector<Matcher>& dimensionInCondition, bool nesting,
uint64_t currentBucketStartNs, uint64_t currentBucketNum,
uint64_t startTimeNs, uint64_t bucketSizeNs, bool conditionSliced,
const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers);
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
index 85f7b7c..f583f91 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
@@ -26,7 +26,7 @@
OringDurationTracker::OringDurationTracker(
const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
- sp<ConditionWizard> wizard, int conditionIndex, const FieldMatcher& dimensionInCondition,
+ sp<ConditionWizard> wizard, int conditionIndex, const vector<Matcher>& dimensionInCondition,
bool nesting, uint64_t currentBucketStartNs, uint64_t currentBucketNum,
uint64_t startTimeNs, uint64_t bucketSizeNs, bool conditionSliced,
const vector<sp<DurationAnomalyTracker>>& anomalyTrackers)
@@ -53,9 +53,7 @@
}
if (mConditionKeyMap.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
size_t newTupleCount = mConditionKeyMap.size() + 1;
- StatsdStats::getInstance().noteMetricDimensionSize(
- mConfigKey, hashMetricDimensionKey(mTrackerId, mEventKey),
- newTupleCount);
+ StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mTrackerId, newTupleCount);
// 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
ALOGE("OringDurTracker %lld dropping data for dimension key %s",
@@ -229,9 +227,9 @@
mWizard->query(mConditionTrackerIndex, mConditionKeyMap[key],
mDimensionInCondition, &conditionDimensionKeySet);
if (conditionState != ConditionState::kTrue ||
- (mDimensionInCondition.has_field() &&
+ (mDimensionInCondition.size() != 0 &&
conditionDimensionKeySet.find(mEventKey.getDimensionKeyInCondition()) ==
- conditionDimensionKeySet.end())) {
+ conditionDimensionKeySet.end())) {
startedToPaused.push_back(*it);
it = mStarted.erase(it);
VLOG("Key %s started -> paused", key.c_str());
@@ -261,9 +259,9 @@
mWizard->query(mConditionTrackerIndex, mConditionKeyMap[key],
mDimensionInCondition, &conditionDimensionKeySet);
if (conditionState == ConditionState::kTrue &&
- (!mDimensionInCondition.has_field() ||
- conditionDimensionKeySet.find(mEventKey.getDimensionKeyInCondition())
- != conditionDimensionKeySet.end())) {
+ (mDimensionInCondition.size() == 0 ||
+ conditionDimensionKeySet.find(mEventKey.getDimensionKeyInCondition()) !=
+ conditionDimensionKeySet.end())) {
pausedToStarted.push_back(*it);
it = mPaused.erase(it);
VLOG("Key %s paused -> started", key.c_str());
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
index 73e50e0..07c1329 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
@@ -29,8 +29,8 @@
public:
OringDurationTracker(const ConfigKey& key, const int64_t& id,
const MetricDimensionKey& eventKey, sp<ConditionWizard> wizard,
- int conditionIndex, const FieldMatcher& dimensionInCondition, bool nesting,
- uint64_t currentBucketStartNs, uint64_t currentBucketNum,
+ int conditionIndex, const std::vector<Matcher>& dimensionInCondition,
+ bool nesting, uint64_t currentBucketStartNs, uint64_t currentBucketNum,
uint64_t startTimeNs, uint64_t bucketSizeNs, bool conditionSliced,
const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers);
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index 205c8e4..769f46d 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -38,6 +38,22 @@
namespace os {
namespace statsd {
+namespace {
+
+bool hasLeafNode(const FieldMatcher& matcher) {
+ if (!matcher.has_field()) {
+ return false;
+ }
+ for (int i = 0; i < matcher.child_size(); ++i) {
+ if (hasLeafNode(matcher.child(i))) {
+ return true;
+ }
+ }
+ return true;
+}
+
+} // namespace
+
bool handleMetricWithLogTrackers(const int64_t what, const int metricIndex,
const bool usedForDimension,
const vector<sp<LogMatchingTracker>>& allAtomMatchers,
diff --git a/cmds/statsd/src/packages/UidMap.cpp b/cmds/statsd/src/packages/UidMap.cpp
index 0d7b722..691423e 100644
--- a/cmds/statsd/src/packages/UidMap.cpp
+++ b/cmds/statsd/src/packages/UidMap.cpp
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#define DEBUG false // STOPSHIP if true
+#define DEBUG true // STOPSHIP if true
#include "Log.h"
#include "guardrail/StatsdStats.h"
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index 6c61400..86c258b 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -16,9 +16,10 @@
#include "stats_log_util.h"
+#include <logd/LogEvent.h>
+#include <utils/Log.h>
#include <set>
#include <stack>
-#include <utils/Log.h>
using android::util::FIELD_COUNT_REPEATED;
using android::util::FIELD_TYPE_BOOL;
@@ -42,6 +43,8 @@
const int DIMENSIONS_VALUE_VALUE_FLOAT = 6;
const int DIMENSIONS_VALUE_VALUE_TUPLE = 7;
+const int DIMENSIONS_VALUE_TUPLE_VALUE = 1;
+
// for MessageValue Proto
const int FIELD_ID_FIELD_VALUE_IN_MESSAGE_VALUE_PROTO = 1;
@@ -51,52 +54,79 @@
const int FIELD_ID_TOTAL_PULL = 2;
const int FIELD_ID_TOTAL_PULL_FROM_CACHE = 3;
const int FIELD_ID_MIN_PULL_INTERVAL_SEC = 4;
+namespace {
-void writeDimensionsValueProtoToStream(const DimensionsValue& dimensionsValue,
- ProtoOutputStream* protoOutput) {
- if (!dimensionsValue.has_field()) {
+void writeDimensionToProtoHelper(const std::vector<FieldValue>& dims, size_t* index, int depth,
+ int prefix, ProtoOutputStream* protoOutput) {
+ size_t count = dims.size();
+ while (*index < count) {
+ const auto& dim = dims[*index];
+ const int valueDepth = dim.mField.getDepth();
+ const int valuePrefix = dim.mField.getPrefix(depth);
+ const int fieldNum = dim.mField.getPosAtDepth(depth);
+ if (valueDepth > 2) {
+ ALOGE("Depth > 2 not supported");
+ return;
+ }
+
+ if (depth == valueDepth && valuePrefix == prefix) {
+ long long token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
+ DIMENSIONS_VALUE_TUPLE_VALUE);
+ protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD, fieldNum);
+ switch (dim.mValue.getType()) {
+ case INT:
+ protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_VALUE_INT,
+ dim.mValue.int_value);
+ break;
+ case LONG:
+ protoOutput->write(FIELD_TYPE_INT64 | DIMENSIONS_VALUE_VALUE_LONG,
+ (long long)dim.mValue.long_value);
+ break;
+ case FLOAT:
+ protoOutput->write(FIELD_TYPE_FLOAT | DIMENSIONS_VALUE_VALUE_FLOAT,
+ dim.mValue.float_value);
+ break;
+ case STRING:
+ protoOutput->write(FIELD_TYPE_STRING | DIMENSIONS_VALUE_VALUE_STR,
+ dim.mValue.str_value);
+ break;
+ default:
+ break;
+ }
+ if (token != 0) {
+ protoOutput->end(token);
+ }
+ (*index)++;
+ } else if (valueDepth > depth && valuePrefix == prefix) {
+ // Writing the sub tree
+ long long dimensionToken = protoOutput->start(
+ FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | DIMENSIONS_VALUE_TUPLE_VALUE);
+ protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD, fieldNum);
+ long long tupleToken =
+ protoOutput->start(FIELD_TYPE_MESSAGE | DIMENSIONS_VALUE_VALUE_TUPLE);
+ writeDimensionToProtoHelper(dims, index, valueDepth, dim.mField.getPrefix(valueDepth),
+ protoOutput);
+ protoOutput->end(tupleToken);
+ protoOutput->end(dimensionToken);
+ } else {
+ // Done with the prev sub tree
+ return;
+ }
+ }
+}
+
+} // namespace
+
+void writeDimensionToProto(const HashableDimensionKey& dimension, ProtoOutputStream* protoOutput) {
+ if (dimension.getValues().size() == 0) {
return;
}
- protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD, dimensionsValue.field());
- switch (dimensionsValue.value_case()) {
- case DimensionsValue::ValueCase::kValueStr:
- protoOutput->write(FIELD_TYPE_STRING | DIMENSIONS_VALUE_VALUE_STR,
- dimensionsValue.value_str());
- break;
- case DimensionsValue::ValueCase::kValueInt:
- protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_VALUE_INT,
- dimensionsValue.value_int());
- break;
- case DimensionsValue::ValueCase::kValueLong:
- protoOutput->write(FIELD_TYPE_INT64 | DIMENSIONS_VALUE_VALUE_LONG,
- dimensionsValue.value_long());
- break;
- case DimensionsValue::ValueCase::kValueBool:
- protoOutput->write(FIELD_TYPE_BOOL | DIMENSIONS_VALUE_VALUE_BOOL,
- dimensionsValue.value_bool());
- break;
- case DimensionsValue::ValueCase::kValueFloat:
- protoOutput->write(FIELD_TYPE_FLOAT | DIMENSIONS_VALUE_VALUE_FLOAT,
- dimensionsValue.value_float());
- break;
- case DimensionsValue::ValueCase::kValueTuple:
- {
- long long tupleToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | DIMENSIONS_VALUE_VALUE_TUPLE);
- for (int i = 0; i < dimensionsValue.value_tuple().dimensions_value_size(); ++i) {
- long long token = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED
- | FIELD_ID_FIELD_VALUE_IN_MESSAGE_VALUE_PROTO);
- writeDimensionsValueProtoToStream(
- dimensionsValue.value_tuple().dimensions_value(i), protoOutput);
- protoOutput->end(token);
- }
- protoOutput->end(tupleToken);
- }
- break;
- default:
- break;
- }
+ protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD,
+ dimension.getValues()[0].mField.getTag());
+ long long topToken = protoOutput->start(FIELD_TYPE_MESSAGE | DIMENSIONS_VALUE_VALUE_TUPLE);
+ size_t index = 0;
+ writeDimensionToProtoHelper(dimension.getValues(), &index, 0, 0, protoOutput);
+ protoOutput->end(topToken);
}
// for Field Proto
@@ -104,133 +134,92 @@
const int FIELD_POSITION_INDEX = 2;
const int FIELD_CHILD = 3;
-void writeFieldProtoToStream(
- const Field& field, util::ProtoOutputStream* protoOutput) {
- if (!field.has_field()) {
- return;
- }
- protoOutput->write(FIELD_TYPE_INT32 | FIELD_FIELD, field.field());
- if (field.has_position_index()) {
- protoOutput->write(FIELD_TYPE_INT32 | FIELD_POSITION_INDEX, field.position_index());
- }
- for (int i = 0; i < field.child_size(); ++i) {
- long long childToken = protoOutput->start(
- FIELD_TYPE_MESSAGE| FIELD_COUNT_REPEATED | FIELD_CHILD);
- writeFieldProtoToStream(field.child(i), protoOutput);
- protoOutput->end(childToken);
- }
-}
-
-namespace {
-
-void addOrUpdateChildrenMap(
- const Field& root,
- const Field& node,
- std::map<Field, std::set<Field, FieldCmp>, FieldCmp> *childrenMap) {
- Field parentNode = root;
- if (node.has_position_index()) {
- appendLeaf(&parentNode, node.field(), node.position_index());
- } else {
- appendLeaf(&parentNode, node.field());
- }
- if (childrenMap->find(parentNode) == childrenMap->end()) {
- childrenMap->insert(std::make_pair(parentNode, std::set<Field, FieldCmp>{}));
- }
- auto it = childrenMap->find(parentNode);
- for (int i = 0; i < node.child_size(); ++i) {
- auto child = node.child(i);
- Field childNode = parentNode;
- if (child.has_position_index()) {
- appendLeaf(&childNode, child.field(), child.position_index());
- } else {
- appendLeaf(&childNode, child.field());
+// Supported Atoms format
+// XYZ_Atom {
+// repeated SubMsg field_1 = 1;
+// SubMsg2 field_2 = 2;
+// int32/float/string/int63 field_3 = 3;
+// }
+// logd's msg format, doesn't allow us to distinguish between the 2 cases below
+// Case (1):
+// Atom {
+// SubMsg {
+// int i = 1;
+// int j = 2;
+// }
+// repeated SubMsg
+// }
+//
+// and case (2):
+// Atom {
+// SubMsg {
+// repeated int i = 1;
+// repeated int j = 2;
+// }
+// optional SubMsg = 1;
+// }
+//
+//
+void writeFieldValueTreeToStreamHelper(const std::vector<FieldValue>& dims, size_t* index,
+ int depth, int prefix, ProtoOutputStream* protoOutput) {
+ size_t count = dims.size();
+ while (*index < count) {
+ const auto& dim = dims[*index];
+ const int valueDepth = dim.mField.getDepth();
+ const int valuePrefix = dim.mField.getPrefix(depth);
+ const int fieldNum = dim.mField.getPosAtDepth(depth);
+ if (valueDepth > 2) {
+ ALOGE("Depth > 2 not supported");
+ return;
}
- it->second.insert(childNode);
- addOrUpdateChildrenMap(parentNode, child, childrenMap);
+
+ if (depth == valueDepth && valuePrefix == prefix) {
+ switch (dim.mValue.getType()) {
+ case INT:
+ protoOutput->write(FIELD_TYPE_INT32 | fieldNum, dim.mValue.int_value);
+ break;
+ case LONG:
+ protoOutput->write(FIELD_TYPE_INT64 | fieldNum,
+ (long long)dim.mValue.long_value);
+ break;
+ case FLOAT:
+ protoOutput->write(FIELD_TYPE_FLOAT | fieldNum, dim.mValue.float_value);
+ break;
+ case STRING:
+ protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value);
+ break;
+ }
+ (*index)++;
+ } else if (valueDepth > depth && valuePrefix == prefix) {
+ // Writing the sub tree
+ long long msg_token = 0;
+ if (valueDepth == depth + 2) {
+ msg_token =
+ protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | fieldNum);
+ } else if (valueDepth == depth + 1) {
+ msg_token = protoOutput->start(FIELD_TYPE_MESSAGE | fieldNum);
+ }
+ // Directly jump to the leaf value because the repeated position field is implied
+ // by the position of the sub msg in the parent field.
+ writeFieldValueTreeToStreamHelper(dims, index, valueDepth,
+ dim.mField.getPrefix(valueDepth), protoOutput);
+ if (msg_token != 0) {
+ protoOutput->end(msg_token);
+ }
+ } else {
+ // Done with the prev sub tree
+ return;
+ }
}
}
-void addOrUpdateChildrenMap(
- const Field& field,
- std::map<Field, std::set<Field, FieldCmp>, FieldCmp> *childrenMap) {
- Field root;
- addOrUpdateChildrenMap(root, field, childrenMap);
-}
-
-} // namespace
-
-void writeFieldValueTreeToStream(const FieldValueMap &fieldValueMap,
+void writeFieldValueTreeToStream(int tagId, const std::vector<FieldValue>& values,
util::ProtoOutputStream* protoOutput) {
- std::map<Field, std::set<Field, FieldCmp>, FieldCmp> childrenMap;
- // Rebuild the field tree.
- for (auto it = fieldValueMap.begin(); it != fieldValueMap.end(); ++it) {
- addOrUpdateChildrenMap(it->first, &childrenMap);
- }
- std::stack<std::pair<long long, Field>> tokenStack;
- // Iterate over the node tree to fill the Atom proto.
- for (auto it = childrenMap.begin(); it != childrenMap.end(); ++it) {
- const Field* nodeLeaf = getSingleLeaf(&it->first);
- const int fieldNum = nodeLeaf->field();
- while (!tokenStack.empty()) {
- auto currentMsgNode = tokenStack.top().second;
- auto currentMsgNodeChildrenIt = childrenMap.find(currentMsgNode);
- if (currentMsgNodeChildrenIt->second.find(it->first) ==
- currentMsgNodeChildrenIt->second.end()) {
- protoOutput->end(tokenStack.top().first);
- tokenStack.pop();
- } else {
- break;
- }
- }
- if (it->second.size() == 0) {
- auto itValue = fieldValueMap.find(it->first);
- if (itValue != fieldValueMap.end()) {
- const DimensionsValue& value = itValue->second;
- switch (value.value_case()) {
- case DimensionsValue::ValueCase::kValueStr:
- protoOutput->write(FIELD_TYPE_STRING | fieldNum,
- value.value_str());
- break;
- case DimensionsValue::ValueCase::kValueInt:
- protoOutput->write(FIELD_TYPE_INT32 | fieldNum,
- value.value_int());
- break;
- case DimensionsValue::ValueCase::kValueLong:
- protoOutput->write(FIELD_TYPE_INT64 | fieldNum,
- value.value_long());
- break;
- case DimensionsValue::ValueCase::kValueBool:
- protoOutput->write(FIELD_TYPE_BOOL | fieldNum,
- value.value_bool());
- break;
- case DimensionsValue::ValueCase::kValueFloat:
- protoOutput->write(FIELD_TYPE_FLOAT | fieldNum,
- value.value_float());
- break;
- // This would not happen as the node has no child.
- case DimensionsValue::ValueCase::kValueTuple:
- break;
- default:
- break;
- }
- } else {
- ALOGE("Leaf node value not found. This should never happen.");
- }
- } else {
- long long token;
- if (nodeLeaf->has_position_index()) {
- token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | fieldNum);
- } else {
- token = protoOutput->start(FIELD_TYPE_MESSAGE | fieldNum);
- }
- tokenStack.push(std::make_pair(token, it->first));
- }
- }
+ long long atomToken = protoOutput->start(FIELD_TYPE_MESSAGE | tagId);
- while (!tokenStack.empty()) {
- protoOutput->end(tokenStack.top().first);
- tokenStack.pop();
- }
+ size_t index = 0;
+ writeFieldValueTreeToStreamHelper(values, &index, 0, 0, protoOutput);
+ protoOutput->end(atomToken);
}
int64_t TimeUnitToBucketSizeInMillis(TimeUnit unit) {
diff --git a/cmds/statsd/src/stats_log_util.h b/cmds/statsd/src/stats_log_util.h
index cee9200..6583f57 100644
--- a/cmds/statsd/src/stats_log_util.h
+++ b/cmds/statsd/src/stats_log_util.h
@@ -17,7 +17,8 @@
#pragma once
#include <android/util/ProtoOutputStream.h>
-#include "field_util.h"
+#include "FieldValue.h"
+#include "HashableDimensionKey.h"
#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
#include "guardrail/StatsdStats.h"
@@ -26,16 +27,10 @@
namespace os {
namespace statsd {
-// Helper function to write DimensionsValue proto to ProtoOutputStream.
-void writeDimensionsValueProtoToStream(const DimensionsValue& fieldValue,
- util::ProtoOutputStream* protoOutput);
-
-// Helper function to write Field proto to ProtoOutputStream.
-void writeFieldProtoToStream(const Field& field, util::ProtoOutputStream* protoOutput);
-
-// Helper function to construct the field value tree and write to ProtoOutputStream
-void writeFieldValueTreeToStream(const FieldValueMap& fieldValueMap,
+void writeFieldValueTreeToStream(int tagId, const std::vector<FieldValue>& values,
util::ProtoOutputStream* protoOutput);
+void writeDimensionToProto(const HashableDimensionKey& dimension,
+ util::ProtoOutputStream* protoOutput);
// Convert the TimeUnit enum to the bucket size in millis.
int64_t TimeUnitToBucketSizeInMillis(TimeUnit unit);
diff --git a/cmds/statsd/src/statsd_internal.proto b/cmds/statsd/src/statsd_internal.proto
deleted file mode 100644
index 25aacee..0000000
--- a/cmds/statsd/src/statsd_internal.proto
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-syntax = "proto2";
-option optimize_for = LITE_RUNTIME;
-
-package android.os.statsd;
-
-option java_package = "com.android.os";
-option java_outer_classname = "StatsdInternalProto";
-
-message Field {
- optional int32 field = 1;
- optional int32 position_index = 2 [default = -1];
- repeated Field child = 3;
-}
diff --git a/cmds/statsd/src/subscriber/SubscriberReporter.cpp b/cmds/statsd/src/subscriber/SubscriberReporter.cpp
index 3af684f..9f68fc4 100644
--- a/cmds/statsd/src/subscriber/SubscriberReporter.cpp
+++ b/cmds/statsd/src/subscriber/SubscriberReporter.cpp
@@ -98,50 +98,66 @@
ALOGW("Failed to send subscriber broadcast: could not access StatsCompanionService.");
return;
}
- mStatsCompanionService->sendSubscriberBroadcast(intentSender,
- configKey.GetUid(),
- configKey.GetId(),
- subscription.id(),
- subscription.rule_id(),
- protoToStatsDimensionsValue(dimKey));
+ mStatsCompanionService->sendSubscriberBroadcast(
+ intentSender, configKey.GetUid(), configKey.GetId(), subscription.id(),
+ subscription.rule_id(), getStatsDimensionsValue(dimKey.getDimensionKeyInWhat()));
}
-StatsDimensionsValue SubscriberReporter::protoToStatsDimensionsValue(
- const MetricDimensionKey& dimKey) {
- return protoToStatsDimensionsValue(dimKey.getDimensionKeyInWhat().getDimensionsValue());
-}
-
-StatsDimensionsValue SubscriberReporter::protoToStatsDimensionsValue(
- const DimensionsValue& protoDimsVal) {
- int32_t field = protoDimsVal.field();
-
- switch (protoDimsVal.value_case()) {
- case DimensionsValue::ValueCase::kValueStr:
- return StatsDimensionsValue(field, String16(protoDimsVal.value_str().c_str()));
- case DimensionsValue::ValueCase::kValueInt:
- return StatsDimensionsValue(field, static_cast<int32_t>(protoDimsVal.value_int()));
- case DimensionsValue::ValueCase::kValueLong:
- return StatsDimensionsValue(field, static_cast<int64_t>(protoDimsVal.value_long()));
- case DimensionsValue::ValueCase::kValueBool:
- return StatsDimensionsValue(field, static_cast<bool>(protoDimsVal.value_bool()));
- case DimensionsValue::ValueCase::kValueFloat:
- return StatsDimensionsValue(field, static_cast<float>(protoDimsVal.value_float()));
- case DimensionsValue::ValueCase::kValueTuple:
- {
- int sz = protoDimsVal.value_tuple().dimensions_value_size();
- std::vector<StatsDimensionsValue> sdvVec(sz);
- for (int i = 0; i < sz; i++) {
- sdvVec[i] = protoToStatsDimensionsValue(
- protoDimsVal.value_tuple().dimensions_value(i));
- }
- return StatsDimensionsValue(field, sdvVec);
+void getStatsDimensionsValueHelper(const std::vector<FieldValue>& dims, size_t* index, int depth,
+ int prefix, vector<StatsDimensionsValue>* output) {
+ size_t count = dims.size();
+ while (*index < count) {
+ const auto& dim = dims[*index];
+ const int valueDepth = dim.mField.getDepth();
+ const int valuePrefix = dim.mField.getPrefix(depth);
+ if (valueDepth > 2) {
+ ALOGE("Depth > 2 not supported");
+ return;
+ }
+ if (depth == valueDepth && valuePrefix == prefix) {
+ switch (dim.mValue.getType()) {
+ case INT:
+ output->push_back(StatsDimensionsValue(dim.mField.getPosAtDepth(depth),
+ dim.mValue.int_value));
+ break;
+ case LONG:
+ output->push_back(StatsDimensionsValue(dim.mField.getPosAtDepth(depth),
+ dim.mValue.long_value));
+ break;
+ case FLOAT:
+ output->push_back(StatsDimensionsValue(dim.mField.getPosAtDepth(depth),
+ dim.mValue.float_value));
+ break;
+ case STRING:
+ output->push_back(StatsDimensionsValue(dim.mField.getPosAtDepth(depth),
+ String16(dim.mValue.str_value.c_str())));
+ break;
+ default:
+ break;
}
- default:
- ALOGW("protoToStatsDimensionsValue failed: illegal type.");
- return StatsDimensionsValue();
+ (*index)++;
+ } else if (valueDepth > depth && valuePrefix == prefix) {
+ vector<StatsDimensionsValue> childOutput;
+ getStatsDimensionsValueHelper(dims, index, depth + 1, dim.mField.getPrefix(depth + 1),
+ &childOutput);
+ output->push_back(StatsDimensionsValue(dim.mField.getPosAtDepth(depth), childOutput));
+ } else {
+ return;
+ }
}
}
+StatsDimensionsValue SubscriberReporter::getStatsDimensionsValue(const HashableDimensionKey& dim) {
+ if (dim.getValues().size() == 0) {
+ return StatsDimensionsValue();
+ }
+
+ vector<StatsDimensionsValue> fields;
+ size_t index = 0;
+ getStatsDimensionsValueHelper(dim.getValues(), &index, 0, 0, &fields);
+ return StatsDimensionsValue(dim.getValues()[0].mField.getTag(), fields);
+}
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/subscriber/SubscriberReporter.h b/cmds/statsd/src/subscriber/SubscriberReporter.h
index 13fc7fd..c7d1a5b 100644
--- a/cmds/statsd/src/subscriber/SubscriberReporter.h
+++ b/cmds/statsd/src/subscriber/SubscriberReporter.h
@@ -82,6 +82,8 @@
const Subscription& subscription,
const MetricDimensionKey& dimKey) const;
+ static StatsDimensionsValue getStatsDimensionsValue(const HashableDimensionKey& dim);
+
private:
SubscriberReporter() {};
@@ -102,14 +104,6 @@
const ConfigKey& configKey,
const Subscription& subscription,
const MetricDimensionKey& dimKey) const;
-
- /** Converts a stats_log.proto DimensionsValue to a StatsDimensionsValue. */
- static StatsDimensionsValue protoToStatsDimensionsValue(
- const DimensionsValue& protoDimsVal);
-
- /** Converts a HashableDimensionKey to a StatsDimensionsValue. */
- static StatsDimensionsValue protoToStatsDimensionsValue(
- const MetricDimensionKey& dimKey);
};
} // namespace statsd
diff --git a/cmds/statsd/tests/FieldValue_test.cpp b/cmds/statsd/tests/FieldValue_test.cpp
new file mode 100644
index 0000000..f1ad0c8
--- /dev/null
+++ b/cmds/statsd/tests/FieldValue_test.cpp
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <gtest/gtest.h>
+#include "src/logd/LogEvent.h"
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
+#include "matchers/matcher_util.h"
+#include "stats_log_util.h"
+#include "stats_util.h"
+#include "subscriber/SubscriberReporter.h"
+
+#ifdef __ANDROID__
+
+namespace android {
+namespace os {
+namespace statsd {
+
+TEST(AtomMatcherTest, TestFieldTranslation) {
+ FieldMatcher matcher1;
+ matcher1.set_field(10);
+ FieldMatcher* child = matcher1.add_child();
+ child->set_field(1);
+ child->set_position(Position::ANY);
+
+ child = child->add_child();
+ child->set_field(1);
+
+ vector<Matcher> output;
+ translateFieldMatcher(matcher1, &output);
+
+ EXPECT_EQ((size_t)1, output.size());
+
+ const auto& matcher12 = output[0];
+ EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag());
+ EXPECT_EQ((int32_t)0x2010001, matcher12.mMatcher.getField());
+ EXPECT_EQ((int32_t)0xff7f007f, matcher12.mMask);
+}
+
+TEST(AtomMatcherTest, TestFilter) {
+ FieldMatcher matcher1;
+ matcher1.set_field(10);
+ FieldMatcher* child = matcher1.add_child();
+ child->set_field(1);
+ child->set_position(Position::ANY);
+
+ child = child->add_child();
+ child->set_field(1);
+
+ child = matcher1.add_child();
+ child->set_field(2);
+
+ vector<Matcher> matchers;
+ translateFieldMatcher(matcher1, &matchers);
+
+ AttributionNode attribution_node1;
+ attribution_node1.set_uid(1111);
+ attribution_node1.set_tag("location1");
+
+ AttributionNode attribution_node2;
+ attribution_node2.set_uid(2222);
+ attribution_node2.set_tag("location2");
+
+ AttributionNode attribution_node3;
+ attribution_node3.set_uid(3333);
+ attribution_node3.set_tag("location3");
+ std::vector<AttributionNode> attribution_nodes = {attribution_node1, attribution_node2,
+ attribution_node3};
+
+ // Set up the event
+ LogEvent event(10, 12345);
+ event.write(attribution_nodes);
+ event.write("some value");
+ // Convert to a LogEvent
+ event.init();
+ vector<HashableDimensionKey> output;
+
+ filterValues(matchers, event.getValues(), &output);
+
+ EXPECT_EQ((size_t)(3), output.size());
+
+ const auto& key1 = output[0];
+ EXPECT_EQ((size_t)2, key1.getValues().size());
+ EXPECT_EQ((int32_t)0x02010001, key1.getValues()[0].mField.getField());
+ EXPECT_EQ((int32_t)1111, key1.getValues()[0].mValue.int_value);
+ EXPECT_EQ((int32_t)0x00020000, key1.getValues()[1].mField.getField());
+ EXPECT_EQ("some value", key1.getValues()[1].mValue.str_value);
+
+ const auto& key2 = output[1];
+ EXPECT_EQ((size_t)2, key2.getValues().size());
+ EXPECT_EQ((int32_t)0x02010001, key2.getValues()[0].mField.getField());
+ EXPECT_EQ((int32_t)2222, key2.getValues()[0].mValue.int_value);
+ EXPECT_EQ((int32_t)0x00020000, key2.getValues()[1].mField.getField());
+ EXPECT_EQ("some value", key2.getValues()[1].mValue.str_value);
+
+ const auto& key3 = output[2];
+ EXPECT_EQ((size_t)2, key3.getValues().size());
+ EXPECT_EQ((int32_t)0x02010001, key3.getValues()[0].mField.getField());
+ EXPECT_EQ((int32_t)3333, key3.getValues()[0].mValue.int_value);
+ EXPECT_EQ((int32_t)0x00020000, key3.getValues()[1].mField.getField());
+ EXPECT_EQ("some value", key3.getValues()[1].mValue.str_value);
+}
+
+TEST(AtomMatcherTest, TestSubDimension) {
+ HashableDimensionKey dim;
+
+ int pos1[] = {1, 1, 1};
+ int pos2[] = {1, 1, 2};
+ int pos3[] = {1, 1, 3};
+ int pos4[] = {2, 0, 0};
+ Field field1(10, pos1, 2);
+ Field field2(10, pos2, 2);
+
+ Field field3(10, pos3, 2);
+ Field field4(10, pos4, 0);
+
+ Value value1((int32_t)10025);
+ Value value2("tag");
+
+ Value value11((int32_t)10026);
+ Value value22("tag2");
+
+ dim.addValue(FieldValue(field1, value1));
+ dim.addValue(FieldValue(field2, value2));
+
+ HashableDimensionKey subDim1;
+ subDim1.addValue(FieldValue(field1, value1));
+
+ HashableDimensionKey subDim2;
+ subDim1.addValue(FieldValue(field2, value2));
+
+ EXPECT_TRUE(dim.contains(dim));
+ EXPECT_TRUE(dim.contains(subDim1));
+ EXPECT_TRUE(dim.contains(subDim2));
+
+ HashableDimensionKey subDim3;
+ subDim3.addValue(FieldValue(field1, value11));
+ EXPECT_FALSE(dim.contains(subDim3));
+
+ HashableDimensionKey subDim4;
+ // Empty dimension is always a sub dimension of other dimensions
+ EXPECT_TRUE(dim.contains(subDim4));
+}
+
+TEST(AtomMatcherTest, TestMetric2ConditionLink) {
+ AttributionNode attribution_node1;
+ attribution_node1.set_uid(1111);
+ attribution_node1.set_tag("location1");
+
+ AttributionNode attribution_node2;
+ attribution_node2.set_uid(2222);
+ attribution_node2.set_tag("location2");
+
+ AttributionNode attribution_node3;
+ attribution_node3.set_uid(3333);
+ attribution_node3.set_tag("location3");
+ std::vector<AttributionNode> attribution_nodes = {attribution_node1, attribution_node2,
+ attribution_node3};
+
+ // Set up the event
+ LogEvent event(10, 12345);
+ event.write(attribution_nodes);
+ event.write("some value");
+ // Convert to a LogEvent
+ event.init();
+
+ FieldMatcher whatMatcher;
+ whatMatcher.set_field(10);
+ FieldMatcher* child11 = whatMatcher.add_child();
+ child11->set_field(1);
+ child11->set_position(Position::ANY);
+ child11 = child11->add_child();
+ child11->set_field(1);
+
+ FieldMatcher conditionMatcher;
+ conditionMatcher.set_field(27);
+ FieldMatcher* child2 = conditionMatcher.add_child();
+ child2->set_field(2);
+ child2->set_position(Position::LAST);
+
+ child2 = child2->add_child();
+ child2->set_field(2);
+
+ Metric2Condition link;
+
+ translateFieldMatcher(whatMatcher, &link.metricFields);
+ translateFieldMatcher(conditionMatcher, &link.conditionFields);
+
+ EXPECT_EQ((size_t)1, link.metricFields.size());
+ EXPECT_EQ((int32_t)0x02010001, link.metricFields[0].mMatcher.getField());
+ EXPECT_EQ((int32_t)0xff7f007f, link.metricFields[0].mMask);
+ EXPECT_EQ((int32_t)10, link.metricFields[0].mMatcher.getTag());
+
+ EXPECT_EQ((size_t)1, link.conditionFields.size());
+ EXPECT_EQ((int32_t)0x02028002, link.conditionFields[0].mMatcher.getField());
+ EXPECT_EQ((int32_t)0xff7f807f, link.conditionFields[0].mMask);
+ EXPECT_EQ((int32_t)27, link.conditionFields[0].mMatcher.getTag());
+}
+
+TEST(AtomMatcherTest, TestSubscriberDimensionWrite) {
+ HashableDimensionKey dim;
+
+ int pos1[] = {1, 1, 1};
+ int pos2[] = {1, 1, 2};
+ int pos3[] = {1, 1, 3};
+ int pos4[] = {2, 0, 0};
+
+ Field field1(10, pos1, 2);
+ Field field2(10, pos2, 2);
+ Field field3(10, pos3, 2);
+ Field field4(10, pos4, 0);
+
+ Value value1((int32_t)10025);
+ Value value2("tag");
+ Value value3((int32_t)987654);
+ Value value4((int32_t)99999);
+
+ dim.addValue(FieldValue(field1, value1));
+ dim.addValue(FieldValue(field2, value2));
+ dim.addValue(FieldValue(field3, value3));
+ dim.addValue(FieldValue(field4, value4));
+
+ SubscriberReporter::getStatsDimensionsValue(dim);
+ // TODO: can't test anything here because SubscriberReport class doesn't have any read api.
+}
+
+TEST(AtomMatcherTest, TestWriteDimensionToProto) {
+ HashableDimensionKey dim;
+ int pos1[] = {1, 1, 1};
+ int pos2[] = {1, 1, 2};
+ int pos3[] = {1, 1, 3};
+ int pos4[] = {2, 0, 0};
+ Field field1(10, pos1, 2);
+ Field field2(10, pos2, 2);
+ Field field3(10, pos3, 2);
+ Field field4(10, pos4, 0);
+
+ Value value1((int32_t)10025);
+ Value value2("tag");
+ Value value3((int32_t)987654);
+ Value value4((int32_t)99999);
+
+ dim.addValue(FieldValue(field1, value1));
+ dim.addValue(FieldValue(field2, value2));
+ dim.addValue(FieldValue(field3, value3));
+ dim.addValue(FieldValue(field4, value4));
+
+ android::util::ProtoOutputStream protoOut;
+ writeDimensionToProto(dim, &protoOut);
+
+ vector<uint8_t> outData;
+ outData.resize(protoOut.size());
+ size_t pos = 0;
+ auto iter = protoOut.data();
+ while (iter.readBuffer() != NULL) {
+ size_t toRead = iter.currentToRead();
+ std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
+ pos += toRead;
+ iter.rp()->move(toRead);
+ }
+
+ DimensionsValue result;
+ EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
+ EXPECT_EQ(10, result.field());
+ EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
+ EXPECT_EQ(2, result.value_tuple().dimensions_value_size());
+
+ const auto& dim1 = result.value_tuple().dimensions_value(0);
+ EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, dim1.value_case());
+ EXPECT_EQ(3, dim1.value_tuple().dimensions_value_size());
+
+ const auto& dim11 = dim1.value_tuple().dimensions_value(0);
+ EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim11.value_case());
+ EXPECT_EQ(10025, dim11.value_int());
+
+ const auto& dim12 = dim1.value_tuple().dimensions_value(1);
+ EXPECT_EQ(DimensionsValue::ValueCase::kValueStr, dim12.value_case());
+ EXPECT_EQ("tag", dim12.value_str());
+
+ const auto& dim13 = dim1.value_tuple().dimensions_value(2);
+ EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim13.value_case());
+ EXPECT_EQ(987654, dim13.value_int());
+
+ const auto& dim2 = result.value_tuple().dimensions_value(1);
+ EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim2.value_case());
+ EXPECT_EQ(99999, dim2.value_int());
+}
+
+TEST(AtomMatcherTest, TestWriteAtomToProto) {
+ AttributionNode attribution_node1;
+ attribution_node1.set_uid(1111);
+ attribution_node1.set_tag("location1");
+
+ AttributionNode attribution_node2;
+ attribution_node2.set_uid(2222);
+ attribution_node2.set_tag("location2");
+
+ std::vector<AttributionNode> attribution_nodes = {attribution_node1, attribution_node2};
+
+ // Set up the event
+ LogEvent event(4, 12345);
+ event.write(attribution_nodes);
+ event.write((int32_t)999);
+ // Convert to a LogEvent
+ event.init();
+
+ android::util::ProtoOutputStream protoOutput;
+ writeFieldValueTreeToStream(event.GetTagId(), event.getValues(), &protoOutput);
+
+ vector<uint8_t> outData;
+ outData.resize(protoOutput.size());
+ size_t pos = 0;
+ auto iter = protoOutput.data();
+ while (iter.readBuffer() != NULL) {
+ size_t toRead = iter.currentToRead();
+ std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
+ pos += toRead;
+ iter.rp()->move(toRead);
+ }
+
+ Atom result;
+ EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
+ EXPECT_EQ(Atom::PushedCase::kBleScanResultReceived, result.pushed_case());
+ const auto& atom = result.ble_scan_result_received();
+ EXPECT_EQ(2, atom.attribution_node_size());
+ EXPECT_EQ(1111, atom.attribution_node(0).uid());
+ EXPECT_EQ("location1", atom.attribution_node(0).tag());
+ EXPECT_EQ(2222, atom.attribution_node(1).uid());
+ EXPECT_EQ("location2", atom.attribution_node(1).tag());
+ EXPECT_EQ(999, atom.num_of_results());
+}
+
+
+} // namespace statsd
+} // namespace os
+} // namespace android
+#else
+GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
\ No newline at end of file
diff --git a/cmds/statsd/tests/LogEntryMatcher_test.cpp b/cmds/statsd/tests/LogEntryMatcher_test.cpp
index 111b4ba..1023ea4 100644
--- a/cmds/statsd/tests/LogEntryMatcher_test.cpp
+++ b/cmds/statsd/tests/LogEntryMatcher_test.cpp
@@ -14,6 +14,7 @@
#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
#include "matchers/matcher_util.h"
+#include "stats_log_util.h"
#include "stats_util.h"
#include <gtest/gtest.h>
@@ -35,8 +36,6 @@
const int ATTRIBUTION_UID_FIELD_ID = 1;
const int ATTRIBUTION_TAG_FIELD_ID = 2;
-// Private API from liblog.
-extern "C" void android_log_rewind(android_log_context ctx);
#ifdef __ANDROID__
TEST(AtomMatcherTest, TestSimpleMatcher) {
@@ -597,7 +596,6 @@
matcherResults.push_back(MatchingState::kMatched);
EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
}
-
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
index fd28460..b649215 100644
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ b/cmds/statsd/tests/LogEvent_test.cpp
@@ -22,548 +22,142 @@
namespace os {
namespace statsd {
-TEST(LogEventTest, testEmptyEvent) {
- const int32_t TAG_ID = 123;
- LogEvent event(TAG_ID, 0);
- event.init();
+TEST(LogEventTest, TestLogParsing) {
+ LogEvent event1(1, 2000);
- DimensionsValue dimensionsValue;
- EXPECT_FALSE(event.GetSimpleAtomDimensionsValueProto(234, &dimensionsValue));
- FieldMatcher dimensions;
- dimensions.set_field(event.GetTagId());
- EXPECT_FALSE(event.GetAtomDimensionsValueProto(dimensions, &dimensionsValue));
+ std::vector<AttributionNode> nodes;
- dimensions.add_child()->set_field(3);
- dimensions.mutable_child(0)->set_position(Position::FIRST);
- EXPECT_FALSE(event.GetAtomDimensionsValueProto(dimensions, &dimensionsValue));
+ AttributionNode node1;
+ node1.set_uid(1000);
+ node1.set_tag("tag1");
+ nodes.push_back(node1);
- dimensions.mutable_child(0)->set_position(Position::ANY);
- EXPECT_FALSE(event.GetAtomDimensionsValueProto(dimensions, &dimensionsValue));
+ AttributionNode node2;
+ node2.set_uid(2000);
+ node2.set_tag("tag2");
+ nodes.push_back(node2);
- dimensions.mutable_child(0)->set_position(Position::LAST);
- EXPECT_FALSE(event.GetAtomDimensionsValueProto(dimensions, &dimensionsValue));
+ event1.write(nodes);
+ event1.write("hello");
+ event1.write((int32_t)10);
+ event1.write((int64_t)20);
+ event1.write((float)1.1);
+ event1.init();
+
+ const auto& items = event1.getValues();
+ EXPECT_EQ((size_t)8, items.size());
+ EXPECT_EQ(1, event1.GetTagId());
+
+ const FieldValue& item0 = event1.getValues()[0];
+ EXPECT_EQ(0x2010101, item0.mField.getField());
+ EXPECT_EQ(Type::INT, item0.mValue.getType());
+ EXPECT_EQ(1000, item0.mValue.int_value);
+
+ const FieldValue& item1 = event1.getValues()[1];
+ EXPECT_EQ(0x2010182, item1.mField.getField());
+ EXPECT_EQ(Type::STRING, item1.mValue.getType());
+ EXPECT_EQ("tag1", item1.mValue.str_value);
+
+ const FieldValue& item2 = event1.getValues()[2];
+ EXPECT_EQ(0x2018201, item2.mField.getField());
+ EXPECT_EQ(Type::INT, item2.mValue.getType());
+ EXPECT_EQ(2000, item2.mValue.int_value);
+
+ const FieldValue& item3 = event1.getValues()[3];
+ EXPECT_EQ(0x2018282, item3.mField.getField());
+ EXPECT_EQ(Type::STRING, item3.mValue.getType());
+ EXPECT_EQ("tag2", item3.mValue.str_value);
+
+ const FieldValue& item4 = event1.getValues()[4];
+ EXPECT_EQ(0x20000, item4.mField.getField());
+ EXPECT_EQ(Type::STRING, item4.mValue.getType());
+ EXPECT_EQ("hello", item4.mValue.str_value);
+
+ const FieldValue& item5 = event1.getValues()[5];
+ EXPECT_EQ(0x30000, item5.mField.getField());
+ EXPECT_EQ(Type::INT, item5.mValue.getType());
+ EXPECT_EQ(10, item5.mValue.int_value);
+
+ const FieldValue& item6 = event1.getValues()[6];
+ EXPECT_EQ(0x40000, item6.mField.getField());
+ EXPECT_EQ(Type::LONG, item6.mValue.getType());
+ EXPECT_EQ((int64_t)20, item6.mValue.long_value);
+
+ const FieldValue& item7 = event1.getValues()[7];
+ EXPECT_EQ(0x50000, item7.mField.getField());
+ EXPECT_EQ(Type::FLOAT, item7.mValue.getType());
+ EXPECT_EQ((float)1.1, item7.mValue.float_value);
}
-TEST(LogEventTest, testRepeatedAttributionNode) {
- const int32_t TAG_ID = 123;
- LogEvent event(TAG_ID, 0);
- AttributionNode attribution_node1;
- attribution_node1.set_uid(1111);
- attribution_node1.set_tag("locationService");
+TEST(LogEventTest, TestLogParsing2) {
+ LogEvent event1(1, 2000);
- AttributionNode attribution_node2;
- attribution_node2.set_uid(2222);
- attribution_node2.set_tag("locationService2");
+ std::vector<AttributionNode> nodes;
- AttributionNode attribution_node3;
- attribution_node3.set_uid(3333);
- attribution_node3.set_tag("locationService3");
- std::vector<AttributionNode> attribution_nodes =
- {attribution_node1, attribution_node2, attribution_node3};
+ event1.write("hello");
- // 1nd field: int32.
- EXPECT_TRUE(event.write(int32_t(11)));
- // 2rd field: float.
- EXPECT_TRUE(event.write(3.45f));
- // Here it assume that the atom proto contains a repeated AttributionNode field.
- // 3rd field: attribution node. This is repeated field.
- EXPECT_TRUE(event.write(attribution_nodes));
- // 4th field: bool.
- EXPECT_TRUE(event.write(true));
- // 5th field: long.
- EXPECT_TRUE(event.write(uint64_t(1234)));
+ // repeated msg can be in the middle
+ AttributionNode node1;
+ node1.set_uid(1000);
+ node1.set_tag("tag1");
+ nodes.push_back(node1);
- event.init();
+ AttributionNode node2;
+ node2.set_uid(2000);
+ node2.set_tag("tag2");
+ nodes.push_back(node2);
+ event1.write(nodes);
- DimensionsValue dimensionsValue;
- // Query single primitive fields.
- EXPECT_TRUE(event.GetSimpleAtomDimensionsValueProto(1, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_int(), 11);
+ event1.write((int32_t)10);
+ event1.write((int64_t)20);
+ event1.write((float)1.1);
+ event1.init();
- EXPECT_TRUE(event.GetSimpleAtomDimensionsValueProto(2, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 2);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_float(), 3.45f);
+ const auto& items = event1.getValues();
+ EXPECT_EQ((size_t)8, items.size());
+ EXPECT_EQ(1, event1.GetTagId());
- EXPECT_TRUE(event.GetSimpleAtomDimensionsValueProto(4, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 4);
- // The bool value is stored in value_int field as logD does not support bool.
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_int(), true);
+ const FieldValue& item = event1.getValues()[0];
+ EXPECT_EQ(0x00010000, item.mField.getField());
+ EXPECT_EQ(Type::STRING, item.mValue.getType());
+ EXPECT_EQ("hello", item.mValue.str_value);
- EXPECT_TRUE(event.GetSimpleAtomDimensionsValueProto(5, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 5);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_long(), long(1234));
+ const FieldValue& item0 = event1.getValues()[1];
+ EXPECT_EQ(0x2020101, item0.mField.getField());
+ EXPECT_EQ(Type::INT, item0.mValue.getType());
+ EXPECT_EQ(1000, item0.mValue.int_value);
- // First attribution.
- FieldMatcher first_uid_dimensions;
- first_uid_dimensions.set_field(event.GetTagId());
- first_uid_dimensions.add_child()->set_field(3);
- first_uid_dimensions.mutable_child(0)->set_position(Position::FIRST);
- first_uid_dimensions.mutable_child(0)->add_child()->set_field(1);
- EXPECT_TRUE(event.GetAtomDimensionsValueProto(first_uid_dimensions, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 3);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).field(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).value_int(), 1111);
+ const FieldValue& item1 = event1.getValues()[2];
+ EXPECT_EQ(0x2020182, item1.mField.getField());
+ EXPECT_EQ(Type::STRING, item1.mValue.getType());
+ EXPECT_EQ("tag1", item1.mValue.str_value);
- FieldMatcher first_tag_dimensions = first_uid_dimensions;
- first_tag_dimensions.mutable_child(0)->mutable_child(0)->set_field(2);
- EXPECT_TRUE(event.GetAtomDimensionsValueProto(first_tag_dimensions, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 3);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).field(), 2);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).value_str(), "locationService");
+ const FieldValue& item2 = event1.getValues()[3];
+ EXPECT_EQ(0x2028201, item2.mField.getField());
+ EXPECT_EQ(Type::INT, item2.mValue.getType());
+ EXPECT_EQ(2000, item2.mValue.int_value);
- FieldMatcher first_attribution_dimensions = first_uid_dimensions;
- first_attribution_dimensions.mutable_child(0)->add_child()->set_field(2);
- EXPECT_TRUE(event.GetAtomDimensionsValueProto(first_attribution_dimensions, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 3);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value_size(), 2);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).field(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).value_int(), 1111);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(1).field(), 2);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(1).value_str(), "locationService");
+ const FieldValue& item3 = event1.getValues()[4];
+ EXPECT_EQ(0x2028282, item3.mField.getField());
+ EXPECT_EQ(Type::STRING, item3.mValue.getType());
+ EXPECT_EQ("tag2", item3.mValue.str_value);
- FieldMatcher last_attribution_dimensions = first_attribution_dimensions;
- last_attribution_dimensions.mutable_child(0)->set_position(Position::LAST);
- EXPECT_TRUE(event.GetAtomDimensionsValueProto(last_attribution_dimensions, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 3);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value_size(), 2);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).field(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).value_int(), 3333);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(1).field(), 2);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(1).value_str(), "locationService3");
+ const FieldValue& item5 = event1.getValues()[5];
+ EXPECT_EQ(0x30000, item5.mField.getField());
+ EXPECT_EQ(Type::INT, item5.mValue.getType());
+ EXPECT_EQ(10, item5.mValue.int_value);
- FieldMatcher any_attribution_dimensions = first_attribution_dimensions;
- any_attribution_dimensions.mutable_child(0)->set_position(Position::ANY);
- std::vector<DimensionsValue> dimensionsValues;
- event.GetAtomDimensionsValueProtos(any_attribution_dimensions, &dimensionsValues);
- EXPECT_EQ(dimensionsValues.size(), 3u);
- EXPECT_EQ(dimensionsValues[0].field(), event.GetTagId());
- EXPECT_EQ(dimensionsValues[0].value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValues[0].value_tuple().dimensions_value(0).field(), 3);
- EXPECT_EQ(dimensionsValues[0].value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value_size(), 2);
- EXPECT_EQ(dimensionsValues[0].value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).field(), 1);
- EXPECT_EQ(dimensionsValues[0].value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).value_int(), 1111);
- EXPECT_EQ(dimensionsValues[0].value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(1).field(), 2);
- EXPECT_EQ(dimensionsValues[0].value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(1).value_str(), "locationService");
- EXPECT_EQ(dimensionsValues[1].field(), event.GetTagId());
- EXPECT_EQ(dimensionsValues[1].value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValues[1].value_tuple().dimensions_value(0).field(), 3);
- EXPECT_EQ(dimensionsValues[1].value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value_size(), 2);
- EXPECT_EQ(dimensionsValues[1].value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).field(), 1);
- EXPECT_EQ(dimensionsValues[1].value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).value_int(), 2222);
- EXPECT_EQ(dimensionsValues[1].value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(1).field(), 2);
- EXPECT_EQ(dimensionsValues[1].value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(1).value_str(), "locationService2");
- EXPECT_EQ(dimensionsValues[2].field(), event.GetTagId());
- EXPECT_EQ(dimensionsValues[2].value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValues[2].value_tuple().dimensions_value(0).field(), 3);
- EXPECT_EQ(dimensionsValues[2].value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value_size(), 2);
- EXPECT_EQ(dimensionsValues[2].value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).field(), 1);
- EXPECT_EQ(dimensionsValues[2].value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).value_int(), 3333);
- EXPECT_EQ(dimensionsValues[2].value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(1).field(), 2);
- EXPECT_EQ(dimensionsValues[2].value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(1).value_str(), "locationService3");
+ const FieldValue& item6 = event1.getValues()[6];
+ EXPECT_EQ(0x40000, item6.mField.getField());
+ EXPECT_EQ(Type::LONG, item6.mValue.getType());
+ EXPECT_EQ((int64_t)20, item6.mValue.long_value);
- FieldMatcher mixed_dimensions = any_attribution_dimensions;
- mixed_dimensions.add_child()->set_field(1000);
- mixed_dimensions.add_child()->set_field(6); // missing field.
- mixed_dimensions.add_child()->set_field(3); // position not set.
- mixed_dimensions.add_child()->set_field(5);
- mixed_dimensions.add_child()->set_field(1);
- dimensionsValues.clear();
- event.GetAtomDimensionsValueProtos(mixed_dimensions, &dimensionsValues);
- EXPECT_EQ(dimensionsValues.size(), 3u);
- EXPECT_EQ(dimensionsValues[0].field(), event.GetTagId());
- EXPECT_EQ(dimensionsValues[0].value_tuple().dimensions_value_size(), 3);
- EXPECT_EQ(dimensionsValues[0].value_tuple().dimensions_value(0).field(), 3);
- EXPECT_EQ(dimensionsValues[0].value_tuple().dimensions_value(0).value_tuple().dimensions_value_size(), 2);
- EXPECT_EQ(dimensionsValues[0].value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(dimensionsValues[0].value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).value_int(),
- 1111);
- EXPECT_EQ(dimensionsValues[0].value_tuple().dimensions_value(0).value_tuple().dimensions_value(1).field(), 2);
- EXPECT_EQ(dimensionsValues[0].value_tuple().dimensions_value(0).value_tuple().dimensions_value(1).value_str(),
- "locationService");
- EXPECT_EQ(dimensionsValues[0].value_tuple().dimensions_value(1).field(), 5);
- EXPECT_EQ(dimensionsValues[0].value_tuple().dimensions_value(1).value_long(), long(1234));
- EXPECT_EQ(dimensionsValues[0].value_tuple().dimensions_value(2).field(), 1);
- EXPECT_EQ(dimensionsValues[0].value_tuple().dimensions_value(2).value_int(), 11);
-
- EXPECT_EQ(dimensionsValues[1].field(), event.GetTagId());
- EXPECT_EQ(dimensionsValues[1].value_tuple().dimensions_value_size(), 3);
- EXPECT_EQ(dimensionsValues[1].value_tuple().dimensions_value(0).field(), 3);
- EXPECT_EQ(dimensionsValues[1].value_tuple().dimensions_value(0).value_tuple().dimensions_value_size(), 2);
- EXPECT_EQ(dimensionsValues[1].value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(dimensionsValues[1].value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).value_int(),
- 2222);
- EXPECT_EQ(dimensionsValues[1].value_tuple().dimensions_value(0).value_tuple().dimensions_value(1).field(), 2);
- EXPECT_EQ(dimensionsValues[1].value_tuple().dimensions_value(0).value_tuple().dimensions_value(1).value_str(),
- "locationService2");
- EXPECT_EQ(dimensionsValues[1].value_tuple().dimensions_value(1).field(), 5);
- EXPECT_EQ(dimensionsValues[1].value_tuple().dimensions_value(1).value_long(), long(1234));
- EXPECT_EQ(dimensionsValues[1].value_tuple().dimensions_value(2).field(), 1);
- EXPECT_EQ(dimensionsValues[1].value_tuple().dimensions_value(2).value_int(), 11);
-
- EXPECT_EQ(dimensionsValues[2].field(), event.GetTagId());
- EXPECT_EQ(dimensionsValues[2].value_tuple().dimensions_value_size(), 3);
- EXPECT_EQ(dimensionsValues[2].value_tuple().dimensions_value(0).field(), 3);
- EXPECT_EQ(dimensionsValues[2].value_tuple().dimensions_value(0).value_tuple().dimensions_value_size(), 2);
- EXPECT_EQ(dimensionsValues[2].value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(dimensionsValues[2].value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).value_int(),
- 3333);
- EXPECT_EQ(dimensionsValues[2].value_tuple().dimensions_value(0).value_tuple().dimensions_value(1).field(), 2);
- EXPECT_EQ(dimensionsValues[2].value_tuple().dimensions_value(0).value_tuple().dimensions_value(1).value_str(),
- "locationService3");
- EXPECT_EQ(dimensionsValues[2].value_tuple().dimensions_value(1).field(), 5);
- EXPECT_EQ(dimensionsValues[2].value_tuple().dimensions_value(1).value_long(), long(1234));
- EXPECT_EQ(dimensionsValues[2].value_tuple().dimensions_value(2).field(), 1);
- EXPECT_EQ(dimensionsValues[2].value_tuple().dimensions_value(2).value_int(), 11);
-
- FieldMatcher wrong_dimensions = mixed_dimensions;
- // Wrong tagId.
- wrong_dimensions.set_field(event.GetTagId() + 100);
- dimensionsValues.clear();
- event.GetAtomDimensionsValueProtos(wrong_dimensions, &dimensionsValues);
- EXPECT_TRUE(dimensionsValues.empty());
+ const FieldValue& item7 = event1.getValues()[7];
+ EXPECT_EQ(0x50000, item7.mField.getField());
+ EXPECT_EQ(Type::FLOAT, item7.mValue.getType());
+ EXPECT_EQ((float)1.1, item7.mValue.float_value);
}
-TEST(LogEventTest, testMessageField) {
- const int32_t TAG_ID = 123;
- LogEvent event(TAG_ID, 0);
- AttributionNode attribution_node1;
- attribution_node1.set_uid(1111);
- attribution_node1.set_tag("locationService");
-
- AttributionNode attribution_node2;
- attribution_node2.set_uid(2222);
- attribution_node2.set_tag("locationService2");
-
- // 1nd field: int32.
- EXPECT_TRUE(event.write(int32_t(11)));
- // 2rd field: float.
- EXPECT_TRUE(event.write(3.45f));
- // Here it assume that the atom proto contains two optional AttributionNode fields.
- // 3rd field: attribution node. This is not repeated field.
- EXPECT_TRUE(event.write(attribution_node1));
- // 4th field: another attribution field. This is not repeated field.
- EXPECT_TRUE(event.write(attribution_node2));
- // 5th field: bool.
- EXPECT_TRUE(event.write(true));
- // 6th field: long.
- EXPECT_TRUE(event.write(uint64_t(1234)));
-
- event.init();
-
- FieldMatcher uid_dimensions1;
- uid_dimensions1.set_field(event.GetTagId());
- uid_dimensions1.add_child()->set_field(3);
- uid_dimensions1.mutable_child(0)->add_child()->set_field(1);
-
- FieldMatcher tag_dimensions1;
- tag_dimensions1.set_field(event.GetTagId());
- tag_dimensions1.add_child()->set_field(3);
- tag_dimensions1.mutable_child(0)->add_child()->set_field(2);
-
- FieldMatcher attribution_dimensions1;
- attribution_dimensions1.set_field(event.GetTagId());
- attribution_dimensions1.add_child()->set_field(3);
- attribution_dimensions1.mutable_child(0)->add_child()->set_field(1);
- attribution_dimensions1.mutable_child(0)->add_child()->set_field(2);
-
- FieldMatcher uid_dimensions2 = uid_dimensions1;
- uid_dimensions2.mutable_child(0)->set_field(4);
-
- FieldMatcher tag_dimensions2 = tag_dimensions1;
- tag_dimensions2.mutable_child(0)->set_field(4);
-
- FieldMatcher attribution_dimensions2 = attribution_dimensions1;
- attribution_dimensions2.mutable_child(0)->set_field(4);
-
- FieldMatcher mixed_dimensions = attribution_dimensions1;
- mixed_dimensions.add_child()->set_field(4);
- mixed_dimensions.mutable_child(1)->add_child()->set_field(1);
- mixed_dimensions.add_child()->set_field(1000);
- mixed_dimensions.add_child()->set_field(5);
- mixed_dimensions.add_child()->set_field(1);
-
- DimensionsValue dimensionsValue;
-
- // Query single primitive fields.
- EXPECT_TRUE(event.GetSimpleAtomDimensionsValueProto(1, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_int(), 11);
-
- EXPECT_TRUE(event.GetSimpleAtomDimensionsValueProto(2, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 2);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_float(), 3.45f);
-
- EXPECT_TRUE(event.GetSimpleAtomDimensionsValueProto(5, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 5);
- // The bool value is stored in value_int field as logD does not support bool.
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_int(), true);
-
- EXPECT_TRUE(event.GetSimpleAtomDimensionsValueProto(6, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 6);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_long(), long(1234));
-
- // Query atom field 3: attribution node uid field only.
- EXPECT_TRUE(event.GetAtomDimensionsValueProto(uid_dimensions1, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 3);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).field(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).value_int(), 1111);
-
- // Query atom field 3: attribution node tag field only.
- EXPECT_TRUE(event.GetAtomDimensionsValueProto(tag_dimensions1, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 3);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).field(), 2);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).value_str(), "locationService");
-
- // Query atom field 3: attribution node uid + tag fields.
- EXPECT_TRUE(event.GetAtomDimensionsValueProto(attribution_dimensions1, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 3);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value_size(), 2);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).field(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).value_int(), 1111);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(1).field(), 2);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(1).value_str(), "locationService");
-
- // Query atom field 4: attribution node uid field only.
- EXPECT_TRUE(event.GetAtomDimensionsValueProto(uid_dimensions2, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 4);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).field(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).value_int(), 2222);
-
- // Query atom field 4: attribution node tag field only.
- EXPECT_TRUE(event.GetAtomDimensionsValueProto(tag_dimensions2, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 4);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).field(), 2);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).value_str(), "locationService2");
-
- // Query atom field 4: attribution node uid + tag fields.
- EXPECT_TRUE(event.GetAtomDimensionsValueProto(attribution_dimensions2, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 4);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value_size(), 2);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).field(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).value_int(), 2222);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(1).field(), 2);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(1).value_str(), "locationService2");
-
- // Query multiple fields:
- // 1/ Field 3: attribution uid + tag.
- // 2/ Field 4: attribution uid only.
- // 3/ Field not exist.
- // 4/ Primitive fields #5
- // 5/ Primitive fields #1
- EXPECT_TRUE(event.GetAtomDimensionsValueProto(mixed_dimensions, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 4);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 3);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value_size(), 2);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).field(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(0).value_int(), 1111);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(1).field(), 2);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_tuple()
- .dimensions_value(1).value_str(), "locationService");
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(1).field(), 4);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(1).value_tuple()
- .dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(1).value_tuple()
- .dimensions_value(0).field(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(1).value_tuple()
- .dimensions_value(0).value_int(), 2222);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(2).field(), 5);
- // The bool value is stored in value_int field as logD does not support bool.
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(2).value_int(), true);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(3).field(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(3).value_int(), 11);
-}
-
-TEST(LogEventTest, testAllPrimitiveFields) {
- const int32_t TAG_ID = 123;
- LogEvent event(TAG_ID, 0);
-
- // 1nd field: int32.
- EXPECT_TRUE(event.write(int32_t(11)));
- // 2rd field: float.
- EXPECT_TRUE(event.write(3.45f));
- // 3th field: string.
- EXPECT_TRUE(event.write("test"));
- // 4th field: bool.
- EXPECT_TRUE(event.write(true));
- // 5th field: bool.
- EXPECT_TRUE(event.write(false));
- // 6th field: long.
- EXPECT_TRUE(event.write(uint64_t(1234)));
-
- event.init();
-
- DimensionsValue dimensionsValue;
- EXPECT_TRUE(event.GetSimpleAtomDimensionsValueProto(1, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_int(), 11);
-
- EXPECT_TRUE(event.GetSimpleAtomDimensionsValueProto(2, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 2);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_float(), 3.45f);
-
- EXPECT_TRUE(event.GetSimpleAtomDimensionsValueProto(3, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 3);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_str(), "test");
-
- EXPECT_TRUE(event.GetSimpleAtomDimensionsValueProto(4, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 4);
- // The bool value is stored in value_int field as logD does not support bool.
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_int(), true);
-
- EXPECT_TRUE(event.GetSimpleAtomDimensionsValueProto(5, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 5);
- // The bool value is stored in value_int field as logD does not support bool.
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_int(), false);
-
- EXPECT_TRUE(event.GetSimpleAtomDimensionsValueProto(6, &dimensionsValue));
- EXPECT_EQ(dimensionsValue.field(), event.GetTagId());
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).field(), 6);
- EXPECT_EQ(dimensionsValue.value_tuple().dimensions_value(0).value_long(), long(1234));
-
- // Field not exist.
- EXPECT_FALSE(event.GetSimpleAtomDimensionsValueProto(7, &dimensionsValue));
-}
-
-TEST(LogEventTest, testWriteAtomProtoToStream) {
- AttributionNode attribution_node1;
- attribution_node1.set_uid(1111);
- attribution_node1.set_tag("locationService");
-
- AttributionNode attribution_node2;
- attribution_node2.set_uid(2222);
- attribution_node2.set_tag("locationService2");
-
- AttributionNode attribution_node3;
- attribution_node3.set_uid(3333);
- attribution_node3.set_tag("locationService3");
- std::vector<AttributionNode> attribution_nodes =
- {attribution_node1, attribution_node2, attribution_node3};
-
- LogEvent event(1, 0);
- EXPECT_TRUE(event.write("222"));
- EXPECT_TRUE(event.write(attribution_nodes));
- EXPECT_TRUE(event.write(345));
- EXPECT_TRUE(event.write(attribution_node3));
- EXPECT_TRUE(event.write("hello"));
- event.init();
-
- util::ProtoOutputStream protoOutput;
- // For now only see whether it will crash.
- // TODO(yanglu): test parsing from stream.
- event.ToProto(protoOutput);
-}
} // namespace statsd
} // namespace os
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
index aab5bed..cb72697 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -45,7 +45,7 @@
}
MOCK_METHOD0(byteSize, size_t());
- MOCK_METHOD1(onDumpReport, void(ProtoOutputStream* output));
+ MOCK_METHOD2(onDumpReport, void(const uint64_t timeNs, ProtoOutputStream* output));
};
TEST(StatsLogProcessorTest, TestRateLimitByteSize) {
@@ -69,24 +69,26 @@
sp<UidMap> m = new UidMap();
sp<AnomalyMonitor> anomalyMonitor;
int broadcastCount = 0;
- StatsLogProcessor p(m, anomalyMonitor, 0,
- [&broadcastCount](const ConfigKey& key) { broadcastCount++; });
+ StatsLogProcessor p(m, anomalyMonitor, 0, [&broadcastCount](const ConfigKey& key) {
+ broadcastCount++;
+ });
MockMetricsManager mockMetricsManager;
ConfigKey key(100, 12345);
EXPECT_CALL(mockMetricsManager, byteSize())
- .Times(2)
+ .Times(1)
.WillRepeatedly(Return(int(StatsdStats::kMaxMetricsBytesPerConfig * .95)));
// Expect only one broadcast despite always returning a size that should trigger broadcast.
p.flushIfNecessaryLocked(1, key, mockMetricsManager);
EXPECT_EQ(1, broadcastCount);
+ // b/73089712
// This next call to flush should not trigger a broadcast.
- p.mLastByteSizeTimes.clear(); // Force another check for byte size.
- p.flushIfNecessaryLocked(2, key, mockMetricsManager);
- EXPECT_EQ(1, broadcastCount);
+ // p.mLastByteSizeTimes.clear(); // Force another check for byte size.
+ // p.flushIfNecessaryLocked(2, key, mockMetricsManager);
+ // EXPECT_EQ(1, broadcastCount);
}
TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge) {
@@ -103,7 +105,7 @@
.Times(1)
.WillRepeatedly(Return(int(StatsdStats::kMaxMetricsBytesPerConfig * 1.2)));
- EXPECT_CALL(mockMetricsManager, onDumpReport(_)).Times(1);
+ EXPECT_CALL(mockMetricsManager, onDumpReport(_, _)).Times(1);
// Expect to call the onDumpReport and skip the broadcast.
p.flushIfNecessaryLocked(1, key, mockMetricsManager);
diff --git a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
index a415ea1..b4a7bb7 100644
--- a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
+++ b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
@@ -34,10 +34,10 @@
const ConfigKey kConfigKey(0, 12345);
MetricDimensionKey getMockMetricDimensionKey(int key, string value) {
- DimensionsValue dimensionsValue;
- dimensionsValue.set_field(key);
- dimensionsValue.set_value_str(value);
- return MetricDimensionKey(HashableDimensionKey(dimensionsValue), DEFAULT_DIMENSION_KEY);
+ int pos[] = {key, 0, 0};
+ HashableDimensionKey dim;
+ dim.addValue(FieldValue(Field(1, pos, 0), Value(value)));
+ return MetricDimensionKey(dim, DEFAULT_DIMENSION_KEY);
}
void AddValueToBucket(const std::vector<std::pair<MetricDimensionKey, long>>& key_value_pair_list,
diff --git a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
index d1b7b28..038d449 100644
--- a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
+++ b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
@@ -80,31 +80,31 @@
const std::vector<int> &uids, const string& conditionName) {
std::map<int64_t, std::vector<HashableDimensionKey>> outputKeyMap;
std::vector<int> uid_indexes;
+ int pos[] = {1, 1, 1};
+ int depth = 2;
+ Field field(1, pos, depth);
switch(position) {
case Position::FIRST:
uid_indexes.push_back(0);
break;
case Position::LAST:
uid_indexes.push_back(uids.size() - 1);
+ field.setField(0x02018001);
break;
case Position::ANY:
uid_indexes.resize(uids.size());
std::iota(uid_indexes.begin(), uid_indexes.end(), 0);
+ field.setField(0x02010001);
break;
default:
break;
}
for (const int idx : uid_indexes) {
- DimensionsValue dimensionsValue;
- dimensionsValue.set_field(TAG_ID);
- dimensionsValue.mutable_value_tuple()->add_dimensions_value()->set_field(
- ATTRIBUTION_NODE_FIELD_ID);
- dimensionsValue.mutable_value_tuple()->mutable_dimensions_value(0)
- ->mutable_value_tuple()->add_dimensions_value()->set_field(ATTRIBUTION_NODE_FIELD_ID);
- dimensionsValue.mutable_value_tuple()->mutable_dimensions_value(0)
- ->mutable_value_tuple()->mutable_dimensions_value(0)->set_value_int(uids[idx]);
- outputKeyMap[StringToId(conditionName)].push_back(HashableDimensionKey(dimensionsValue));
+ Value value((int32_t)uids[idx]);
+ HashableDimensionKey dim;
+ dim.addValue(FieldValue(field, value));
+ outputKeyMap[StringToId(conditionName)].push_back(dim);
}
return outputKeyMap;
}
@@ -265,7 +265,7 @@
TEST(SimpleConditionTrackerTest, TestSlicedCondition) {
for (Position position :
{ Position::ANY, Position::FIRST, Position::LAST}) {
- FieldMatcher dimensionInCondition;
+ vector<Matcher> dimensionInCondition;
std::unordered_set<HashableDimensionKey> dimensionKeys;
SimplePredicate simplePredicate = getWakeLockHeldCondition(
@@ -374,7 +374,7 @@
}
TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim) {
- FieldMatcher dimensionInCondition;
+ vector<Matcher> dimensionInCondition;
std::unordered_set<HashableDimensionKey> dimensionKeys;
SimplePredicate simplePredicate = getWakeLockHeldCondition(
@@ -470,7 +470,7 @@
TEST(SimpleConditionTrackerTest, TestStopAll) {
for (Position position :
{Position::ANY, Position::FIRST, Position::LAST}) {
- FieldMatcher dimensionInCondition;
+ vector<Matcher> dimensionInCondition;
std::unordered_set<HashableDimensionKey> dimensionKeys;
SimplePredicate simplePredicate = getWakeLockHeldCondition(
true /*nesting*/, true /*default to false*/, true /*output slice by uid*/,
@@ -576,7 +576,6 @@
conditionCache, dimensionKeys);
EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
}
-
}
} // namespace statsd
diff --git a/cmds/statsd/tests/dimension_test.cpp b/cmds/statsd/tests/dimension_test.cpp
deleted file mode 100644
index 678abae..0000000
--- a/cmds/statsd/tests/dimension_test.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "dimension.h"
-
-#include <gtest/gtest.h>
-
-using namespace android::os::statsd;
-
-#ifdef __ANDROID__
-
-TEST(DimensionTest, subLeafNodes) {
- DimensionsValue dimension;
- int tagId = 100;
- dimension.set_field(tagId);
- auto child = dimension.mutable_value_tuple()->add_dimensions_value();
- child->set_field(1);
- child->set_value_int(2000);
-
- child = dimension.mutable_value_tuple()->add_dimensions_value();
- child->set_field(3);
- child->set_value_str("test");
-
- child = dimension.mutable_value_tuple()->add_dimensions_value();
- child->set_field(4);
- auto grandChild = child->mutable_value_tuple()->add_dimensions_value();
- grandChild->set_field(1);
- grandChild->set_value_float(1.3f);
- grandChild = child->mutable_value_tuple()->add_dimensions_value();
- grandChild->set_field(3);
- grandChild->set_value_str("tag");
-
- child = dimension.mutable_value_tuple()->add_dimensions_value();
- child->set_field(6);
- child->set_value_bool(false);
-
- DimensionsValue sub_dimension;
- FieldMatcher matcher;
-
- // Tag id not matched.
- matcher.set_field(tagId + 1);
- EXPECT_FALSE(getSubDimension(dimension, matcher, &sub_dimension));
-
- // Field not exist.
- matcher.Clear();
- matcher.set_field(tagId);
- matcher.add_child()->set_field(5);
- EXPECT_FALSE(getSubDimension(dimension, matcher, &sub_dimension));
-
- // Field exists.
- matcher.Clear();
- matcher.set_field(tagId);
- matcher.add_child()->set_field(3);
- EXPECT_TRUE(getSubDimension(dimension, matcher, &sub_dimension));
-
- // Field exists.
- matcher.Clear();
- sub_dimension.Clear();
- matcher.set_field(tagId);
- matcher.add_child()->set_field(6);
- EXPECT_TRUE(getSubDimension(dimension, matcher, &sub_dimension));
-
- // Field exists.
- matcher.Clear();
- sub_dimension.Clear();
- matcher.set_field(tagId);
- matcher.add_child()->set_field(1);
- EXPECT_TRUE(getSubDimension(dimension, matcher, &sub_dimension));
-
- // Not leaf field.
- matcher.Clear();
- sub_dimension.Clear();
- matcher.set_field(tagId);
- matcher.add_child()->set_field(4);
- EXPECT_FALSE(getSubDimension(dimension, matcher, &sub_dimension));
-
- // Grand-child leaf field not exist.
- matcher.Clear();
- sub_dimension.Clear();
- matcher.set_field(tagId);
- auto childMatcher = matcher.add_child();
- childMatcher->set_field(4);
- childMatcher->add_child()->set_field(2);
- EXPECT_FALSE(getSubDimension(dimension, matcher, &sub_dimension));
-
- // Grand-child leaf field.
- matcher.Clear();
- sub_dimension.Clear();
- matcher.set_field(tagId);
- childMatcher = matcher.add_child();
- childMatcher->set_field(4);
- childMatcher->add_child()->set_field(1);
- EXPECT_TRUE(getSubDimension(dimension, matcher, &sub_dimension));
-
- matcher.Clear();
- sub_dimension.Clear();
- matcher.set_field(tagId);
- childMatcher = matcher.add_child();
- childMatcher->set_field(4);
- childMatcher->add_child()->set_field(3);
- EXPECT_TRUE(getSubDimension(dimension, matcher, &sub_dimension));
-
- // Multiple grand-child fields.
- matcher.Clear();
- sub_dimension.Clear();
- matcher.set_field(tagId);
- childMatcher = matcher.add_child();
- childMatcher->set_field(4);
- childMatcher->add_child()->set_field(3);
- childMatcher->add_child()->set_field(1);
- EXPECT_TRUE(getSubDimension(dimension, matcher, &sub_dimension));
-
- // Multiple fields.
- matcher.Clear();
- sub_dimension.Clear();
- matcher.set_field(tagId);
- childMatcher = matcher.add_child();
- childMatcher->set_field(4);
- childMatcher->add_child()->set_field(3);
- childMatcher->add_child()->set_field(1);
- matcher.add_child()->set_field(3);
- EXPECT_TRUE(getSubDimension(dimension, matcher, &sub_dimension));
-
- // Subset of the fields not exist.
- matcher.Clear();
- sub_dimension.Clear();
- matcher.set_field(tagId);
- childMatcher = matcher.add_child();
- childMatcher->set_field(4);
- childMatcher->add_child()->set_field(3);
- childMatcher->add_child()->set_field(1);
- matcher.add_child()->set_field(2);
- EXPECT_FALSE(getSubDimension(dimension, matcher, &sub_dimension));
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
index a56db28..01743ef 100644
--- a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
@@ -146,9 +146,13 @@
processor->OnLogEvent(event.get());
}
ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, &reports);
+ vector<uint8_t> buffer;
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, &buffer);
+ EXPECT_TRUE(buffer.size() > 0);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
EXPECT_EQ(reports.reports_size(), 1);
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
+
StatsLogReport::CountMetricDataWrapper countMetrics;
sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
EXPECT_EQ(countMetrics.data_size(), 4);
diff --git a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_test.cpp b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_test.cpp
index b5d48ef..275b5824 100644
--- a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_test.cpp
@@ -43,8 +43,8 @@
auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
// The predicate is dimensioning by any attribution node and both by uid and tag.
*holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() =
- CreateAttributionUidAndTagDimensions(
- android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
+ CreateAttributionUidAndTagDimensions(android::util::WAKELOCK_STATE_CHANGED,
+ {Position::FIRST});
*config.add_predicate() = holdingWakelockPredicate;
auto combinationPredicate = config.add_predicate();
@@ -57,8 +57,8 @@
metric->set_id(StringToId("ScreenBrightnessChangeMetric"));
metric->set_what(screenBrightnessChangeAtomMatcher.id());
metric->set_condition(combinationPredicate->id());
- *metric->mutable_dimensions_in_what() = CreateDimensions(
- android::util::SCREEN_BRIGHTNESS_CHANGED, {1 /* level */});
+ *metric->mutable_dimensions_in_what() =
+ CreateDimensions(android::util::SCREEN_BRIGHTNESS_CHANGED, {1 /* level */});
*metric->mutable_dimensions_in_condition() = CreateAttributionUidDimensions(
android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
metric->set_bucket(ONE_MINUTE);
@@ -72,62 +72,54 @@
auto config = CreateCountMetricWithNoLinkConfig();
int64_t bucketStartTimeNs = 10000000000;
int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
+ TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
auto processor = CreateStatsLogProcessor(bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- std::vector<AttributionNode> attributions1 =
- {CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(222, "GMSCoreModule2")};
+ std::vector<AttributionNode> attributions1 = {CreateAttribution(111, "App1"),
+ CreateAttribution(222, "GMSCoreModule1"),
+ CreateAttribution(222, "GMSCoreModule2")};
- std::vector<AttributionNode> attributions2 =
- {CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(555, "GMSCoreModule2")};
+ std::vector<AttributionNode> attributions2 = {CreateAttribution(333, "App2"),
+ CreateAttribution(222, "GMSCoreModule1"),
+ CreateAttribution(555, "GMSCoreModule2")};
std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_ON, bucketStartTimeNs + 10));
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_OFF, bucketStartTimeNs + 100));
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_ON, bucketStartTimeNs + bucketSizeNs + 1));
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_OFF, bucketStartTimeNs + 2 * bucketSizeNs - 10));
+ events.push_back(
+ CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, bucketStartTimeNs + 10));
+ events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
+ bucketStartTimeNs + 100));
+ events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
+ bucketStartTimeNs + bucketSizeNs + 1));
+ events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
+ bucketStartTimeNs + 2 * bucketSizeNs - 10));
- events.push_back(CreateAcquireWakelockEvent(
- attributions1, "wl1", bucketStartTimeNs + 200));
- events.push_back(CreateReleaseWakelockEvent(
- attributions1, "wl1", bucketStartTimeNs + bucketSizeNs + 1));
+ events.push_back(CreateAcquireWakelockEvent(attributions1, "wl1", bucketStartTimeNs + 200));
+ events.push_back(
+ CreateReleaseWakelockEvent(attributions1, "wl1", bucketStartTimeNs + bucketSizeNs + 1));
- events.push_back(CreateAcquireWakelockEvent(
- attributions2, "wl2", bucketStartTimeNs + bucketSizeNs - 100));
- events.push_back(CreateReleaseWakelockEvent(
- attributions2, "wl2", bucketStartTimeNs + 2 * bucketSizeNs - 50));
+ events.push_back(CreateAcquireWakelockEvent(attributions2, "wl2",
+ bucketStartTimeNs + bucketSizeNs - 100));
+ events.push_back(CreateReleaseWakelockEvent(attributions2, "wl2",
+ bucketStartTimeNs + 2 * bucketSizeNs - 50));
- events.push_back(CreateScreenBrightnessChangedEvent(
- 123, bucketStartTimeNs + 11));
- events.push_back(CreateScreenBrightnessChangedEvent(
- 123, bucketStartTimeNs + 101));
- events.push_back(CreateScreenBrightnessChangedEvent(
- 123, bucketStartTimeNs + 201));
- events.push_back(CreateScreenBrightnessChangedEvent(
- 456, bucketStartTimeNs + 203));
- events.push_back(CreateScreenBrightnessChangedEvent(
- 456, bucketStartTimeNs + bucketSizeNs - 99));
- events.push_back(CreateScreenBrightnessChangedEvent(
- 456, bucketStartTimeNs + bucketSizeNs - 2));
- events.push_back(CreateScreenBrightnessChangedEvent(
- 789, bucketStartTimeNs + bucketSizeNs - 1));
- events.push_back(CreateScreenBrightnessChangedEvent(
- 456, bucketStartTimeNs + bucketSizeNs + 2));
- events.push_back(CreateScreenBrightnessChangedEvent(
- 789, bucketStartTimeNs + 2 * bucketSizeNs - 11));
- events.push_back(CreateScreenBrightnessChangedEvent(
- 789, bucketStartTimeNs + 2 * bucketSizeNs - 9));
- events.push_back(CreateScreenBrightnessChangedEvent(
- 789, bucketStartTimeNs + 2 * bucketSizeNs - 1));
+ events.push_back(CreateScreenBrightnessChangedEvent(123, bucketStartTimeNs + 11));
+ events.push_back(CreateScreenBrightnessChangedEvent(123, bucketStartTimeNs + 101));
+ events.push_back(CreateScreenBrightnessChangedEvent(123, bucketStartTimeNs + 201));
+ events.push_back(CreateScreenBrightnessChangedEvent(456, bucketStartTimeNs + 203));
+ events.push_back(
+ CreateScreenBrightnessChangedEvent(456, bucketStartTimeNs + bucketSizeNs - 99));
+ events.push_back(CreateScreenBrightnessChangedEvent(456, bucketStartTimeNs + bucketSizeNs - 2));
+ events.push_back(CreateScreenBrightnessChangedEvent(789, bucketStartTimeNs + bucketSizeNs - 1));
+ events.push_back(CreateScreenBrightnessChangedEvent(456, bucketStartTimeNs + bucketSizeNs + 2));
+ events.push_back(
+ CreateScreenBrightnessChangedEvent(789, bucketStartTimeNs + 2 * bucketSizeNs - 11));
+ events.push_back(
+ CreateScreenBrightnessChangedEvent(789, bucketStartTimeNs + 2 * bucketSizeNs - 9));
+ events.push_back(
+ CreateScreenBrightnessChangedEvent(789, bucketStartTimeNs + 2 * bucketSizeNs - 1));
sortLogEventsByTimestamp(&events);
@@ -136,7 +128,10 @@
}
ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &reports);
+ vector<uint8_t> buffer;
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer);
+ EXPECT_TRUE(buffer.size() > 0);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
EXPECT_EQ(reports.reports_size(), 1);
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
@@ -147,7 +142,7 @@
auto data = countMetrics.data(0);
EXPECT_EQ(data.bucket_info_size(), 1);
EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_nanos(), bucketStartTimeNs );
+ EXPECT_EQ(data.bucket_info(0).start_bucket_nanos(), bucketStartTimeNs);
EXPECT_EQ(data.bucket_info(0).end_bucket_nanos(), bucketStartTimeNs + bucketSizeNs);
EXPECT_EQ(data.dimensions_in_what().field(), android::util::SCREEN_BRIGHTNESS_CHANGED);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
@@ -164,7 +159,8 @@
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 123);
- ValidateAttributionUidDimension(data.dimensions_in_condition(), android::util::WAKELOCK_STATE_CHANGED, 111);
+ ValidateAttributionUidDimension(data.dimensions_in_condition(),
+ android::util::WAKELOCK_STATE_CHANGED, 111);
data = countMetrics.data(2);
EXPECT_EQ(data.bucket_info_size(), 1);
@@ -175,7 +171,8 @@
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 456);
- ValidateAttributionUidDimension(data.dimensions_in_condition(), android::util::WAKELOCK_STATE_CHANGED, 111);
+ ValidateAttributionUidDimension(data.dimensions_in_condition(),
+ android::util::WAKELOCK_STATE_CHANGED, 111);
data = countMetrics.data(3);
EXPECT_EQ(data.bucket_info_size(), 2);
@@ -189,7 +186,8 @@
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 456);
- ValidateAttributionUidDimension(data.dimensions_in_condition(), android::util::WAKELOCK_STATE_CHANGED, 333);
+ ValidateAttributionUidDimension(data.dimensions_in_condition(),
+ android::util::WAKELOCK_STATE_CHANGED, 333);
data = countMetrics.data(4);
EXPECT_EQ(data.bucket_info_size(), 1);
@@ -211,7 +209,8 @@
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 789);
- ValidateAttributionUidDimension(data.dimensions_in_condition(), android::util::WAKELOCK_STATE_CHANGED, 111);
+ ValidateAttributionUidDimension(data.dimensions_in_condition(),
+ android::util::WAKELOCK_STATE_CHANGED, 111);
data = countMetrics.data(6);
EXPECT_EQ(data.bucket_info_size(), 1);
@@ -222,7 +221,8 @@
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 789);
- ValidateAttributionUidDimension(data.dimensions_in_condition(), android::util::WAKELOCK_STATE_CHANGED, 333);
+ ValidateAttributionUidDimension(data.dimensions_in_condition(),
+ android::util::WAKELOCK_STATE_CHANGED, 333);
}
namespace {
@@ -239,8 +239,8 @@
auto screenIsOffPredicate = CreateScreenIsOffPredicate();
auto isSyncingPredicate = CreateIsSyncingPredicate();
auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
- *syncDimension = CreateAttributionUidAndTagDimensions(
- android::util::SYNC_STATE_CHANGED, {Position::FIRST});
+ *syncDimension = CreateAttributionUidAndTagDimensions(android::util::SYNC_STATE_CHANGED,
+ {Position::FIRST});
syncDimension->add_child()->set_field(2 /* name field*/);
*config.add_predicate() = screenIsOffPredicate;
@@ -256,8 +256,8 @@
metric->set_id(StringToId("AppCrashMetric"));
metric->set_what(appCrashMatcher.id());
metric->set_condition(combinationPredicate->id());
- *metric->mutable_dimensions_in_what() = CreateDimensions(
- android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, {1 /* uid */});
+ *metric->mutable_dimensions_in_what() =
+ CreateDimensions(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, {1 /* uid */});
*metric->mutable_dimensions_in_condition() = CreateAttributionUidAndTagDimensions(
android::util::SYNC_STATE_CHANGED, {Position::FIRST});
@@ -267,8 +267,8 @@
auto dimensionWhat = links->mutable_fields_in_what();
dimensionWhat->set_field(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
dimensionWhat->add_child()->set_field(1); // uid field.
- *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
- android::util::SYNC_STATE_CHANGED, {Position::FIRST});
+ *links->mutable_fields_in_condition() =
+ CreateAttributionUidDimensions(android::util::SYNC_STATE_CHANGED, {Position::FIRST});
return config;
}
@@ -279,18 +279,18 @@
auto config = CreateCountMetricWithLinkConfig();
int64_t bucketStartTimeNs = 10000000000;
int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
+ TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
auto processor = CreateStatsLogProcessor(bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- std::vector<AttributionNode> attributions1 =
- {CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(222, "GMSCoreModule2")};
+ std::vector<AttributionNode> attributions1 = {CreateAttribution(111, "App1"),
+ CreateAttribution(222, "GMSCoreModule1"),
+ CreateAttribution(222, "GMSCoreModule2")};
- std::vector<AttributionNode> attributions2 =
- {CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(555, "GMSCoreModule2")};
+ std::vector<AttributionNode> attributions2 = {CreateAttribution(333, "App2"),
+ CreateAttribution(222, "GMSCoreModule1"),
+ CreateAttribution(555, "GMSCoreModule2")};
std::vector<std::unique_ptr<LogEvent>> events;
@@ -311,26 +311,26 @@
events.push_back(CreateAppCrashEvent(777, bucketStartTimeNs + bucketSizeNs + 701));
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_ON, bucketStartTimeNs + 10));
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_OFF, bucketStartTimeNs + 100));
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_ON, bucketStartTimeNs + 202));
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_OFF, bucketStartTimeNs + bucketSizeNs + 700));
+ events.push_back(
+ CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, bucketStartTimeNs + 10));
+ events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
+ bucketStartTimeNs + 100));
+ events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
+ bucketStartTimeNs + 202));
+ events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
+ bucketStartTimeNs + bucketSizeNs + 700));
events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail", bucketStartTimeNs + 200));
- events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + bucketSizeNs + 300));
+ events.push_back(
+ CreateSyncEndEvent(attributions1, "ReadEmail", bucketStartTimeNs + bucketSizeNs + 300));
events.push_back(CreateSyncStartEvent(attributions1, "ReadDoc", bucketStartTimeNs + 400));
- events.push_back(CreateSyncEndEvent(attributions1, "ReadDoc",
- bucketStartTimeNs + bucketSizeNs - 1));
+ events.push_back(
+ CreateSyncEndEvent(attributions1, "ReadDoc", bucketStartTimeNs + bucketSizeNs - 1));
events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail", bucketStartTimeNs + 400));
- events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail",
- bucketStartTimeNs + bucketSizeNs + 600));
+ events.push_back(
+ CreateSyncEndEvent(attributions2, "ReadEmail", bucketStartTimeNs + bucketSizeNs + 600));
sortLogEventsByTimestamp(&events);
@@ -339,7 +339,10 @@
}
ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &reports);
+ vector<uint8_t> buffer;
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer);
+ EXPECT_TRUE(buffer.size() > 0);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
EXPECT_EQ(reports.reports_size(), 1);
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
@@ -363,8 +366,8 @@
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 111);
- ValidateAttributionUidAndTagDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 111, "App1");
+ ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
+ android::util::SYNC_STATE_CHANGED, 111, "App1");
EXPECT_EQ(data.bucket_info_size(), 1);
EXPECT_EQ(data.bucket_info(0).count(), 2);
EXPECT_EQ(data.bucket_info(0).start_bucket_nanos(), bucketStartTimeNs);
@@ -386,8 +389,8 @@
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 333);
- ValidateAttributionUidAndTagDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333, "App2");
+ ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
+ android::util::SYNC_STATE_CHANGED, 333, "App2");
EXPECT_EQ(data.bucket_info_size(), 2);
EXPECT_EQ(data.bucket_info(0).count(), 1);
EXPECT_EQ(data.bucket_info(0).start_bucket_nanos(), bucketStartTimeNs);
@@ -424,8 +427,8 @@
auto screenIsOffPredicate = CreateScreenIsOffPredicate();
auto isSyncingPredicate = CreateIsSyncingPredicate();
auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
- *syncDimension = CreateAttributionUidAndTagDimensions(
- android::util::SYNC_STATE_CHANGED, {Position::FIRST});
+ *syncDimension = CreateAttributionUidAndTagDimensions(android::util::SYNC_STATE_CHANGED,
+ {Position::FIRST});
syncDimension->add_child()->set_field(2 /* name field */);
*config.add_predicate() = inBatterySaverModePredicate;
@@ -449,26 +452,25 @@
} // namespace
-
TEST(DimensionInConditionE2eTest, TestDurationMetricNoLink) {
- for (auto aggregationType : { DurationMetric::SUM, DurationMetric::MAX_SPARSE}) {
+ for (auto aggregationType : {DurationMetric::SUM, DurationMetric::MAX_SPARSE}) {
ConfigKey cfgKey;
auto config = CreateDurationMetricConfigNoLink(aggregationType);
int64_t bucketStartTimeNs = 10000000000;
int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
+ TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
auto processor = CreateStatsLogProcessor(bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- std::vector<AttributionNode> attributions1 =
- {CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(222, "GMSCoreModule2")};
+ std::vector<AttributionNode> attributions1 = {CreateAttribution(111, "App1"),
+ CreateAttribution(222, "GMSCoreModule1"),
+ CreateAttribution(222, "GMSCoreModule2")};
- std::vector<AttributionNode> attributions2 =
- {CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(555, "GMSCoreModule2")};
+ std::vector<AttributionNode> attributions2 = {CreateAttribution(333, "App2"),
+ CreateAttribution(222, "GMSCoreModule1"),
+ CreateAttribution(555, "GMSCoreModule2")};
std::vector<std::unique_ptr<LogEvent>> events;
@@ -485,26 +487,26 @@
events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + bucketSizeNs + 870));
events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + bucketSizeNs + 900));
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_ON, bucketStartTimeNs + 10));
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_OFF, bucketStartTimeNs + 100));
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_ON, bucketStartTimeNs + 202));
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_OFF, bucketStartTimeNs + bucketSizeNs + 800));
+ events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
+ bucketStartTimeNs + 10));
+ events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
+ bucketStartTimeNs + 100));
+ events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
+ bucketStartTimeNs + 202));
+ events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
+ bucketStartTimeNs + bucketSizeNs + 800));
events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail", bucketStartTimeNs + 200));
events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + bucketSizeNs + 300));
+ bucketStartTimeNs + bucketSizeNs + 300));
events.push_back(CreateSyncStartEvent(attributions1, "ReadDoc", bucketStartTimeNs + 400));
- events.push_back(CreateSyncEndEvent(attributions1, "ReadDoc",
- bucketStartTimeNs + bucketSizeNs - 1));
+ events.push_back(
+ CreateSyncEndEvent(attributions1, "ReadDoc", bucketStartTimeNs + bucketSizeNs - 1));
events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail", bucketStartTimeNs + 401));
events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail",
- bucketStartTimeNs + bucketSizeNs + 700));
+ bucketStartTimeNs + bucketSizeNs + 700));
sortLogEventsByTimestamp(&events);
@@ -513,7 +515,10 @@
}
ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &reports);
+ vector<uint8_t> buffer;
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer);
+ EXPECT_TRUE(buffer.size() > 0);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
EXPECT_EQ(reports.reports_size(), 1);
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
@@ -534,8 +539,8 @@
data = metrics.data(1);
EXPECT_FALSE(data.dimensions_in_what().has_field());
- ValidateAttributionUidAndTagDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 111, "App1");
+ ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
+ android::util::SYNC_STATE_CHANGED, 111, "App1");
EXPECT_EQ(data.bucket_info_size(), 2);
EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 201 + bucketSizeNs - 600);
EXPECT_EQ(data.bucket_info(0).start_bucket_nanos(), bucketStartTimeNs);
@@ -546,8 +551,8 @@
data = metrics.data(2);
EXPECT_FALSE(data.dimensions_in_what().has_field());
- ValidateAttributionUidAndTagDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333, "App2");
+ ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
+ android::util::SYNC_STATE_CHANGED, 333, "App2");
EXPECT_EQ(data.bucket_info_size(), 2);
EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 401 + bucketSizeNs - 600);
EXPECT_EQ(data.bucket_info(0).start_bucket_nanos(), bucketStartTimeNs);
@@ -572,13 +577,13 @@
auto screenIsOffPredicate = CreateScreenIsOffPredicate();
auto isSyncingPredicate = CreateIsSyncingPredicate();
auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
- *syncDimension = CreateAttributionUidAndTagDimensions(
- android::util::SYNC_STATE_CHANGED, {Position::FIRST});
+ *syncDimension = CreateAttributionUidAndTagDimensions(android::util::SYNC_STATE_CHANGED,
+ {Position::FIRST});
syncDimension->add_child()->set_field(2 /* name field */);
auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
*isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
- CreateDimensions(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */ });
+ CreateDimensions(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */});
*config.add_predicate() = screenIsOffPredicate;
*config.add_predicate() = isSyncingPredicate;
@@ -594,8 +599,8 @@
metric->set_id(StringToId("AppInBackgroundMetric"));
metric->set_what(isInBackgroundPredicate.id());
metric->set_condition(combinationPredicate->id());
- *metric->mutable_dimensions_in_what() = CreateDimensions(
- android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */ });
+ *metric->mutable_dimensions_in_what() =
+ CreateDimensions(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */});
*metric->mutable_dimensions_in_condition() = CreateAttributionUidAndTagDimensions(
android::util::SYNC_STATE_CHANGED, {Position::FIRST});
@@ -605,32 +610,32 @@
auto dimensionWhat = links->mutable_fields_in_what();
dimensionWhat->set_field(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
dimensionWhat->add_child()->set_field(1); // uid field.
- *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
- android::util::SYNC_STATE_CHANGED, {Position::FIRST});
+ *links->mutable_fields_in_condition() =
+ CreateAttributionUidDimensions(android::util::SYNC_STATE_CHANGED, {Position::FIRST});
return config;
}
} // namespace
TEST(DimensionInConditionE2eTest, TestDurationMetricWithLink) {
- for (auto aggregationType : { DurationMetric::SUM, DurationMetric::MAX_SPARSE}) {
+ for (auto aggregationType : {DurationMetric::SUM, DurationMetric::MAX_SPARSE}) {
ConfigKey cfgKey;
auto config = CreateDurationMetricConfigWithLink(aggregationType);
int64_t bucketStartTimeNs = 10000000000;
int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
+ TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
auto processor = CreateStatsLogProcessor(bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- std::vector<AttributionNode> attributions1 =
- {CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(222, "GMSCoreModule2")};
+ std::vector<AttributionNode> attributions1 = {CreateAttribution(111, "App1"),
+ CreateAttribution(222, "GMSCoreModule1"),
+ CreateAttribution(222, "GMSCoreModule2")};
- std::vector<AttributionNode> attributions2 =
- {CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(555, "GMSCoreModule2")};
+ std::vector<AttributionNode> attributions2 = {CreateAttribution(333, "App2"),
+ CreateAttribution(222, "GMSCoreModule1"),
+ CreateAttribution(555, "GMSCoreModule2")};
std::vector<std::unique_ptr<LogEvent>> events;
@@ -643,26 +648,26 @@
events.push_back(CreateMoveToBackgroundEvent(333, bucketStartTimeNs + 399));
events.push_back(CreateMoveToForegroundEvent(333, bucketStartTimeNs + bucketSizeNs + 800));
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_ON, bucketStartTimeNs + 10));
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_OFF, bucketStartTimeNs + 100));
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_ON, bucketStartTimeNs + 202));
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_OFF, bucketStartTimeNs + bucketSizeNs + 801));
+ events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
+ bucketStartTimeNs + 10));
+ events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
+ bucketStartTimeNs + 100));
+ events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
+ bucketStartTimeNs + 202));
+ events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
+ bucketStartTimeNs + bucketSizeNs + 801));
events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail", bucketStartTimeNs + 200));
events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + bucketSizeNs + 300));
+ bucketStartTimeNs + bucketSizeNs + 300));
events.push_back(CreateSyncStartEvent(attributions1, "ReadDoc", bucketStartTimeNs + 400));
- events.push_back(CreateSyncEndEvent(attributions1, "ReadDoc",
- bucketStartTimeNs + bucketSizeNs - 1));
+ events.push_back(
+ CreateSyncEndEvent(attributions1, "ReadDoc", bucketStartTimeNs + bucketSizeNs - 1));
events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail", bucketStartTimeNs + 401));
events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail",
- bucketStartTimeNs + bucketSizeNs + 700));
+ bucketStartTimeNs + bucketSizeNs + 700));
sortLogEventsByTimestamp(&events);
@@ -671,7 +676,10 @@
}
ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &reports);
+ vector<uint8_t> buffer;
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer);
+ EXPECT_TRUE(buffer.size() > 0);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
EXPECT_EQ(reports.reports_size(), 1);
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
@@ -691,8 +699,8 @@
data = metrics.data(1);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 111);
- ValidateAttributionUidAndTagDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 111, "App1");
+ ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
+ android::util::SYNC_STATE_CHANGED, 111, "App1");
EXPECT_EQ(data.bucket_info_size(), 2);
EXPECT_EQ(data.bucket_info(0).duration_nanos(), bucketSizeNs - 201);
EXPECT_EQ(data.bucket_info(0).start_bucket_nanos(), bucketStartTimeNs);
@@ -704,8 +712,8 @@
data = metrics.data(2);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 333);
- ValidateAttributionUidAndTagDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333, "App2");
+ ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
+ android::util::SYNC_STATE_CHANGED, 333, "App2");
EXPECT_EQ(data.bucket_info_size(), 2);
EXPECT_EQ(data.bucket_info(0).duration_nanos(), bucketSizeNs - 401);
EXPECT_EQ(data.bucket_info(0).start_bucket_nanos(), bucketStartTimeNs);
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_test.cpp
index a80fdc5..674d810 100644
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_test.cpp
@@ -140,7 +140,10 @@
processor->OnLogEvent(event.get());
}
ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 3 * bucketSizeNs, &reports);
+ vector<uint8_t> buffer;
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 3 * bucketSizeNs, &buffer);
+ EXPECT_TRUE(buffer.size() > 0);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
EXPECT_EQ(reports.reports_size(), 1);
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
diff --git a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
index 233031c..d005181 100644
--- a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
@@ -95,8 +95,10 @@
}
} // namespace
-
-TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks) {
+// If we want to test multiple dump data, we must do it in separate tests, because in the e2e tests,
+// we should use the real API which will clear the data after dump data is called.
+// TODO: better refactor the code so that the tests are not so verbose.
+TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks1) {
auto config = CreateStatsdConfig();
uint64_t bucketStartTimeNs = 10000000000;
uint64_t bucketSizeNs =
@@ -195,7 +197,10 @@
processor->OnLogEvent(event.get());
}
ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, &reports);
+ vector<uint8_t> buffer;
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, &buffer);
+ EXPECT_TRUE(buffer.size() > 0);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
EXPECT_EQ(reports.reports_size(), 1);
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data_size(), 1);
@@ -208,16 +213,115 @@
// Uid field.
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), appUid);
+}
- reports.Clear();
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &reports);
+TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks2) {
+ auto config = CreateStatsdConfig();
+ uint64_t bucketStartTimeNs = 10000000000;
+ uint64_t bucketSizeNs =
+ TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
+
+ ConfigKey cfgKey;
+ auto processor = CreateStatsLogProcessor(bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
+ EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+ EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
+
+ int appUid = 123;
+ auto crashEvent1 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 1);
+ auto crashEvent2 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 201);
+ auto crashEvent3 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 2 * bucketSizeNs - 101);
+
+ auto crashEvent4 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 51);
+ auto crashEvent5 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 299);
+ auto crashEvent6 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 2001);
+
+ auto crashEvent7 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 16);
+ auto crashEvent8 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 249);
+
+ auto crashEvent9 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 351);
+ auto crashEvent10 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 2 * bucketSizeNs - 2);
+
+ auto screenTurnedOnEvent = CreateScreenStateChangedEvent(
+ android::view::DisplayStateEnum::DISPLAY_STATE_ON, bucketStartTimeNs + 2);
+ auto screenTurnedOffEvent = CreateScreenStateChangedEvent(
+ android::view::DisplayStateEnum::DISPLAY_STATE_OFF, bucketStartTimeNs + 200);
+ auto screenTurnedOnEvent2 =
+ CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
+ bucketStartTimeNs + 2 * bucketSizeNs - 100);
+
+ std::vector<AttributionNode> attributions = {CreateAttribution(appUid, "App1"),
+ CreateAttribution(appUid + 1, "GMSCoreModule1")};
+ auto syncOnEvent1 = CreateSyncStartEvent(attributions, "ReadEmail", bucketStartTimeNs + 50);
+ auto syncOffEvent1 =
+ CreateSyncEndEvent(attributions, "ReadEmail", bucketStartTimeNs + bucketSizeNs + 300);
+ auto syncOnEvent2 =
+ CreateSyncStartEvent(attributions, "ReadDoc", bucketStartTimeNs + bucketSizeNs + 2000);
+
+ auto moveToBackgroundEvent1 = CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + 15);
+ auto moveToForegroundEvent1 =
+ CreateMoveToForegroundEvent(appUid, bucketStartTimeNs + bucketSizeNs + 250);
+
+ auto moveToBackgroundEvent2 =
+ CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + bucketSizeNs + 350);
+ auto moveToForegroundEvent2 =
+ CreateMoveToForegroundEvent(appUid, bucketStartTimeNs + 2 * bucketSizeNs - 1);
+
+ /*
+ bucket #1 bucket #2
+
+
+ | | | | | | | | | | (crashEvents)
+ |-------------------------------------|-----------------------------------|---------
+
+ | | (MoveToBkground)
+
+ | | (MoveToForeground)
+
+ | | (SyncIsOn)
+ | (SyncIsOff)
+ | | (ScreenIsOn)
+ | (ScreenIsOff)
+ */
+ std::vector<std::unique_ptr<LogEvent>> events;
+ events.push_back(std::move(crashEvent1));
+ events.push_back(std::move(crashEvent2));
+ events.push_back(std::move(crashEvent3));
+ events.push_back(std::move(crashEvent4));
+ events.push_back(std::move(crashEvent5));
+ events.push_back(std::move(crashEvent6));
+ events.push_back(std::move(crashEvent7));
+ events.push_back(std::move(crashEvent8));
+ events.push_back(std::move(crashEvent9));
+ events.push_back(std::move(crashEvent10));
+ events.push_back(std::move(screenTurnedOnEvent));
+ events.push_back(std::move(screenTurnedOffEvent));
+ events.push_back(std::move(screenTurnedOnEvent2));
+ events.push_back(std::move(syncOnEvent1));
+ events.push_back(std::move(syncOffEvent1));
+ events.push_back(std::move(syncOnEvent2));
+ events.push_back(std::move(moveToBackgroundEvent1));
+ events.push_back(std::move(moveToForegroundEvent1));
+ events.push_back(std::move(moveToBackgroundEvent2));
+ events.push_back(std::move(moveToForegroundEvent2));
+
+ sortLogEventsByTimestamp(&events);
+
+ for (const auto& event : events) {
+ processor->OnLogEvent(event.get());
+ }
+ ConfigMetricsReportList reports;
+ vector<uint8_t> buffer;
+
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer);
+ EXPECT_TRUE(buffer.size() > 0);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
EXPECT_EQ(reports.reports_size(), 1);
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data_size(), 1);
EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info_size(), 2);
EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(0).count(), 1);
EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(1).count(), 3);
- data = reports.reports(0).metrics(0).count_metrics().data(0);
+ auto data = reports.reports(0).metrics(0).count_metrics().data(0);
// Validate dimension value.
EXPECT_EQ(data.dimensions_in_what().field(),
android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
diff --git a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
index a99dbe8..3b25694b 100644
--- a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
@@ -114,7 +114,7 @@
} // namespace
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration) {
+TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1) {
ConfigKey cfgKey;
auto config = CreateStatsdConfig(DurationMetric::SUM);
uint64_t bucketStartTimeNs = 10000000000;
@@ -124,8 +124,11 @@
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
FeedEvents(config, processor);
+ vector<uint8_t> buffer;
ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, &reports);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, &buffer);
+ EXPECT_TRUE(buffer.size() > 0);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
EXPECT_EQ(reports.reports_size(), 1);
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
@@ -142,15 +145,30 @@
// The wakelock holding interval starts from the screen off event and to the end of the 1st
// bucket.
EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(), bucketSizeNs - 200);
+}
- reports.Clear();
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &reports);
+TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2) {
+ ConfigKey cfgKey;
+ auto config = CreateStatsdConfig(DurationMetric::SUM);
+ uint64_t bucketStartTimeNs = 10000000000;
+ uint64_t bucketSizeNs =
+ TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
+ auto processor = CreateStatsLogProcessor(bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
+ EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+ EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
+ FeedEvents(config, processor);
+ vector<uint8_t> buffer;
+ ConfigMetricsReportList reports;
+
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer);
+ EXPECT_TRUE(buffer.size() > 0);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
EXPECT_EQ(reports.reports_size(), 1);
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
// Dump the report after the end of 2nd bucket.
EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
- data = reports.reports(0).metrics(0).duration_metrics().data(0);
+ auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
// Validate dimension value.
ValidateAttributionUidDimension(data.dimensions_in_what(),
android::util::WAKELOCK_STATE_CHANGED, 111);
@@ -162,6 +180,19 @@
// The wakelock holding interval in the 2nd bucket starts at the beginning of the bucket and
// ends at the second screen on event.
EXPECT_EQ((unsigned long long)data.bucket_info(1).duration_nanos(), 500UL);
+}
+TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration3) {
+ ConfigKey cfgKey;
+ auto config = CreateStatsdConfig(DurationMetric::SUM);
+ uint64_t bucketStartTimeNs = 10000000000;
+ uint64_t bucketSizeNs =
+ TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
+ auto processor = CreateStatsLogProcessor(bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
+ EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+ EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
+ FeedEvents(config, processor);
+ vector<uint8_t> buffer;
+ ConfigMetricsReportList reports;
std::vector<std::unique_ptr<LogEvent>> events;
events.push_back(
@@ -175,13 +206,15 @@
for (const auto& event : events) {
processor->OnLogEvent(event.get());
}
- reports.Clear();
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, &reports);
+
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, &buffer);
+ EXPECT_TRUE(buffer.size() > 0);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
EXPECT_EQ(reports.reports_size(), 1);
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 6);
- data = reports.reports(0).metrics(0).duration_metrics().data(0);
+ auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
ValidateAttributionUidDimension(data.dimensions_in_what(),
android::util::WAKELOCK_STATE_CHANGED, 111);
// The last wakelock holding spans 4 buckets.
@@ -191,7 +224,7 @@
EXPECT_EQ((unsigned long long)data.bucket_info(5).duration_nanos(), 100UL);
}
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration) {
+TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration1) {
ConfigKey cfgKey;
auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
uint64_t bucketStartTimeNs = 10000000000;
@@ -202,15 +235,35 @@
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
FeedEvents(config, processor);
ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, &reports);
+ vector<uint8_t> buffer;
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, &buffer);
+ EXPECT_TRUE(buffer.size() > 0);
+
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
EXPECT_EQ(reports.reports_size(), 1);
- EXPECT_EQ(reports.reports(0).metrics_size(), 1);
- // Nothing has ended in the first bucket.
- EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 0);
- reports.Clear();
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &reports);
+ // When using ProtoOutputStream, if nothing written to a sub msg, it won't be treated as
+ // one. It was previsouly 1 because we had a fake onDumpReport which calls add_metric() by
+ // itself.
+ EXPECT_EQ(0, reports.reports(0).metrics_size());
+}
+
+TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration2) {
+ ConfigKey cfgKey;
+ auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
+ uint64_t bucketStartTimeNs = 10000000000;
+ uint64_t bucketSizeNs =
+ TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
+ auto processor = CreateStatsLogProcessor(bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
+ EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+ EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
+ FeedEvents(config, processor);
+ ConfigMetricsReportList reports;
+ vector<uint8_t> buffer;
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer);
+ EXPECT_TRUE(buffer.size() > 0);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
EXPECT_EQ(reports.reports_size(), 1);
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
@@ -222,6 +275,20 @@
android::util::WAKELOCK_STATE_CHANGED, 111);
// The max is acquire event for wl1 to screen off start.
EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(), bucketSizeNs + 2 - 200);
+}
+
+TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration3) {
+ ConfigKey cfgKey;
+ auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
+ uint64_t bucketStartTimeNs = 10000000000;
+ uint64_t bucketSizeNs =
+ TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
+ auto processor = CreateStatsLogProcessor(bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
+ EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+ EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
+ FeedEvents(config, processor);
+ ConfigMetricsReportList reports;
+ vector<uint8_t> buffer;
std::vector<std::unique_ptr<LogEvent>> events;
events.push_back(
@@ -235,13 +302,15 @@
for (const auto& event : events) {
processor->OnLogEvent(event.get());
}
- reports.Clear();
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, &reports);
+
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, &buffer);
+ EXPECT_TRUE(buffer.size() > 0);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
EXPECT_EQ(reports.reports_size(), 1);
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
- data = reports.reports(0).metrics(0).duration_metrics().data(0);
+ auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
ValidateAttributionUidDimension(data.dimensions_in_what(),
android::util::WAKELOCK_STATE_CHANGED, 111);
// The last wakelock holding spans 4 buckets.
diff --git a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
index 87a1079..1e71b73 100644
--- a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
@@ -13,7 +13,6 @@
// limitations under the License.
#include "src/metrics/CountMetricProducer.h"
-#include "src/dimension.h"
#include "src/stats_log_util.h"
#include "metrics_test_helper.h"
#include "tests/statsd_test_util.h"
diff --git a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
index 3deab37..8246268 100644
--- a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
@@ -13,7 +13,6 @@
// limitations under the License.
#include "src/metrics/EventMetricProducer.h"
-#include "src/dimension.h"
#include "metrics_test_helper.h"
#include "tests/statsd_test_util.h"
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index 470d4d0..26f7c26 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -80,9 +80,10 @@
gaugeProducer.onDataPulled(allData);
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
auto it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
- EXPECT_EQ(10, it->second.value_int());
+ EXPECT_EQ(INT, it->mValue.getType());
+ EXPECT_EQ(10, it->mValue.int_value);
it++;
- EXPECT_EQ(11, it->second.value_int());
+ EXPECT_EQ(11, it->mValue.int_value);
EXPECT_EQ(0UL, gaugeProducer.mPastBuckets.size());
allData.clear();
@@ -96,16 +97,20 @@
gaugeProducer.onDataPulled(allData);
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
- EXPECT_EQ(24, it->second.value_int());
+ EXPECT_EQ(INT, it->mValue.getType());
+ EXPECT_EQ(24, it->mValue.int_value);
it++;
- EXPECT_EQ(25, it->second.value_int());
+ EXPECT_EQ(INT, it->mValue.getType());
+ EXPECT_EQ(25, it->mValue.int_value);
// One dimension.
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.begin()->second.size());
it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.front().mFields->begin();
- EXPECT_EQ(10L, it->second.value_int());
+ EXPECT_EQ(INT, it->mValue.getType());
+ EXPECT_EQ(10L, it->mValue.int_value);
it++;
- EXPECT_EQ(11L, it->second.value_int());
+ EXPECT_EQ(INT, it->mValue.getType());
+ EXPECT_EQ(11L, it->mValue.int_value);
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.begin()->second.back().mBucketNum);
gaugeProducer.flushIfNeededLocked(bucket4StartTimeNs);
@@ -114,9 +119,11 @@
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.front().mFields->begin();
- EXPECT_EQ(24L, it->second.value_int());
+ EXPECT_EQ(INT, it->mValue.getType());
+ EXPECT_EQ(24L, it->mValue.int_value);
it++;
- EXPECT_EQ(25L, it->second.value_int());
+ EXPECT_EQ(INT, it->mValue.getType());
+ EXPECT_EQ(25L, it->mValue.int_value);
EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.back().mBucketNum);
}
@@ -230,7 +237,7 @@
EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
->second.front()
.mFields->begin()
- ->second.value_int());
+ ->mValue.int_value);
gaugeProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
@@ -240,7 +247,7 @@
EXPECT_EQ(2, gaugeProducer.mCurrentSlicedBucket->begin()
->second.front()
.mFields->begin()
- ->second.value_int());
+ ->mValue.int_value);
allData.clear();
event = make_shared<LogEvent>(tagId, bucketStartTimeNs + bucketSizeNs + 1);
@@ -254,7 +261,7 @@
EXPECT_EQ(3, gaugeProducer.mCurrentSlicedBucket->begin()
->second.front()
.mFields->begin()
- ->second.value_int());
+ ->mValue.int_value);
}
TEST(GaugeMetricProducerTest, TestWithCondition) {
@@ -288,9 +295,10 @@
gaugeProducer.onConditionChanged(true, bucketStartTimeNs + 8);
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(100,
- gaugeProducer.mCurrentSlicedBucket->begin()->
- second.front().mFields->begin()->second.value_int());
+ EXPECT_EQ(100, gaugeProducer.mCurrentSlicedBucket->begin()
+ ->second.front()
+ .mFields->begin()
+ ->mValue.int_value);
EXPECT_EQ(0UL, gaugeProducer.mPastBuckets.size());
vector<shared_ptr<LogEvent>> allData;
@@ -303,19 +311,26 @@
gaugeProducer.onDataPulled(allData);
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(110,
- gaugeProducer.mCurrentSlicedBucket->begin()->
- second.front().mFields->begin()->second.value_int());
+ EXPECT_EQ(110, gaugeProducer.mCurrentSlicedBucket->begin()
+ ->second.front()
+ .mFields->begin()
+ ->mValue.int_value);
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- EXPECT_EQ(100, gaugeProducer.mPastBuckets.begin()->second.back()
- .mGaugeAtoms.front().mFields->begin()->second.value_int());
+ EXPECT_EQ(100, gaugeProducer.mPastBuckets.begin()
+ ->second.back()
+ .mGaugeAtoms.front()
+ .mFields->begin()
+ ->mValue.int_value);
gaugeProducer.onConditionChanged(false, bucket2StartTimeNs + 10);
gaugeProducer.flushIfNeededLocked(bucket3StartTimeNs + 10);
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(110L, gaugeProducer.mPastBuckets.begin()->second.back()
- .mGaugeAtoms.front().mFields->begin()->second.value_int());
+ EXPECT_EQ(110L, gaugeProducer.mPastBuckets.begin()
+ ->second.back()
+ .mGaugeAtoms.front()
+ .mFields->begin()
+ ->mValue.int_value);
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.begin()->second.back().mBucketNum);
}
@@ -353,9 +368,10 @@
gaugeProducer.onDataPulled({event1});
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(13L,
- gaugeProducer.mCurrentSlicedBucket->begin()->
- second.front().mFields->begin()->second.value_int());
+ EXPECT_EQ(13L, gaugeProducer.mCurrentSlicedBucket->begin()
+ ->second.front()
+ .mFields->begin()
+ ->mValue.int_value);
EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
std::shared_ptr<LogEvent> event2 =
@@ -366,9 +382,10 @@
gaugeProducer.onDataPulled({event2});
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(15L,
- gaugeProducer.mCurrentSlicedBucket->begin()->
- second.front().mFields->begin()->second.value_int());
+ EXPECT_EQ(15L, gaugeProducer.mCurrentSlicedBucket->begin()
+ ->second.front()
+ .mFields->begin()
+ ->mValue.int_value);
EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
event2->GetTimestampNs() / NS_PER_SEC + refPeriodSec);
@@ -380,9 +397,10 @@
gaugeProducer.onDataPulled({event3});
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(26L,
- gaugeProducer.mCurrentSlicedBucket->begin()->
- second.front().mFields->begin()->second.value_int());
+ EXPECT_EQ(26L, gaugeProducer.mCurrentSlicedBucket->begin()
+ ->second.front()
+ .mFields->begin()
+ ->mValue.int_value);
EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
event2->GetTimestampNs() / NS_PER_SEC + refPeriodSec);
diff --git a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
index 2658e4e..3397f14 100644
--- a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
+++ b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
@@ -53,7 +53,8 @@
const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
- FieldMatcher dimensionInCondition;
+ vector<Matcher> dimensionInCondition;
+
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
@@ -89,7 +90,7 @@
const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
- FieldMatcher dimensionInCondition;
+ vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
@@ -126,7 +127,7 @@
const std::vector<HashableDimensionKey> conditionKey = {getMockedDimensionKey(TagId, 4, "1")};
const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
- FieldMatcher dimensionInCondition;
+ vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
@@ -168,7 +169,7 @@
const std::vector<HashableDimensionKey> conditionKey = {getMockedDimensionKey(TagId, 4, "1")};
const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
- FieldMatcher dimensionInCondition;
+ vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
@@ -206,7 +207,7 @@
const std::vector<HashableDimensionKey> conditionKey = {getMockedDimensionKey(TagId, 4, "1")};
const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
- FieldMatcher dimensionInCondition;
+ vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
ConditionKey conditionKey1;
diff --git a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
index 4b579b1..293b1a8 100644
--- a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
+++ b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
@@ -52,7 +52,7 @@
{getMockedDimensionKey(TagId, 1, "maps")};
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- FieldMatcher dimensionInCondition;
+ vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
@@ -88,7 +88,7 @@
{getMockedDimensionKey(TagId, 1, "maps")};
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- FieldMatcher dimensionInCondition;
+ vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
@@ -122,7 +122,7 @@
{getMockedDimensionKey(TagId, 1, "maps")};
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- FieldMatcher dimensionInCondition;
+ vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
@@ -155,7 +155,7 @@
{getMockedDimensionKey(TagId, 1, "maps")};
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- FieldMatcher dimensionInCondition;
+ vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
@@ -197,7 +197,7 @@
{getMockedDimensionKey(TagId, 1, "maps")};
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- FieldMatcher dimensionInCondition;
+ vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
ConditionKey key1;
@@ -238,7 +238,7 @@
{getMockedDimensionKey(TagId, 1, "maps")};
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- FieldMatcher dimensionInCondition;
+ vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
ConditionKey key1;
@@ -283,7 +283,7 @@
{getMockedDimensionKey(TagId, 1, "maps")};
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- FieldMatcher dimensionInCondition;
+ vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
ConditionKey key1;
@@ -326,7 +326,7 @@
{getMockedDimensionKey(TagId, 1, "maps")};
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- FieldMatcher dimensionInCondition;
+ vector<Matcher> dimensionInCondition;
Alert alert;
alert.set_id(101);
alert.set_metric_id(1);
@@ -395,7 +395,7 @@
const std::vector<HashableDimensionKey> kConditionKey1 = {getMockedDimensionKey(TagId, 1, "maps")};
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- FieldMatcher dimensionInCondition;
+ vector<Matcher> dimensionInCondition;
Alert alert;
alert.set_id(101);
alert.set_metric_id(1);
@@ -446,7 +446,7 @@
{getMockedDimensionKey(TagId, 1, "maps")};
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- FieldMatcher dimensionInCondition;
+ vector<Matcher> dimensionInCondition;
Alert alert;
alert.set_id(101);
alert.set_metric_id(1);
diff --git a/cmds/statsd/tests/metrics/metrics_test_helper.cpp b/cmds/statsd/tests/metrics/metrics_test_helper.cpp
index ab9345a..7b9c0d6 100644
--- a/cmds/statsd/tests/metrics/metrics_test_helper.cpp
+++ b/cmds/statsd/tests/metrics/metrics_test_helper.cpp
@@ -19,20 +19,26 @@
namespace statsd {
HashableDimensionKey getMockedDimensionKey(int tagId, int key, string value) {
- DimensionsValue dimensionsValue;
- dimensionsValue.set_field(tagId);
- dimensionsValue.mutable_value_tuple()->add_dimensions_value()->set_field(key);
- dimensionsValue.mutable_value_tuple()->mutable_dimensions_value(0)->set_value_str(value);
- return HashableDimensionKey(dimensionsValue);
+ HashableDimensionKey dimension;
+ int pos[] = {key, 0, 0};
+ dimension.addValue(FieldValue(Field(tagId, pos, 0), Value(value)));
+
+ return dimension;
}
MetricDimensionKey getMockedMetricDimensionKey(int tagId, int key, string value) {
- DimensionsValue dimensionsValue;
- dimensionsValue.set_field(tagId);
- dimensionsValue.mutable_value_tuple()->add_dimensions_value()->set_field(key);
- dimensionsValue.mutable_value_tuple()->mutable_dimensions_value(0)->set_value_str(value);
- return MetricDimensionKey(HashableDimensionKey(dimensionsValue), DEFAULT_DIMENSION_KEY);
+ return MetricDimensionKey(getMockedDimensionKey(tagId, key, value), DEFAULT_DIMENSION_KEY);
}
+
+void buildSimpleAtomFieldMatcher(const int tagId, FieldMatcher* matcher) {
+ matcher->set_field(tagId);
+}
+
+void buildSimpleAtomFieldMatcher(const int tagId, const int fieldNum, FieldMatcher* matcher) {
+ matcher->set_field(tagId);
+ matcher->add_child()->set_field(fieldNum);
+}
+
} // namespace statsd
} // namespace os
} // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/tests/metrics/metrics_test_helper.h b/cmds/statsd/tests/metrics/metrics_test_helper.h
index b48de54..a01de63 100644
--- a/cmds/statsd/tests/metrics/metrics_test_helper.h
+++ b/cmds/statsd/tests/metrics/metrics_test_helper.h
@@ -26,12 +26,10 @@
class MockConditionWizard : public ConditionWizard {
public:
- MOCK_METHOD4(
- query,
- ConditionState(const int conditionIndex,
- const ConditionKey& conditionParameters,
- const FieldMatcher& dimensionFields,
- std::unordered_set<HashableDimensionKey> *dimensionKeySet));
+ MOCK_METHOD4(query,
+ ConditionState(const int conditionIndex, const ConditionKey& conditionParameters,
+ const vector<Matcher>& dimensionFields,
+ std::unordered_set<HashableDimensionKey>* dimensionKeySet));
};
class MockStatsPullerManager : public StatsPullerManager {
@@ -49,6 +47,10 @@
HashableDimensionKey getMockedDimensionKey(int tagId, int key, std::string value);
MetricDimensionKey getMockedMetricDimensionKey(int tagId, int key, std::string value);
+// Utils to build FieldMatcher proto for simple one-depth atoms.
+void buildSimpleAtomFieldMatcher(const int tagId, const int atomFieldNum, FieldMatcher* matcher);
+void buildSimpleAtomFieldMatcher(const int tagId, FieldMatcher* matcher);
+
} // namespace statsd
} // namespace os
} // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp
index 13055cb..d3a89617 100644
--- a/cmds/statsd/tests/statsd_test_util.cpp
+++ b/cmds/statsd/tests/statsd_test_util.cpp
@@ -186,7 +186,7 @@
Predicate CreateScreenIsOffPredicate() {
Predicate predicate;
- predicate.set_id(StringToId("ScreenIsOff"));
+ predicate.set_id(1111123);
predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOff"));
predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOn"));
return predicate;
@@ -202,7 +202,7 @@
Predicate CreateIsSyncingPredicate() {
Predicate predicate;
- predicate.set_id(StringToId("IsSyncing"));
+ predicate.set_id(33333333333333);
predicate.mutable_simple_predicate()->set_start(StringToId("SyncStart"));
predicate.mutable_simple_predicate()->set_stop(StringToId("SyncEnd"));
return predicate;
@@ -461,6 +461,93 @@
.value_tuple().dimensions_value(1).value_str(), tag);
}
+bool EqualsTo(const DimensionsValue& s1, const DimensionsValue& s2) {
+ if (s1.field() != s2.field()) {
+ return false;
+ }
+ if (s1.value_case() != s2.value_case()) {
+ return false;
+ }
+ switch (s1.value_case()) {
+ case DimensionsValue::ValueCase::kValueStr:
+ return (s1.value_str() == s2.value_str());
+ case DimensionsValue::ValueCase::kValueInt:
+ return s1.value_int() == s2.value_int();
+ case DimensionsValue::ValueCase::kValueLong:
+ return s1.value_long() == s2.value_long();
+ case DimensionsValue::ValueCase::kValueBool:
+ return s1.value_bool() == s2.value_bool();
+ case DimensionsValue::ValueCase::kValueFloat:
+ return s1.value_float() == s2.value_float();
+ case DimensionsValue::ValueCase::kValueTuple: {
+ if (s1.value_tuple().dimensions_value_size() !=
+ s2.value_tuple().dimensions_value_size()) {
+ return false;
+ }
+ bool allMatched = true;
+ for (int i = 0; allMatched && i < s1.value_tuple().dimensions_value_size(); ++i) {
+ allMatched &= EqualsTo(s1.value_tuple().dimensions_value(i),
+ s2.value_tuple().dimensions_value(i));
+ }
+ return allMatched;
+ }
+ case DimensionsValue::ValueCase::VALUE_NOT_SET:
+ default:
+ return true;
+ }
+}
+
+bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2) {
+ if (s1.field() != s2.field()) {
+ return s1.field() < s2.field();
+ }
+ if (s1.value_case() != s2.value_case()) {
+ return s1.value_case() < s2.value_case();
+ }
+ switch (s1.value_case()) {
+ case DimensionsValue::ValueCase::kValueStr:
+ return s1.value_str() < s2.value_str();
+ case DimensionsValue::ValueCase::kValueInt:
+ return s1.value_int() < s2.value_int();
+ case DimensionsValue::ValueCase::kValueLong:
+ return s1.value_long() < s2.value_long();
+ case DimensionsValue::ValueCase::kValueBool:
+ return (int)s1.value_bool() < (int)s2.value_bool();
+ case DimensionsValue::ValueCase::kValueFloat:
+ return s1.value_float() < s2.value_float();
+ case DimensionsValue::ValueCase::kValueTuple: {
+ if (s1.value_tuple().dimensions_value_size() !=
+ s2.value_tuple().dimensions_value_size()) {
+ return s1.value_tuple().dimensions_value_size() <
+ s2.value_tuple().dimensions_value_size();
+ }
+ for (int i = 0; i < s1.value_tuple().dimensions_value_size(); ++i) {
+ if (EqualsTo(s1.value_tuple().dimensions_value(i),
+ s2.value_tuple().dimensions_value(i))) {
+ continue;
+ } else {
+ return LessThan(s1.value_tuple().dimensions_value(i),
+ s2.value_tuple().dimensions_value(i));
+ }
+ }
+ return false;
+ }
+ case DimensionsValue::ValueCase::VALUE_NOT_SET:
+ default:
+ return false;
+ }
+}
+
+bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2) {
+ if (LessThan(s1.dimInWhat, s2.dimInWhat)) {
+ return true;
+ } else if (LessThan(s2.dimInWhat, s1.dimInWhat)) {
+ return false;
+ }
+
+ return LessThan(s1.dimInCondition, s2.dimInCondition);
+}
+
} // namespace statsd
} // namespace os
} // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h
index 6638893..5d83ed7 100644
--- a/cmds/statsd/tests/statsd_test_util.h
+++ b/cmds/statsd/tests/statsd_test_util.h
@@ -159,14 +159,30 @@
void ValidateAttributionUidAndTagDimension(
const DimensionsValue& value, int atomId, int uid, const std::string& tag);
+struct DimensionsPair {
+ DimensionsPair(DimensionsValue m1, DimensionsValue m2) : dimInWhat(m1), dimInCondition(m2){};
+
+ DimensionsValue dimInWhat;
+ DimensionsValue dimInCondition;
+};
+
+bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2);
+bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2);
+
+struct DimensionCompare {
+ bool operator()(const DimensionsPair& s1, const DimensionsPair& s2) const {
+ return LessThan(s1, s2);
+ }
+};
+
template <typename T>
void sortMetricDataByDimensionsValue(const T& metricData, T* sortedMetricData) {
- std::map<MetricDimensionKey, int> dimensionIndexMap;
+ std::map<DimensionsPair, int, DimensionCompare> dimensionIndexMap;
for (int i = 0; i < metricData.data_size(); ++i) {
- dimensionIndexMap.insert(std::make_pair(
- MetricDimensionKey(HashableDimensionKey(metricData.data(i).dimensions_in_what()),
- HashableDimensionKey(metricData.data(i).dimensions_in_condition())),
- i));
+ dimensionIndexMap.insert(
+ std::make_pair(DimensionsPair(metricData.data(i).dimensions_in_what(),
+ metricData.data(i).dimensions_in_condition()),
+ i));
}
for (const auto& itr : dimensionIndexMap) {
*sortedMetricData->add_data() = metricData.data(itr.second);
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 7b70f59..b822f2c 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -1,7 +1,11 @@
Landroid/accounts/AccountManager;->mContext:Landroid/content/Context;
+Landroid/accounts/IAccountManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accounts/IAccountManager;
+Landroid/accounts/IAccountManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/animation/LayoutTransition;->cancel()V
Landroid/animation/ValueAnimator;->animateValue(F)V
Landroid/animation/ValueAnimator;->getDurationScale()F
Landroid/animation/ValueAnimator;->sDurationScale:F
+Landroid/animation/ValueAnimator;->setDurationScale(F)V
Landroid/app/Activity;->convertFromTranslucent()V
Landroid/app/Activity;->convertToTranslucent(Landroid/app/Activity$TranslucentConversionListener;Landroid/app/ActivityOptions;)Z
Landroid/app/Activity;->getActivityOptions()Landroid/app/ActivityOptions;
@@ -12,6 +16,8 @@
Landroid/app/ActivityManager;->forceStopPackage(Ljava/lang/String;)V
Landroid/app/ActivityManager;->getCurrentUser()I
Landroid/app/ActivityManager;->getPackageImportance(Ljava/lang/String;)I
+Landroid/app/ActivityManager;->getService()Landroid/app/IActivityManager;
+Landroid/app/ActivityManager;->IActivityManagerSingleton:Landroid/util/Singleton;
Landroid/app/ActivityManager;->isLowRamDeviceStatic()Z
Landroid/app/ActivityManager;->isUserRunning(I)Z
Landroid/app/ActivityManager;->mContext:Landroid/content/Context;
@@ -22,17 +28,37 @@
Landroid/app/ActivityManager$RunningAppProcessInfo;->flags:I
Landroid/app/ActivityManager$RunningAppProcessInfo;->processState:I
Landroid/app/Activity;->mApplication:Landroid/app/Application;
+Landroid/app/Activity;->mComponent:Landroid/content/ComponentName;
+Landroid/app/Activity;->mFragments:Landroid/app/FragmentController;
Landroid/app/Activity;->mHandler:Landroid/os/Handler;
+Landroid/app/Activity;->mInstrumentation:Landroid/app/Instrumentation;
+Landroid/app/Activity;->mReferrer:Ljava/lang/String;
Landroid/app/Activity;->mResultCode:I
Landroid/app/Activity;->mResultData:Landroid/content/Intent;
+Landroid/app/Activity;->mResumed:Z
Landroid/app/Activity;->mToken:Landroid/os/IBinder;
Landroid/app/Activity;->mWindow:Landroid/view/Window;
Landroid/app/Activity;->mWindowManager:Landroid/view/WindowManager;
Landroid/app/Activity;->setDisablePreviewScreenshots(Z)V
Landroid/app/ActivityThread$ActivityClientRecord;->activityInfo:Landroid/content/pm/ActivityInfo;
+Landroid/app/ActivityThread$ActivityClientRecord;->activity:Landroid/app/Activity;
+Landroid/app/ActivityThread$ActivityClientRecord;->compatInfo:Landroid/content/res/CompatibilityInfo;
+Landroid/app/ActivityThread$ActivityClientRecord;->intent:Landroid/content/Intent;
+Landroid/app/ActivityThread$ActivityClientRecord;->mPreserveWindow:Z
+Landroid/app/ActivityThread$ActivityClientRecord;->packageInfo:Landroid/app/LoadedApk;
+Landroid/app/ActivityThread$ActivityClientRecord;->paused:Z
+Landroid/app/ActivityThread$ActivityClientRecord;->stopped:Z
Landroid/app/ActivityThread$ActivityClientRecord;->token:Landroid/os/IBinder;
+Landroid/app/ActivityThread$AppBindData;->appInfo:Landroid/content/pm/ApplicationInfo;
Landroid/app/ActivityThread$AppBindData;->info:Landroid/app/LoadedApk;
Landroid/app/ActivityThread$AppBindData;->instrumentationArgs:Landroid/os/Bundle;
+Landroid/app/ActivityThread$AppBindData;->providers:Ljava/util/List;
+Landroid/app/ActivityThread$BindServiceData;->intent:Landroid/content/Intent;
+Landroid/app/ActivityThread$BindServiceData;->token:Landroid/os/IBinder;
+Landroid/app/ActivityThread$CreateServiceData;->compatInfo:Landroid/content/res/CompatibilityInfo;
+Landroid/app/ActivityThread$CreateServiceData;->info:Landroid/content/pm/ServiceInfo;
+Landroid/app/ActivityThread$CreateServiceData;->intent:Landroid/content/Intent;
+Landroid/app/ActivityThread$CreateServiceData;->token:Landroid/os/IBinder;
Landroid/app/ActivityThread;->currentActivityThread()Landroid/app/ActivityThread;
Landroid/app/ActivityThread;->currentApplication()Landroid/app/Application;
Landroid/app/ActivityThread;->currentPackageName()Ljava/lang/String;
@@ -42,25 +68,41 @@
Landroid/app/ActivityThread;->getApplicationThread()Landroid/app/ActivityThread$ApplicationThread;
Landroid/app/ActivityThread;->getHandler()Landroid/os/Handler;
Landroid/app/ActivityThread;->getInstrumentation()Landroid/app/Instrumentation;
+Landroid/app/ActivityThread;->getPackageInfo(Landroid/content/pm/ApplicationInfo;Landroid/content/res/CompatibilityInfo;I)Landroid/app/LoadedApk;
+Landroid/app/ActivityThread;->getPackageInfoNoCheck(Landroid/content/pm/ApplicationInfo;Landroid/content/res/CompatibilityInfo;)Landroid/app/LoadedApk;
Landroid/app/ActivityThread;->getPackageManager()Landroid/content/pm/IPackageManager;
Landroid/app/ActivityThread;->getProcessName()Ljava/lang/String;
+Landroid/app/ActivityThread;->getSystemContext()Landroid/app/ContextImpl;
Landroid/app/ActivityThread$H;->BIND_SERVICE:I
Landroid/app/ActivityThread$H;->CREATE_SERVICE:I
Landroid/app/ActivityThread$H;->EXIT_APPLICATION:I
+Landroid/app/ActivityThread$H;->GC_WHEN_IDLE:I
Landroid/app/ActivityThread$H;->RECEIVER:I
Landroid/app/ActivityThread$H;->REMOVE_PROVIDER:I
Landroid/app/ActivityThread$H;->SERVICE_ARGS:I
Landroid/app/ActivityThread$H;->STOP_SERVICE:I
Landroid/app/ActivityThread$H;->UNBIND_SERVICE:I
Landroid/app/ActivityThread;->installContentProviders(Landroid/content/Context;Ljava/util/List;)V
+Landroid/app/ActivityThread;->installProvider(Landroid/content/Context;Landroid/app/ContentProviderHolder;Landroid/content/pm/ProviderInfo;ZZZ)Landroid/app/ContentProviderHolder;
Landroid/app/ActivityThread;->mActivities:Landroid/util/ArrayMap;
Landroid/app/ActivityThread;->mAllApplications:Ljava/util/ArrayList;
Landroid/app/ActivityThread;->mBoundApplication:Landroid/app/ActivityThread$AppBindData;
+Landroid/app/ActivityThread;->mH:Landroid/app/ActivityThread$H;
Landroid/app/ActivityThread;->mInitialApplication:Landroid/app/Application;
Landroid/app/ActivityThread;->mInstrumentation:Landroid/app/Instrumentation;
Landroid/app/ActivityThread;->mNumVisibleActivities:I
Landroid/app/ActivityThread;->mPackages:Landroid/util/ArrayMap;
+Landroid/app/ActivityThread;->mProviderMap:Landroid/util/ArrayMap;
+Landroid/app/ActivityThread;->mServices:Landroid/util/ArrayMap;
Landroid/app/ActivityThread;->performStopActivity(Landroid/os/IBinder;ZLjava/lang/String;)V
+Landroid/app/ActivityThread$ProviderClientRecord;->mLocalProvider:Landroid/content/ContentProvider;
+Landroid/app/ActivityThread$ReceiverData;->compatInfo:Landroid/content/res/CompatibilityInfo;
+Landroid/app/ActivityThread$ReceiverData;->info:Landroid/content/pm/ActivityInfo;
+Landroid/app/ActivityThread$ReceiverData;->intent:Landroid/content/Intent;
+Landroid/app/ActivityThread;->sCurrentActivityThread:Landroid/app/ActivityThread;
+Landroid/app/ActivityThread;->sendActivityResult(Landroid/os/IBinder;Ljava/lang/String;IILandroid/content/Intent;)V
+Landroid/app/ActivityThread$ServiceArgsData;->args:Landroid/content/Intent;
+Landroid/app/ActivityThread$ServiceArgsData;->token:Landroid/os/IBinder;
Landroid/app/ActivityThread;->sPackageManager:Landroid/content/pm/IPackageManager;
Landroid/app/admin/DevicePolicyManager;->getDeviceOwnerComponentOnAnyUser()Landroid/content/ComponentName;
Landroid/app/admin/DevicePolicyManager;->getDeviceOwner()Ljava/lang/String;
@@ -72,10 +114,14 @@
Landroid/app/admin/DevicePolicyManager;->packageHasActiveAdmins(Ljava/lang/String;)Z
Landroid/app/admin/DevicePolicyManager;->setActiveAdmin(Landroid/content/ComponentName;ZI)V
Landroid/app/admin/DevicePolicyManager;->setActiveAdmin(Landroid/content/ComponentName;Z)V
+Landroid/app/admin/IDevicePolicyManager$Stub;->TRANSACTION_packageHasActiveAdmins:I
+Landroid/app/admin/IDevicePolicyManager$Stub;->TRANSACTION_removeActiveAdmin:I
+Landroid/app/admin/SecurityLog$SecurityEvent;-><init>([B)V
Landroid/app/AlarmManager;->FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED:I
Landroid/app/AlarmManager;->FLAG_IDLE_UNTIL:I
Landroid/app/AlarmManager;->FLAG_STANDALONE:I
Landroid/app/AlarmManager;->FLAG_WAKE_FROM_IDLE:I
+Landroid/app/AlarmManager;->mService:Landroid/app/IAlarmManager;
Landroid/app/AlarmManager;->set(IJJJLandroid/app/AlarmManager$OnAlarmListener;Landroid/os/Handler;Landroid/os/WorkSource;)V
Landroid/app/AlarmManager;->set(IJJJLandroid/app/PendingIntent;Landroid/os/WorkSource;)V
Landroid/app/AlarmManager;->WINDOW_EXACT:J
@@ -85,26 +131,50 @@
Landroid/app/AppGlobals;->getInitialApplication()Landroid/app/Application;
Landroid/app/AppGlobals;->getPackageManager()Landroid/content/pm/IPackageManager;
Landroid/app/Application;->attach(Landroid/content/Context;)V
+Landroid/app/Application;->collectActivityLifecycleCallbacks()[Ljava/lang/Object;
+Landroid/app/Application;->dispatchActivityCreated(Landroid/app/Activity;Landroid/os/Bundle;)V
+Landroid/app/Application;->dispatchActivityDestroyed(Landroid/app/Activity;)V
+Landroid/app/Application;->dispatchActivityPaused(Landroid/app/Activity;)V
+Landroid/app/Application;->dispatchActivityResumed(Landroid/app/Activity;)V
+Landroid/app/Application;->dispatchActivitySaveInstanceState(Landroid/app/Activity;Landroid/os/Bundle;)V
+Landroid/app/Application;->dispatchActivityStarted(Landroid/app/Activity;)V
+Landroid/app/Application;->dispatchActivityStopped(Landroid/app/Activity;)V
Landroid/app/ApplicationLoaders;->getDefault()Landroid/app/ApplicationLoaders;
Landroid/app/ApplicationLoaders;->mLoaders:Landroid/util/ArrayMap;
Landroid/app/Application;->mComponentCallbacks:Ljava/util/ArrayList;
Landroid/app/Application;->mLoadedApk:Landroid/app/LoadedApk;
Landroid/app/ApplicationPackageManager;->deletePackage(Ljava/lang/String;Landroid/content/pm/IPackageDeleteObserver;I)V
+Landroid/app/ApplicationPackageManager;->getPackageSizeInfoAsUser(Ljava/lang/String;ILandroid/content/pm/IPackageStatsObserver;)V
+Landroid/app/ApplicationPackageManager;-><init>(Landroid/app/ContextImpl;Landroid/content/pm/IPackageManager;)V
Landroid/app/ApplicationPackageManager;->installExistingPackage(Ljava/lang/String;)I
Landroid/app/ApplicationPackageManager;->installExistingPackage(Ljava/lang/String;I)I
+Landroid/app/ApplicationPackageManager;->mPM:Landroid/content/pm/IPackageManager;
Landroid/app/AppOpsManager;->checkOp(IILjava/lang/String;)I
Landroid/app/AppOpsManager;->checkOpNoThrow(IILjava/lang/String;)I
+Landroid/app/AppOpsManager;->mService:Lcom/android/internal/app/IAppOpsService;
Landroid/app/AppOpsManager;->noteOp(I)I
Landroid/app/AppOpsManager;->noteOp(IILjava/lang/String;)I
+Landroid/app/AppOpsManager;->OP_COARSE_LOCATION:I
+Landroid/app/AppOpsManager;->OP_FINE_LOCATION:I
+Landroid/app/AppOpsManager;->OP_GET_USAGE_STATS:I
Landroid/app/AppOpsManager;->OP_POST_NOTIFICATION:I
+Landroid/app/AppOpsManager;->OP_READ_PHONE_STATE:I
+Landroid/app/AppOpsManager;->OP_READ_SMS:I
+Landroid/app/AppOpsManager;->OP_SYSTEM_ALERT_WINDOW:I
Landroid/app/AppOpsManager;->OP_WIFI_SCAN:I
Landroid/app/AppOpsManager;->OP_WRITE_SMS:I
+Landroid/app/AppOpsManager;->permissionToOpCode(Ljava/lang/String;)I
Landroid/app/AppOpsManager;->setMode(IILjava/lang/String;I)V
Landroid/app/AppOpsManager;->strOpToOp(Ljava/lang/String;)I
+Landroid/app/backup/BackupDataInput$EntityHeader;->dataSize:I
+Landroid/app/backup/BackupDataInput$EntityHeader;->key:Ljava/lang/String;
Landroid/app/backup/BackupDataInput;-><init>(Ljava/io/FileDescriptor;)V
Landroid/app/backup/BackupDataInputStream;->dataSize:I
Landroid/app/backup/BackupDataInputStream;->key:Ljava/lang/String;
Landroid/app/backup/BackupDataOutput;-><init>(Ljava/io/FileDescriptor;)V
+Landroid/app/backup/BackupDataOutput;->mBackupWriter:J
+Landroid/app/backup/BackupHelperDispatcher$Header;->chunkSize:I
+Landroid/app/backup/BackupHelperDispatcher$Header;->keyPrefix:Ljava/lang/String;
Landroid/app/backup/BackupManager;->backupNow()V
Landroid/app/backup/BackupManager;->beginRestoreSession()Landroid/app/backup/RestoreSession;
Landroid/app/backup/BackupManager;->cancelBackups()V
@@ -118,64 +188,135 @@
Landroid/app/backup/BackupManager;->selectBackupTransport(Ljava/lang/String;)Ljava/lang/String;
Landroid/app/backup/BackupManager;->setAutoRestore(Z)V
Landroid/app/backup/BackupManager;->setBackupEnabled(Z)V
+Landroid/app/backup/BackupManager;->updateTransportAttributes(Landroid/content/ComponentName;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;)V
Landroid/app/backup/BackupObserver;-><init>()V
Landroid/app/backup/BackupTransport;-><init>()V
Landroid/app/backup/FullBackup;->backupToTar(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/backup/FullBackupDataOutput;)I
+Landroid/app/backup/FullBackupDataOutput;->addSize(J)V
+Landroid/app/backup/FullBackupDataOutput;->mData:Landroid/app/backup/BackupDataOutput;
Landroid/app/backup/RestoreDescription;-><init>(Ljava/lang/String;I)V
Landroid/app/backup/RestoreSession;->endRestoreSession()V
Landroid/app/backup/RestoreSession;->getAvailableRestoreSets(Landroid/app/backup/RestoreObserver;)I
Landroid/app/backup/RestoreSession;->restoreAll(JLandroid/app/backup/RestoreObserver;)I
Landroid/app/backup/RestoreSet;-><init>(Ljava/lang/String;Ljava/lang/String;J)V
Landroid/app/backup/SelectBackupTransportCallback;-><init>()V
+Landroid/app/ContentProviderHolder;->provider:Landroid/content/IContentProvider;
Landroid/app/ContextImpl;->createActivityContext(Landroid/app/ActivityThread;Landroid/app/LoadedApk;Landroid/content/pm/ActivityInfo;Landroid/os/IBinder;ILandroid/content/res/Configuration;)Landroid/app/ContextImpl;
Landroid/app/ContextImpl;->getActivityToken()Landroid/os/IBinder;
+Landroid/app/ContextImpl;->getDisplay()Landroid/view/Display;
+Landroid/app/ContextImpl;->getPreferencesDir()Ljava/io/File;
+Landroid/app/ContextImpl;->mContentResolver:Landroid/app/ContextImpl$ApplicationContentResolver;
Landroid/app/ContextImpl;->mMainThread:Landroid/app/ActivityThread;
+Landroid/app/ContextImpl;->mOpPackageName:Ljava/lang/String;
+Landroid/app/ContextImpl;->mOuterContext:Landroid/content/Context;
Landroid/app/ContextImpl;->mPackageInfo:Landroid/app/LoadedApk;
+Landroid/app/ContextImpl;->mPackageManager:Landroid/content/pm/PackageManager;
+Landroid/app/ContextImpl;->mResources:Landroid/content/res/Resources;
+Landroid/app/ContextImpl;->mServiceCache:[Ljava/lang/Object;
+Landroid/app/ContextImpl;->mTheme:Landroid/content/res/Resources$Theme;
+Landroid/app/ContextImpl;->scheduleFinalCleanup(Ljava/lang/String;Ljava/lang/String;)V
Landroid/app/ContextImpl;->setOuterContext(Landroid/content/Context;)V
Landroid/app/DatePickerDialog;->mDatePicker:Landroid/widget/DatePicker;
Landroid/app/Dialog;->CANCEL:I
+Landroid/app/Dialog;->dismissDialog()V
Landroid/app/Dialog;->mCancelMessage:Landroid/os/Message;
Landroid/app/Dialog;->mDismissMessage:Landroid/os/Message;
Landroid/app/Dialog;->mListenersHandler:Landroid/os/Handler;
Landroid/app/Dialog;->mOwnerActivity:Landroid/app/Activity;
Landroid/app/Dialog;->mShowMessage:Landroid/os/Message;
Landroid/app/DownloadManager$Request;->mUri:Landroid/net/Uri;
+Landroid/app/FragmentManagerImpl;->mAdded:Ljava/util/ArrayList;
Landroid/app/Fragment;->mChildFragmentManager:Landroid/app/FragmentManagerImpl;
Landroid/app/IActivityManager;->forceStopPackage(Ljava/lang/String;I)V
Landroid/app/IActivityManager;->getLaunchedFromPackage(Landroid/os/IBinder;)Ljava/lang/String;
+Landroid/app/IActivityManager;->getTaskForActivity(Landroid/os/IBinder;Z)I
Landroid/app/IActivityManager;->resumeAppSwitches()V
+Landroid/app/IActivityManager;->setRequestedOrientation(Landroid/os/IBinder;I)V
+Landroid/app/IActivityManager$Stub$Proxy;->getConfiguration()Landroid/content/res/Configuration;
+Landroid/app/IActivityManager$Stub$Proxy;->getLaunchedFromUid(Landroid/os/IBinder;)I
+Landroid/app/IActivityManager$Stub$Proxy;->getProcessPss([I)[J
+Landroid/app/IActivityManager$Stub$Proxy;->isAppForeground(I)Z
+Landroid/app/IActivityManager$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/app/IAlarmManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/app/IAlarmManager$Stub;->TRANSACTION_remove:I
+Landroid/app/IAlarmManager$Stub;->TRANSACTION_set:I
Landroid/app/IApplicationThread;->scheduleTrimMemory(I)V
+Landroid/app/INotificationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/INotificationManager;
+Landroid/app/INotificationManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/app/InstantAppResolverService;-><init>()V
Landroid/app/InstantAppResolverService$InstantAppResolutionCallback;->onInstantAppResolveInfo(Ljava/util/List;)V
+Landroid/app/Instrumentation;->execStartActivity(Landroid/content/Context;Landroid/os/IBinder;Landroid/os/IBinder;Landroid/app/Activity;Landroid/content/Intent;ILandroid/os/Bundle;)Landroid/app/Instrumentation$ActivityResult;
+Landroid/app/Instrumentation;->execStartActivity(Landroid/content/Context;Landroid/os/IBinder;Landroid/os/IBinder;Ljava/lang/String;Landroid/content/Intent;ILandroid/os/Bundle;)Landroid/app/Instrumentation$ActivityResult;
+Landroid/app/Instrumentation;->execStartActivity(Landroid/content/Context;Landroid/os/IBinder;Landroid/os/IBinder;Ljava/lang/String;Landroid/content/Intent;ILandroid/os/Bundle;Landroid/os/UserHandle;)Landroid/app/Instrumentation$ActivityResult;
Landroid/app/IntentService;->mServiceHandler:Landroid/app/IntentService$ServiceHandler;
+Landroid/app/ISearchManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/ISearchManager;
+Landroid/app/ISearchManager$Stub$Proxy;->getGlobalSearchActivity()Landroid/content/ComponentName;
+Landroid/app/ISearchManager$Stub$Proxy;->getWebSearchActivity()Landroid/content/ComponentName;
+Landroid/app/IUiModeManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/app/IWallpaperManager;->getWallpaper(Ljava/lang/String;Landroid/app/IWallpaperManagerCallback;ILandroid/os/Bundle;I)Landroid/os/ParcelFileDescriptor;
+Landroid/app/job/IJobScheduler$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/job/IJobScheduler;
+Landroid/app/job/IJobScheduler$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/app/LoadedApk;->mActivityThread:Landroid/app/ActivityThread;
+Landroid/app/LoadedApk;->makeApplication(ZLandroid/app/Instrumentation;)Landroid/app/Application;
+Landroid/app/LoadedApk;->mAppDir:Ljava/lang/String;
+Landroid/app/LoadedApk;->mApplicationInfo:Landroid/content/pm/ApplicationInfo;
Landroid/app/LoadedApk;->mApplication:Landroid/app/Application;
+Landroid/app/LoadedApk;->mBaseClassLoader:Ljava/lang/ClassLoader;
+Landroid/app/LoadedApk;->mClassLoader:Ljava/lang/ClassLoader;
+Landroid/app/LoadedApk;->mDataDir:Ljava/lang/String;
+Landroid/app/LoadedApk;->mPackageName:Ljava/lang/String;
Landroid/app/LoadedApk;->mReceivers:Landroid/util/ArrayMap;
Landroid/app/LoadedApk;->mResDir:Ljava/lang/String;
Landroid/app/LoadedApk;->mResources:Landroid/content/res/Resources;
+Landroid/app/LoadedApk;->mSplitResDirs:[Ljava/lang/String;
Landroid/app/LocalActivityManager;->mActivities:Ljava/util/Map;
Landroid/app/LocalActivityManager;->mActivityArray:Ljava/util/ArrayList;
+Landroid/app/NativeActivity;->hideIme(I)V
+Landroid/app/NativeActivity;->setWindowFlags(II)V
+Landroid/app/NativeActivity;->setWindowFormat(I)V
+Landroid/app/NativeActivity;->showIme(I)V
Landroid/app/Notification$Builder;->mActions:Ljava/util/ArrayList;
Landroid/app/Notification;->EXTRA_SUBSTITUTE_APP_NAME:Ljava/lang/String;
Landroid/app/Notification;->isGroupSummary()Z
Landroid/app/NotificationManager;->getService()Landroid/app/INotificationManager;
Landroid/app/NotificationManager;->notifyAsUser(Ljava/lang/String;ILandroid/app/Notification;Landroid/os/UserHandle;)V
+Landroid/app/NotificationManager;->sService:Landroid/app/INotificationManager;
+Landroid/app/Notification;->mLargeIcon:Landroid/graphics/drawable/Icon;
+Landroid/app/Notification;->mSmallIcon:Landroid/graphics/drawable/Icon;
Landroid/app/Notification;->setLatestEventInfo(Landroid/content/Context;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Landroid/app/PendingIntent;)V
Landroid/app/PendingIntent;->getActivityAsUser(Landroid/content/Context;ILandroid/content/Intent;ILandroid/os/Bundle;Landroid/os/UserHandle;)Landroid/app/PendingIntent;
Landroid/app/PendingIntent;->getIntent()Landroid/content/Intent;
Landroid/app/PendingIntent;->isActivity()Z
Landroid/app/Presentation;->createPresentationContext(Landroid/content/Context;Landroid/view/Display;I)Landroid/content/Context;
Landroid/app/ProgressDialog;->mProgressNumber:Landroid/widget/TextView;
+Landroid/app/QueuedWork;->addFinisher(Ljava/lang/Runnable;)V
+Landroid/app/QueuedWork;->removeFinisher(Ljava/lang/Runnable;)V
+Landroid/app/ResourcesManager;->appendLibAssetForMainAssetPath(Ljava/lang/String;Ljava/lang/String;)V
+Landroid/app/ResourcesManager;->getInstance()Landroid/app/ResourcesManager;
+Landroid/app/ResourcesManager;->mActivityResourceReferences:Ljava/util/WeakHashMap;
+Landroid/app/ResourcesManager;->mResourceImpls:Landroid/util/ArrayMap;
+Landroid/app/ResourcesManager;->mResourceReferences:Ljava/util/ArrayList;
+Landroid/app/Service;->attach(Landroid/content/Context;Landroid/app/ActivityThread;Ljava/lang/String;Landroid/os/IBinder;Landroid/app/Application;Ljava/lang/Object;)V
+Landroid/app/Service;->mActivityManager:Landroid/app/IActivityManager;
+Landroid/app/Service;->mApplication:Landroid/app/Application;
+Landroid/app/Service;->mClassName:Ljava/lang/String;
+Landroid/app/Service;->mStartCompatibility:Z
+Landroid/app/Service;->mThread:Landroid/app/ActivityThread;
+Landroid/app/Service;->mToken:Landroid/os/IBinder;
Landroid/app/Service;->setForeground(Z)V
+Landroid/app/SharedPreferencesImpl;->mFile:Ljava/io/File;
Landroid/app/StatusBarManager;->collapsePanels()V
Landroid/app/StatusBarManager;->disable(I)V
Landroid/app/StatusBarManager;->expandNotificationsPanel()V
Landroid/app/StatusBarManager;->expandSettingsPanel(Ljava/lang/String;)V
Landroid/app/StatusBarManager;->expandSettingsPanel()V
Landroid/app/TimePickerDialog;->mTimePicker:Landroid/widget/TimePicker;
+Landroid/app/trust/ITrustManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/app/usage/UsageStatsManager;->getAppStandbyBuckets()Ljava/util/Map;
+Landroid/app/usage/UsageStatsManager;->mService:Landroid/app/usage/IUsageStatsManager;
Landroid/app/usage/UsageStatsManager;->setAppStandbyBuckets(Ljava/util/Map;)V
Landroid/app/usage/UsageStatsManager;->whitelistAppTemporarily(Ljava/lang/String;JLandroid/os/UserHandle;)V
+Landroid/app/usage/UsageStats;->mLastEvent:I
Landroid/app/WallpaperColors;->getColorHints()I
Landroid/app/WallpaperManager;->getBitmap()Landroid/graphics/Bitmap;
Landroid/app/WallpaperManager;->getBitmap(Z)Landroid/graphics/Bitmap;
@@ -194,6 +335,7 @@
Landroid/bluetooth/BluetoothAdapter;->getDiscoverableTimeout()I
Landroid/bluetooth/BluetoothAdapter;->isBleScanAlwaysAvailable()Z
Landroid/bluetooth/BluetoothAdapter;->isLeEnabled()Z
+Landroid/bluetooth/BluetoothAdapter;->mService:Landroid/bluetooth/IBluetooth;
Landroid/bluetooth/BluetoothAdapter;->setScanMode(II)Z
Landroid/bluetooth/BluetoothAdapter;->setScanMode(I)Z
Landroid/bluetooth/BluetoothDevice;->cancelBondProcess()Z
@@ -211,15 +353,29 @@
Landroid/bluetooth/BluetoothHeadset;->close()V
Landroid/bluetooth/BluetoothHeadset;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
Landroid/bluetooth/BluetoothUuid;->RESERVED_UUIDS:[Landroid/os/ParcelUuid;
+Landroid/bluetooth/IBluetooth;->getAddress()Ljava/lang/String;
Landroid/bluetooth/IBluetooth$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetooth;
+Landroid/bluetooth/IBluetooth$Stub$Proxy;->getAddress()Ljava/lang/String;
Landroid/bluetooth/le/BluetoothLeScanner;->startScanFromSource(Ljava/util/List;Landroid/bluetooth/le/ScanSettings;Landroid/os/WorkSource;Landroid/bluetooth/le/ScanCallback;)V
Landroid/bluetooth/le/ScanSettings$Builder;->setScanResultType(I)Landroid/bluetooth/le/ScanSettings$Builder;
Landroid/content/AsyncTaskLoader;->mExecutor:Ljava/util/concurrent/Executor;
+Landroid/content/BroadcastReceiver$PendingResult;-><init>(ILjava/lang/String;Landroid/os/Bundle;IZZLandroid/os/IBinder;II)V
+Landroid/content/BroadcastReceiver;->setPendingResult(Landroid/content/BroadcastReceiver$PendingResult;)V
+Landroid/content/ContentProvider;->mContext:Landroid/content/Context;
+Landroid/content/ContentProvider;->mPathPermissions:[Landroid/content/pm/PathPermission;
+Landroid/content/ContentProvider;->mReadPermission:Ljava/lang/String;
+Landroid/content/ContentProvider;->mWritePermission:Ljava/lang/String;
Landroid/content/ContentProviderOperation;->mSelection:Ljava/lang/String;
Landroid/content/ContentProviderOperation;->mType:I
+Landroid/content/ContentProviderOperation;->TYPE_DELETE:I
+Landroid/content/ContentProviderOperation;->TYPE_INSERT:I
+Landroid/content/ContentProviderOperation;->TYPE_UPDATE:I
+Landroid/content/ContentResolver;->acquireProvider(Landroid/net/Uri;)Landroid/content/IContentProvider;
Landroid/content/ContentResolver;->getContentService()Landroid/content/IContentService;
Landroid/content/ContentResolver;->getSyncStatus(Landroid/accounts/Account;Ljava/lang/String;)Landroid/content/SyncStatusInfo;
Landroid/content/ContentResolver;->mContext:Landroid/content/Context;
+Landroid/content/ContentResolver;->mPackageName:Ljava/lang/String;
+Landroid/content/ContentValues;-><init>(Ljava/util/HashMap;)V
Landroid/content/ContentValues;->mValues:Ljava/util/HashMap;
Landroid/content/Context;->bindServiceAsUser(Landroid/content/Intent;Landroid/content/ServiceConnection;ILandroid/os/UserHandle;)Z
Landroid/content/Context;->createCredentialProtectedStorageContext()Landroid/content/Context;
@@ -227,40 +383,59 @@
Landroid/content/Context;->getSharedPrefsFile(Ljava/lang/String;)Ljava/io/File;
Landroid/content/Context;->getThemeResId()I
Landroid/content/Context;->isCredentialProtectedStorage()Z
+Landroid/content/Context;->PERSISTENT_DATA_BLOCK_SERVICE:Ljava/lang/String;
Landroid/content/Context;->sendBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;Ljava/lang/String;I)V
Landroid/content/Context;->sendBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;Ljava/lang/String;Landroid/os/Bundle;)V
Landroid/content/Context;->sendOrderedBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;Ljava/lang/String;ILandroid/content/BroadcastReceiver;Landroid/os/Handler;ILjava/lang/String;Landroid/os/Bundle;)V
Landroid/content/Context;->sendOrderedBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;Ljava/lang/String;ILandroid/os/Bundle;Landroid/content/BroadcastReceiver;Landroid/os/Handler;ILjava/lang/String;Landroid/os/Bundle;)V
Landroid/content/ContextWrapper;->createCredentialProtectedStorageContext()Landroid/content/Context;
+Landroid/content/ContextWrapper;->getDisplay()Landroid/view/Display;
Landroid/content/ContextWrapper;->mBase:Landroid/content/Context;
Landroid/content/CursorLoader;->mCancellationSignal:Landroid/os/CancellationSignal;
Landroid/content/CursorLoader;->mObserver:Landroid/content/Loader$ForceLoadContentObserver;
+Landroid/content/IClipboard$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IClipboard;
Landroid/content/IContentService;->cancelSync(Landroid/accounts/Account;Ljava/lang/String;Landroid/content/ComponentName;)V
Landroid/content/IContentService;->getMasterSyncAutomatically()Z
Landroid/content/IContentService;->setMasterSyncAutomatically(Z)V
+Landroid/content/IContentService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/content/Intent;->ACTION_ALARM_CHANGED:Ljava/lang/String;
+Landroid/content/IntentFilter;->mActions:Ljava/util/ArrayList;
Landroid/content/IntentFilter;->setOrder(I)V
Landroid/content/Intent;->putExtra(Ljava/lang/String;Landroid/os/IBinder;)Landroid/content/Intent;
+Landroid/content/pm/ApplicationInfo;->enabledSetting:I
+Landroid/content/pm/ApplicationInfo;->getBaseResourcePath()Ljava/lang/String;
Landroid/content/pm/ApplicationInfo;->installLocation:I
Landroid/content/pm/ApplicationInfo;->isForwardLocked()Z
Landroid/content/pm/ApplicationInfo;->isInstantApp()Z
Landroid/content/pm/ApplicationInfo;->isPrivilegedApp()Z
Landroid/content/pm/ApplicationInfo;->primaryCpuAbi:Ljava/lang/String;
Landroid/content/pm/ApplicationInfo;->privateFlags:I
+Landroid/content/pm/ApplicationInfo;->scanPublicSourceDir:Ljava/lang/String;
+Landroid/content/pm/ApplicationInfo;->scanSourceDir:Ljava/lang/String;
+Landroid/content/pm/ApplicationInfo;->secondaryNativeLibraryDir:Ljava/lang/String;
Landroid/content/pm/ApplicationInfo;->targetSandboxVersion:I
Landroid/content/pm/InstantAppIntentFilter;-><init>(Ljava/lang/String;Ljava/util/List;)V
Landroid/content/pm/InstantAppResolveInfo;->getPackageName()Ljava/lang/String;
Landroid/content/pm/InstantAppResolveInfo;-><init>(Landroid/content/pm/InstantAppResolveInfo$InstantAppDigest;Ljava/lang/String;Ljava/util/List;I)V
Landroid/content/pm/InstantAppResolveInfo$InstantAppDigest;->getDigestPrefix()[I
Landroid/content/pm/InstantAppResolveInfo$InstantAppDigest;-><init>(Ljava/lang/String;)V
+Landroid/content/pm/IPackageManager;->getInstallLocation()I
Landroid/content/pm/IPackageManager;->getLastChosenActivity(Landroid/content/Intent;Ljava/lang/String;I)Landroid/content/pm/ResolveInfo;
+Landroid/content/pm/IPackageManager;->setApplicationEnabledSetting(Ljava/lang/String;IIILjava/lang/String;)V
+Landroid/content/pm/IPackageManager;->setComponentEnabledSetting(Landroid/content/ComponentName;III)V
Landroid/content/pm/IPackageManager;->setLastChosenActivity(Landroid/content/Intent;Ljava/lang/String;ILandroid/content/IntentFilter;ILandroid/content/ComponentName;)V
+Landroid/content/pm/IPackageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageManager;
+Landroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInfo(Ljava/lang/String;II)Landroid/content/pm/PackageInfo;
+Landroid/content/pm/IPackageManager$Stub$Proxy;->getPackagesForUid(I)[Ljava/lang/String;
+Landroid/content/pm/IPackageManager$Stub$Proxy;->getSystemSharedLibraryNames()[Ljava/lang/String;
Landroid/content/pm/IPackageStatsObserver$Stub;-><init>()V
Landroid/content/pm/LauncherApps;->mPm:Landroid/content/pm/PackageManager;
Landroid/content/pm/LauncherApps;->startShortcut(Ljava/lang/String;Ljava/lang/String;Landroid/graphics/Rect;Landroid/os/Bundle;I)V
+Landroid/content/pm/PackageInstaller$SessionParams;->setAllocateAggressive(Z)V
Landroid/content/pm/PackageInstaller$SessionParams;->setGrantedRuntimePermissions([Ljava/lang/String;)V
Landroid/content/pm/PackageInstaller$SessionParams;->setInstallAsInstantApp(Z)V
Landroid/content/pm/PackageManager;->addOnPermissionsChangeListener(Landroid/content/pm/PackageManager$OnPermissionsChangedListener;)V
+Landroid/content/pm/PackageManager;->buildRequestPermissionsIntent([Ljava/lang/String;)Landroid/content/Intent;
Landroid/content/pm/PackageManager;->freeStorageAndNotify(JLandroid/content/pm/IPackageDataObserver;)V
Landroid/content/pm/PackageManager;->freeStorageAndNotify(Ljava/lang/String;JLandroid/content/pm/IPackageDataObserver;)V
Landroid/content/pm/PackageManager;->freeStorage(JLandroid/content/IntentSender;)V
@@ -271,29 +446,70 @@
Landroid/content/pm/PackageManager;->getPackageSizeInfo(Ljava/lang/String;Landroid/content/pm/IPackageStatsObserver;)V
Landroid/content/pm/PackageManager;->getResourcesForApplicationAsUser(Ljava/lang/String;I)Landroid/content/res/Resources;
Landroid/content/pm/PackageManager;->movePackage(Ljava/lang/String;Landroid/os/storage/VolumeInfo;)I
+Landroid/content/pm/PackageManager;->NO_NATIVE_LIBRARIES:I
Landroid/content/pm/PackageManager;->queryBroadcastReceivers(Landroid/content/Intent;II)Ljava/util/List;
Landroid/content/pm/PackageManager;->removeOnPermissionsChangeListener(Landroid/content/pm/PackageManager$OnPermissionsChangedListener;)V
Landroid/content/pm/PackageManager;->verifyIntentFilter(IILjava/util/List;)V
+Landroid/content/pm/PackageParser$Activity;->info:Landroid/content/pm/ActivityInfo;
+Landroid/content/pm/PackageParser$ActivityIntentInfo;->activity:Landroid/content/pm/PackageParser$Activity;
Landroid/content/pm/PackageParser;->collectCertificates(Landroid/content/pm/PackageParser$Package;Ljava/io/File;Z)V
Landroid/content/pm/PackageParser;->collectCertificates(Landroid/content/pm/PackageParser$Package;Z)V
+Landroid/content/pm/PackageParser$Component;->className:Ljava/lang/String;
+Landroid/content/pm/PackageParser$Component;->getComponentName()Landroid/content/ComponentName;
+Landroid/content/pm/PackageParser$Component;->intents:Ljava/util/ArrayList;
Landroid/content/pm/PackageParser;->generatePackageInfo(Landroid/content/pm/PackageParser$Package;[IIJJLjava/util/Set;Landroid/content/pm/PackageUserState;I)Landroid/content/pm/PackageInfo;
Landroid/content/pm/PackageParser;->generatePackageInfo(Landroid/content/pm/PackageParser$Package;[IIJJLjava/util/Set;Landroid/content/pm/PackageUserState;)Landroid/content/pm/PackageInfo;
+Landroid/content/pm/PackageParser;-><init>()V
+Landroid/content/pm/PackageParser$Package;->activities:Ljava/util/ArrayList;
+Landroid/content/pm/PackageParser$Package;->applicationInfo:Landroid/content/pm/ApplicationInfo;
+Landroid/content/pm/PackageParser$Package;->mVersionCode:I
+Landroid/content/pm/PackageParser$Package;->mVersionName:Ljava/lang/String;
+Landroid/content/pm/PackageParser$Package;->packageName:Ljava/lang/String;
+Landroid/content/pm/PackageParser$Package;->providers:Ljava/util/ArrayList;
+Landroid/content/pm/PackageParser$Package;->receivers:Ljava/util/ArrayList;
+Landroid/content/pm/PackageParser$Package;->requestedPermissions:Ljava/util/ArrayList;
+Landroid/content/pm/PackageParser$Package;->services:Ljava/util/ArrayList;
+Landroid/content/pm/PackageParser;->parseBaseApk(Ljava/lang/String;Landroid/content/res/Resources;Landroid/content/res/XmlResourceParser;I[Ljava/lang/String;)Landroid/content/pm/PackageParser$Package;
Landroid/content/pm/PackageParser;->parseMonolithicPackage(Ljava/io/File;I)Landroid/content/pm/PackageParser$Package;
Landroid/content/pm/PackageParser;->parsePackage(Ljava/io/File;I)Landroid/content/pm/PackageParser$Package;
Landroid/content/pm/PackageParser;->parsePackage(Ljava/io/File;IZ)Landroid/content/pm/PackageParser$Package;
+Landroid/content/pm/PackageParser$Provider;->info:Landroid/content/pm/ProviderInfo;
+Landroid/content/pm/PackageParser$ProviderIntentInfo;->provider:Landroid/content/pm/PackageParser$Provider;
+Landroid/content/pm/PackageParser$ServiceIntentInfo;->service:Landroid/content/pm/PackageParser$Service;
+Landroid/content/pm/PackageUserState;-><init>()V
+Landroid/content/pm/ParceledListSlice;-><init>(Ljava/util/List;)V
+Landroid/content/pm/ResolveInfo;->instantAppAvailable:Z
+Landroid/content/pm/Signature;->getPublicKey()Ljava/security/PublicKey;
Landroid/content/pm/UserInfo;->id:I
Landroid/content/pm/UserInfo;->isPrimary()Z
+Landroid/content/pm/UserInfo;->serialNumber:I
+Landroid/content/res/AssetFileDescriptor;->mFd:Landroid/os/ParcelFileDescriptor;
+Landroid/content/res/AssetFileDescriptor;->mLength:J
+Landroid/content/res/AssetFileDescriptor;->mStartOffset:J
+Landroid/content/res/AssetManager;->addAssetPathAsSharedLibrary(Ljava/lang/String;)I
Landroid/content/res/AssetManager;->addAssetPath(Ljava/lang/String;)I
+Landroid/content/res/AssetManager;->addAssetPathNative(Ljava/lang/String;Z)I
Landroid/content/res/AssetManager;->addAssetPaths([Ljava/lang/String;)[I
Landroid/content/res/AssetManager;->applyStyle(JIIJ[IIJJ)V
+Landroid/content/res/AssetManager;->ensureStringBlocks()[Landroid/content/res/StringBlock;
Landroid/content/res/AssetManager;->getArraySize(I)I
Landroid/content/res/AssetManager;->getAssignedPackageIdentifiers()Landroid/util/SparseArray;
Landroid/content/res/AssetManager;->getCookieName(I)Ljava/lang/String;
+Landroid/content/res/AssetManager;->getNativeStringBlock(I)J
Landroid/content/res/AssetManager;->getResourceBagText(II)Ljava/lang/CharSequence;
+Landroid/content/res/AssetManager;->getResourceEntryName(I)Ljava/lang/String;
+Landroid/content/res/AssetManager;->getResourceIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
+Landroid/content/res/AssetManager;->getResourceName(I)Ljava/lang/String;
+Landroid/content/res/AssetManager;->getResourcePackageName(I)Ljava/lang/String;
+Landroid/content/res/AssetManager;->getResourceTypeName(I)Ljava/lang/String;
+Landroid/content/res/AssetManager;->getStringBlockCount()I
+Landroid/content/res/AssetManager;-><init>()V
+Landroid/content/res/AssetManager;->isUpToDate()Z
Landroid/content/res/AssetManager;->loadResourceBagValue(IILandroid/util/TypedValue;Z)I
Landroid/content/res/AssetManager;->loadResourceValue(ISLandroid/util/TypedValue;Z)I
Landroid/content/res/AssetManager;->loadThemeAttributeValue(JILandroid/util/TypedValue;Z)I
Landroid/content/res/AssetManager;->mObject:J
+Landroid/content/res/AssetManager;->mStringBlocks:[Landroid/content/res/StringBlock;
Landroid/content/res/AssetManager;->openNonAssetFdNative(ILjava/lang/String;[J)Landroid/os/ParcelFileDescriptor;
Landroid/content/res/AssetManager;->openNonAsset(ILjava/lang/String;I)Ljava/io/InputStream;
Landroid/content/res/AssetManager;->openNonAsset(ILjava/lang/String;)Ljava/io/InputStream;
@@ -304,9 +520,16 @@
Landroid/content/res/AssetManager;->resolveAttrs(JII[I[I[I[I)Z
Landroid/content/res/AssetManager;->retrieveArray(I[I)I
Landroid/content/res/AssetManager;->retrieveAttributes(J[I[I[I)Z
+Landroid/content/res/AssetManager;->setConfiguration(IILjava/lang/String;IIIIIIIIIIIIIII)V
Landroid/content/res/AssetManager;->STYLE_NUM_ENTRIES:I
Landroid/content/res/AssetManager;->STYLE_RESOURCE_ID:I
+Landroid/content/res/ColorStateList$ColorStateListFactory;-><init>(Landroid/content/res/ColorStateList;)V
+Landroid/content/res/ColorStateList;->mColors:[I
+Landroid/content/res/ColorStateList;->mDefaultColor:I
+Landroid/content/res/ColorStateList;->mFactory:Landroid/content/res/ColorStateList$ColorStateListFactory;
+Landroid/content/res/CompatibilityInfo;->DEFAULT_COMPATIBILITY_INFO:Landroid/content/res/CompatibilityInfo;
Landroid/content/res/DrawableCache;->getInstance(JLandroid/content/res/Resources;Landroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
+Landroid/content/res/ObbInfo;->salt:[B
Landroid/content/res/Resources;->getCompatibilityInfo()Landroid/content/res/CompatibilityInfo;
Landroid/content/res/ResourcesImpl;->mAccessLock:Ljava/lang/Object;
Landroid/content/res/ResourcesImpl;->mAssets:Landroid/content/res/AssetManager;
@@ -315,15 +538,20 @@
Landroid/content/res/ResourcesImpl;->mDrawableCache:Landroid/content/res/DrawableCache;
Landroid/content/res/ResourcesImpl;->mPreloading:Z
Landroid/content/res/ResourcesImpl;->sPreloadedColorDrawables:Landroid/util/LongSparseArray;
+Landroid/content/res/ResourcesImpl;->sPreloadedComplexColors:Landroid/util/LongSparseArray;
Landroid/content/res/ResourcesImpl;->sPreloadedDrawables:[Landroid/util/LongSparseArray;
Landroid/content/res/ResourcesImpl;->TRACE_FOR_MISS_PRELOAD:Z
Landroid/content/res/ResourcesImpl;->TRACE_FOR_PRELOAD:Z
+Landroid/content/res/ResourcesKey;->mSplitResDirs:[Ljava/lang/String;
Landroid/content/res/Resources;->loadXmlResourceParser(ILjava/lang/String;)Landroid/content/res/XmlResourceParser;
Landroid/content/res/Resources;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;
Landroid/content/res/Resources;->mResourcesImpl:Landroid/content/res/ResourcesImpl;
Landroid/content/res/Resources;->mTmpValue:Landroid/util/TypedValue;
Landroid/content/res/Resources;->mTypedArrayPool:Landroid/util/Pools$SynchronizedPool;
Landroid/content/res/Resources;->setCompatibilityInfo(Landroid/content/res/CompatibilityInfo;)V
+Landroid/content/res/Resources;->updateSystemConfiguration(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;)V
+Landroid/content/res/StringBlock;-><init>(JZ)V
+Landroid/content/res/TypedArray;->getNonConfigurationString(II)Ljava/lang/String;
Landroid/content/res/TypedArray;->getValueAt(ILandroid/util/TypedValue;)Z
Landroid/content/res/TypedArray;->mAssets:Landroid/content/res/AssetManager;
Landroid/content/res/TypedArray;->mData:[I
@@ -336,18 +564,48 @@
Landroid/content/res/TypedArray;->mValue:Landroid/util/TypedValue;
Landroid/content/res/TypedArray;->mXml:Landroid/content/res/XmlBlock$Parser;
Landroid/content/res/XmlBlock;->close()V
+Landroid/content/res/XmlBlock;-><init>([B)V
Landroid/content/res/XmlBlock;->newParser()Landroid/content/res/XmlResourceParser;
Landroid/content/res/XmlBlock$Parser;->mParseState:J
Landroid/content/SyncStatusInfo;->lastSuccessTime:J
+Landroid/database/AbstractCursor;->mExtras:Landroid/os/Bundle;
Landroid/database/AbstractCursor;->mNotifyUri:Landroid/net/Uri;
Landroid/database/CursorWindow;->mWindowPtr:J
Landroid/database/CursorWindow;->sCursorWindowSize:I
Landroid/database/CursorWindow;->sWindowToPidMap:Landroid/util/LongSparseArray;
Landroid/database/CursorWrapper;->mCursor:Landroid/database/Cursor;
+Landroid/database/sqlite/SQLiteCustomFunction;->dispatchCallback([Ljava/lang/String;)V
+Landroid/database/sqlite/SQLiteCustomFunction;->name:Ljava/lang/String;
+Landroid/database/sqlite/SQLiteCustomFunction;->numArgs:I
+Landroid/database/sqlite/SQLiteDatabaseConfiguration;->maxSqlCacheSize:I
+Landroid/database/sqlite/SQLiteDatabase;->mConfigurationLocked:Landroid/database/sqlite/SQLiteDatabaseConfiguration;
+Landroid/database/sqlite/SQLiteDatabase;->mConnectionPoolLocked:Landroid/database/sqlite/SQLiteConnectionPool;
+Landroid/database/sqlite/SQLiteDebug$PagerStats;->largestMemAlloc:I
+Landroid/database/sqlite/SQLiteDebug$PagerStats;->memoryUsed:I
+Landroid/database/sqlite/SQLiteDebug$PagerStats;->pageCacheOverflow:I
+Landroid/database/sqlite/SQLiteOpenHelper;->mName:Ljava/lang/String;
+Landroid/ddm/DdmHandleAppName;->getAppName()Ljava/lang/String;
+Landroid/graphics/BaseCanvas;->mNativeCanvasWrapper:J
Landroid/graphics/Bitmap$Config;->nativeInt:I
+Landroid/graphics/Bitmap$Config;->nativeToConfig(I)Landroid/graphics/Bitmap$Config;
Landroid/graphics/Bitmap;->createAshmemBitmap()Landroid/graphics/Bitmap;
Landroid/graphics/Bitmap;->createAshmemBitmap(Landroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;
+Landroid/graphics/BitmapFactory;->nativeDecodeAsset(JLandroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
+Landroid/graphics/BitmapFactory;->nativeDecodeByteArray([BIILandroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
+Landroid/graphics/BitmapFactory;->nativeDecodeFileDescriptor(Ljava/io/FileDescriptor;Landroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
+Landroid/graphics/BitmapFactory;->nativeDecodeStream(Ljava/io/InputStream;[BLandroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
Landroid/graphics/Bitmap;->getDefaultDensity()I
+Landroid/graphics/Bitmap;-><init>(JIIIZZ[BLandroid/graphics/NinePatch$InsetStruct;)V
+Landroid/graphics/Bitmap;->mNativePtr:J
+Landroid/graphics/Bitmap;->mNinePatchChunk:[B
+Landroid/graphics/Bitmap;->mNinePatchInsets:Landroid/graphics/NinePatch$InsetStruct;
+Landroid/graphics/BitmapRegionDecoder;-><init>(J)V
+Landroid/graphics/Bitmap;->reinit(IIZ)V
+Landroid/graphics/Camera;->native_instance:J
+Landroid/graphics/Canvas;-><init>(J)V
+Landroid/graphics/Canvas;->release()V
+Landroid/graphics/drawable/AnimatedImageDrawable;->onAnimationEnd()V
+Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->callOnFinished(Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V
Landroid/graphics/drawable/AnimationDrawable;->mCurFrame:I
Landroid/graphics/drawable/BitmapDrawable;->getTint()Landroid/content/res/ColorStateList;
Landroid/graphics/drawable/BitmapDrawable;->getTintMode()Landroid/graphics/PorterDuff$Mode;
@@ -357,6 +615,11 @@
Landroid/graphics/drawable/DrawableContainer;->mDrawableContainerState:Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;
Landroid/graphics/drawable/Drawable;->inflateWithAttributes(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/TypedArray;I)V
Landroid/graphics/drawable/Drawable;->mCallback:Ljava/lang/ref/WeakReference;
+Landroid/graphics/drawable/GradientDrawable$GradientState;->mAngle:I
+Landroid/graphics/drawable/GradientDrawable$GradientState;->mPadding:Landroid/graphics/Rect;
+Landroid/graphics/drawable/GradientDrawable$GradientState;->mPositions:[F
+Landroid/graphics/drawable/GradientDrawable;->mPadding:Landroid/graphics/Rect;
+Landroid/graphics/drawable/Icon;->getResPackage()Ljava/lang/String;
Landroid/graphics/drawable/NinePatchDrawable;->mNinePatchState:Landroid/graphics/drawable/NinePatchDrawable$NinePatchState;
Landroid/graphics/drawable/NinePatchDrawable$NinePatchState;->mNinePatch:Landroid/graphics/NinePatch;
Landroid/graphics/drawable/StateListDrawable;->extractStateSet(Landroid/util/AttributeSet;)[I
@@ -370,18 +633,45 @@
Landroid/graphics/FontFamily;->addFontFromBuffer(Ljava/nio/ByteBuffer;I[Landroid/graphics/fonts/FontVariationAxis;II)Z
Landroid/graphics/FontFamily;->freeze()Z
Landroid/graphics/FontFamily;-><init>()V
+Landroid/graphics/fonts/FontVariationAxis;->mStyleValue:F
+Landroid/graphics/fonts/FontVariationAxis;->mTag:I
+Landroid/graphics/GraphicBuffer;->createFromExisting(IIIIJ)Landroid/graphics/GraphicBuffer;
+Landroid/graphics/GraphicBuffer;-><init>(IIIIJ)V
+Landroid/graphics/GraphicBuffer;->mNativeObject:J
+Landroid/graphics/ImageDecoder;-><init>(JIIZ)V
+Landroid/graphics/ImageDecoder;->onPartialImage(I)Z
+Landroid/graphics/ImageDecoder;->postProcessAndRelease(Landroid/graphics/Canvas;)I
Landroid/graphics/LinearGradient;->mColors:[I
+Landroid/graphics/Matrix;->native_instance:J
+Landroid/graphics/Movie;-><init>(J)V
+Landroid/graphics/Movie;->mNativeMovie:J
+Landroid/graphics/NinePatch$InsetStruct;-><init>(IIIIIIIIFIF)V
Landroid/graphics/NinePatch;->mBitmap:Landroid/graphics/Bitmap;
+Landroid/graphics/Picture;->mNativePicture:J
+Landroid/graphics/Region;-><init>(JI)V
+Landroid/graphics/Region;->mNativeRegion:J
+Landroid/graphics/SurfaceTexture;->mFrameAvailableListener:J
+Landroid/graphics/SurfaceTexture;->mProducer:J
+Landroid/graphics/SurfaceTexture;->mSurfaceTexture:J
Landroid/graphics/SurfaceTexture;->nativeDetachFromGLContext()I
+Landroid/graphics/SurfaceTexture;->postEventFromNative(Ljava/lang/ref/WeakReference;)V
Landroid/graphics/Typeface;->mStyle:I
Landroid/graphics/Typeface;->sDefaults:[Landroid/graphics/Typeface;
Landroid/graphics/Typeface;->setDefault(Landroid/graphics/Typeface;)V
Landroid/graphics/Typeface;->sSystemFontMap:Ljava/util/Map;
+Landroid/hardware/camera2/CameraCharacteristics$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;J)V
+Landroid/hardware/camera2/CaptureRequest$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;J)V
+Landroid/hardware/camera2/CaptureResult$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;J)V
+Landroid/hardware/camera2/impl/CameraMetadataNative;->mMetadataPtr:J
Landroid/hardware/Camera;->addCallbackBuffer([BI)V
+Landroid/hardware/Camera;->mNativeContext:J
Landroid/hardware/Camera;->openLegacy(II)Landroid/hardware/Camera;
+Landroid/hardware/Camera;->postEventFromNative(Ljava/lang/Object;IIILjava/lang/Object;)V
Landroid/hardware/display/DisplayManager;->getStableDisplaySize()Landroid/graphics/Point;
Landroid/hardware/display/WifiDisplayStatus;->mActiveDisplay:Landroid/hardware/display/WifiDisplay;
Landroid/hardware/display/WifiDisplayStatus;->mDisplays:[Landroid/hardware/display/WifiDisplay;
+Landroid/hardware/HardwareBuffer;-><init>(J)V
+Landroid/hardware/HardwareBuffer;->mNativeObject:J
Landroid/hardware/input/IInputManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/input/IInputManager;
Landroid/hardware/input/InputManager;->getInstance()Landroid/hardware/input/InputManager;
Landroid/hardware/input/InputManager;->mIm:Landroid/hardware/input/IInputManager;
@@ -422,19 +712,113 @@
Landroid/hardware/location/NanoAppInstanceInfo;->getAppVersion()I
Landroid/hardware/location/NanoAppInstanceInfo;->getHandle()I
Landroid/hardware/location/NanoAppInstanceInfo;->getName()Ljava/lang/String;
+Landroid/hardware/SerialPort;->mNativeContext:I
+Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;->confidenceLevel:I
+Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;-><init>(II)V
+Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;->userId:I
+Landroid/hardware/soundtrigger/SoundTrigger$GenericRecognitionEvent;-><init>(IIZIIIZLandroid/media/AudioFormat;[B)V
+Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->id:I
+Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->locale:Ljava/lang/String;
+Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionEvent;-><init>(IIZIIIZLandroid/media/AudioFormat;[B[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;)V
+Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;->coarseConfidenceLevel:I
+Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;->confidenceLevels:[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;
+Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;->id:I
+Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;-><init>(III[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;)V
+Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;->recognitionModes:I
+Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->recognitionModes:I
+Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseSoundModel;->keyphrases:[Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;
+Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->text:Ljava/lang/String;
+Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->users:[I
+Landroid/hardware/soundtrigger/SoundTriggerModule;->mId:I
+Landroid/hardware/soundtrigger/SoundTriggerModule;->mNativeContext:J
+Landroid/hardware/soundtrigger/SoundTriggerModule;->postEventFromNative(Ljava/lang/Object;IIILjava/lang/Object;)V
+Landroid/hardware/soundtrigger/SoundTrigger$ModuleProperties;-><init>(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIZIZIZ)V
+Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;->captureRequested:Z
+Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;->data:[B
+Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;->keyphrases:[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;
+Landroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;-><init>(IIZIIIZLandroid/media/AudioFormat;[B)V
+Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;->data:[B
+Landroid/hardware/soundtrigger/SoundTrigger$SoundModelEvent;-><init>(II[B)V
+Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;->uuid:Ljava/util/UUID;
+Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;->vendorUuid:Ljava/util/UUID;
+Landroid/hardware/SystemSensorManager$BaseEventQueue;->dispatchAdditionalInfoEvent(III[F[I)V
+Landroid/hardware/SystemSensorManager$BaseEventQueue;->dispatchFlushCompleteEvent(I)V
+Landroid/hardware/SystemSensorManager$BaseEventQueue;->dispatchSensorEvent(I[FIJ)V
+Landroid/hardware/usb/UsbDeviceConnection;->mNativeContext:J
Landroid/hardware/usb/UsbManager;->setCurrentFunction(Ljava/lang/String;Z)V
+Landroid/hardware/usb/UsbRequest;->mNativeContext:J
+Landroid/icu/impl/number/DecimalFormatProperties;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/impl/number/DecimalFormatProperties;->writeObject(Ljava/io/ObjectOutputStream;)V
+Landroid/icu/impl/TimeZoneGenericNames;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/text/DateFormat;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/text/DateFormatSymbols;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/text/DateIntervalFormat;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/text/DecimalFormat_ICU58_Android;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/text/DecimalFormat_ICU58_Android;->writeObject(Ljava/io/ObjectOutputStream;)V
+Landroid/icu/text/DecimalFormat;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/text/DecimalFormatSymbols;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/text/DecimalFormat;->writeObject(Ljava/io/ObjectOutputStream;)V
+Landroid/icu/text/MessageFormat;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/text/MessageFormat;->writeObject(Ljava/io/ObjectOutputStream;)V
+Landroid/icu/text/NumberFormat;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/text/NumberFormat;->writeObject(Ljava/io/ObjectOutputStream;)V
+Landroid/icu/text/PluralFormat;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/text/PluralRules$FixedDecimal;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/text/PluralRules$FixedDecimal;->writeObject(Ljava/io/ObjectOutputStream;)V
+Landroid/icu/text/PluralRules;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/text/PluralRules;->writeObject(Ljava/io/ObjectOutputStream;)V
+Landroid/icu/text/RuleBasedNumberFormat;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/text/RuleBasedNumberFormat;->writeObject(Ljava/io/ObjectOutputStream;)V
+Landroid/icu/text/SelectFormat;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/text/SimpleDateFormat;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/text/SimpleDateFormat;->writeObject(Ljava/io/ObjectOutputStream;)V
+Landroid/icu/text/TimeZoneFormat;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/text/TimeZoneFormat;->writeObject(Ljava/io/ObjectOutputStream;)V
+Landroid/icu/util/Calendar;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/util/Calendar;->writeObject(Ljava/io/ObjectOutputStream;)V
+Landroid/icu/util/ChineseCalendar;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/util/IslamicCalendar;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/icu/util/SimpleTimeZone;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/location/CountryDetector;->detectCountry()Landroid/location/Country;
+Landroid/location/Country;->getCountryIso()Ljava/lang/String;
+Landroid/location/Country;->getSource()I
Landroid/location/GeocoderParams;->getClientPackage()Ljava/lang/String;
Landroid/location/GeocoderParams;->getLocale()Ljava/util/Locale;
+Landroid/location/ILocationManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/location/LocationManager;->mService:Landroid/location/ILocationManager;
Landroid/location/LocationManager;->requestLocationUpdates(Landroid/location/LocationRequest;Landroid/location/LocationListener;Landroid/os/Looper;)V
Landroid/location/LocationRequest;->createFromDeprecatedProvider(Ljava/lang/String;JFZ)Landroid/location/LocationRequest;
Landroid/location/LocationRequest;->setHideFromAppOps(Z)V
Landroid/location/LocationRequest;->setWorkSource(Landroid/os/WorkSource;)V
Landroid/location/Location;->setIsFromMockProvider(Z)V
+Landroid/Manifest$permission;->REAL_GET_TASKS:Ljava/lang/String;
Landroid/media/AudioAttributes$Builder;->setInternalCapturePreset(I)Landroid/media/AudioAttributes$Builder;
+Landroid/media/AudioAttributes;->mContentType:I
+Landroid/media/AudioAttributes;->mFlags:I
+Landroid/media/AudioAttributes;->mFormattedTags:Ljava/lang/String;
+Landroid/media/AudioAttributes;->mSource:I
+Landroid/media/AudioAttributes;->mUsage:I
+Landroid/media/AudioDevicePortConfig;-><init>(Landroid/media/AudioDevicePort;IIILandroid/media/AudioGainConfig;)V
+Landroid/media/AudioDevicePort;-><init>(Landroid/media/AudioHandle;Ljava/lang/String;[I[I[I[I[Landroid/media/AudioGain;ILjava/lang/String;)V
Landroid/media/AudioFocusInfo;->getClientId()Ljava/lang/String;
Landroid/media/AudioFocusInfo;->getClientUid()I
Landroid/media/AudioFocusInfo;->getLossReceived()I
+Landroid/media/AudioFormat;-><init>(IIII)V
+Landroid/media/AudioFormat;->mChannelMask:I
+Landroid/media/AudioFormat;->mEncoding:I
+Landroid/media/AudioFormat;->mSampleRate:I
+Landroid/media/audiofx/AudioEffect;-><init>(Ljava/util/UUID;Ljava/util/UUID;II)V
+Landroid/media/AudioGainConfig;-><init>(ILandroid/media/AudioGain;II[II)V
+Landroid/media/AudioGainConfig;->mChannelMask:I
+Landroid/media/AudioGainConfig;->mIndex:I
+Landroid/media/AudioGainConfig;->mMode:I
+Landroid/media/AudioGainConfig;->mRampDurationMs:I
+Landroid/media/AudioGainConfig;->mValues:[I
+Landroid/media/AudioGain;-><init>(IIIIIIIII)V
+Landroid/media/AudioHandle;-><init>(I)V
+Landroid/media/AudioHandle;->mId:I
Landroid/media/AudioManager;->abandonAudioFocus(Landroid/media/AudioManager$OnAudioFocusChangeListener;Landroid/media/AudioAttributes;)I
+Landroid/media/AudioManager;->getService()Landroid/media/IAudioService;
Landroid/media/AudioManager;->mAudioFocusIdListenerMap:Ljava/util/concurrent/ConcurrentHashMap;
Landroid/media/AudioManager;->registerAudioPolicy(Landroid/media/audiopolicy/AudioPolicy;)I
Landroid/media/AudioManager;->requestAudioFocus(Landroid/media/AudioFocusRequest;Landroid/media/audiopolicy/AudioPolicy;)I
@@ -445,13 +829,28 @@
Landroid/media/AudioManager;->STREAM_SYSTEM_ENFORCED:I
Landroid/media/AudioManager;->STREAM_TTS:I
Landroid/media/AudioManager;->unregisterAudioPolicyAsync(Landroid/media/audiopolicy/AudioPolicy;)V
+Landroid/media/AudioMixPortConfig;-><init>(Landroid/media/AudioMixPort;IIILandroid/media/AudioGainConfig;)V
+Landroid/media/AudioMixPort;-><init>(Landroid/media/AudioHandle;IILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V
+Landroid/media/AudioPatch;-><init>(Landroid/media/AudioHandle;[Landroid/media/AudioPortConfig;[Landroid/media/AudioPortConfig;)V
+Landroid/media/AudioPatch;->mHandle:Landroid/media/AudioHandle;
Landroid/media/audiopolicy/AudioMix$Builder;->build()Landroid/media/audiopolicy/AudioMix;
Landroid/media/audiopolicy/AudioMix$Builder;-><init>(Landroid/media/audiopolicy/AudioMixingRule;)V
Landroid/media/audiopolicy/AudioMix$Builder;->setFormat(Landroid/media/AudioFormat;)Landroid/media/audiopolicy/AudioMix$Builder;
Landroid/media/audiopolicy/AudioMix$Builder;->setRouteFlags(I)Landroid/media/audiopolicy/AudioMix$Builder;
+Landroid/media/audiopolicy/AudioMixingRule$AudioMixMatchCriterion;->mAttr:Landroid/media/AudioAttributes;
+Landroid/media/audiopolicy/AudioMixingRule$AudioMixMatchCriterion;->mIntProp:I
+Landroid/media/audiopolicy/AudioMixingRule$AudioMixMatchCriterion;->mRule:I
Landroid/media/audiopolicy/AudioMixingRule$Builder;->addRule(Landroid/media/AudioAttributes;I)Landroid/media/audiopolicy/AudioMixingRule$Builder;
Landroid/media/audiopolicy/AudioMixingRule$Builder;->build()Landroid/media/audiopolicy/AudioMixingRule;
Landroid/media/audiopolicy/AudioMixingRule$Builder;-><init>()V
+Landroid/media/audiopolicy/AudioMixingRule;->mCriteria:Ljava/util/ArrayList;
+Landroid/media/audiopolicy/AudioMix;->mCallbackFlags:I
+Landroid/media/audiopolicy/AudioMix;->mDeviceAddress:Ljava/lang/String;
+Landroid/media/audiopolicy/AudioMix;->mDeviceSystemType:I
+Landroid/media/audiopolicy/AudioMix;->mFormat:Landroid/media/AudioFormat;
+Landroid/media/audiopolicy/AudioMix;->mMixType:I
+Landroid/media/audiopolicy/AudioMix;->mRouteFlags:I
+Landroid/media/audiopolicy/AudioMix;->mRule:Landroid/media/audiopolicy/AudioMixingRule;
Landroid/media/audiopolicy/AudioPolicy$AudioPolicyFocusListener;-><init>()V
Landroid/media/audiopolicy/AudioPolicy$Builder;->addMix(Landroid/media/audiopolicy/AudioMix;)Landroid/media/audiopolicy/AudioPolicy$Builder;
Landroid/media/audiopolicy/AudioPolicy$Builder;->build()Landroid/media/audiopolicy/AudioPolicy;
@@ -459,18 +858,54 @@
Landroid/media/audiopolicy/AudioPolicy$Builder;->setAudioPolicyFocusListener(Landroid/media/audiopolicy/AudioPolicy$AudioPolicyFocusListener;)V
Landroid/media/audiopolicy/AudioPolicy$Builder;->setLooper(Landroid/os/Looper;)Landroid/media/audiopolicy/AudioPolicy$Builder;
Landroid/media/audiopolicy/AudioPolicy;->createAudioRecordSink(Landroid/media/audiopolicy/AudioMix;)Landroid/media/AudioRecord;
+Landroid/media/AudioPortConfig;-><init>(Landroid/media/AudioPort;IIILandroid/media/AudioGainConfig;)V
+Landroid/media/AudioPortConfig;->mChannelMask:I
+Landroid/media/AudioPortConfig;->mConfigMask:I
+Landroid/media/AudioPortConfig;->mFormat:I
+Landroid/media/AudioPortConfig;->mGain:Landroid/media/AudioGainConfig;
+Landroid/media/AudioPortConfig;->mPort:Landroid/media/AudioPort;
+Landroid/media/AudioPortConfig;->mSamplingRate:I
+Landroid/media/AudioPortEventHandler;->mJniCallback:J
+Landroid/media/AudioPortEventHandler;->postEventFromNative(Ljava/lang/Object;IIILjava/lang/Object;)V
+Landroid/media/AudioPort;-><init>(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V
+Landroid/media/AudioPort;->mActiveConfig:Landroid/media/AudioPortConfig;
+Landroid/media/AudioPort;->mGains:[Landroid/media/AudioGain;
+Landroid/media/AudioPort;->mHandle:Landroid/media/AudioHandle;
+Landroid/media/AudioPort;->mRole:I
+Landroid/media/AudioRecord;->mNativeCallbackCookie:J
+Landroid/media/AudioRecord;->mNativeDeviceCallback:J
+Landroid/media/AudioRecord;->mNativeRecorderInJavaObj:J
+Landroid/media/AudioRecord;->postEventFromNative(Ljava/lang/Object;IIILjava/lang/Object;)V
+Landroid/media/AudioSystem;->dynamicPolicyCallbackFromNative(ILjava/lang/String;I)V
+Landroid/media/AudioSystem;->errorCallbackFromNative(I)V
+Landroid/media/AudioSystem;->getPrimaryOutputFrameCount()I
+Landroid/media/AudioSystem;->getPrimaryOutputSamplingRate()I
+Landroid/media/AudioSystem;->recordingCallbackFromNative(IIII[I)V
Landroid/media/AudioSystem;->setDeviceConnectionState(IILjava/lang/String;Ljava/lang/String;)I
Landroid/media/AudioTrack;->getLatency()I
+Landroid/media/AudioTrack;->mJniData:J
+Landroid/media/AudioTrack;->mNativeTrackInJavaObj:J
+Landroid/media/AudioTrack;->mStreamType:I
+Landroid/media/AudioTrack;->postEventFromNative(Ljava/lang/Object;IIILjava/lang/Object;)V
Landroid/media/IAudioService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IAudioService;
+Landroid/media/JetPlayer;->mNativePlayerInJavaObj:J
+Landroid/media/JetPlayer;->postEventFromNative(Ljava/lang/Object;III)V
Landroid/media/MediaCodec;->releaseOutputBuffer(IZZJ)V
+Landroid/media/MediaFile;->FIRST_AUDIO_FILE_TYPE:I
Landroid/media/MediaFile;->getFileType(Ljava/lang/String;)Landroid/media/MediaFile$MediaFileType;
Landroid/media/MediaFile;->getMimeTypeForFile(Ljava/lang/String;)Ljava/lang/String;
+Landroid/media/MediaFile;-><init>()V
+Landroid/media/MediaFile;->isAudioFileType(I)Z
+Landroid/media/MediaFile;->isImageFileType(I)Z
Landroid/media/MediaFile;->isVideoFileType(I)Z
+Landroid/media/MediaFile;->LAST_AUDIO_FILE_TYPE:I
Landroid/media/MediaFile$MediaFileType;->fileType:I
+Landroid/media/MediaFile$MediaFileType;->mimeType:Ljava/lang/String;
Landroid/media/MediaFile;->sFileTypeMap:Ljava/util/HashMap;
Landroid/media/MediaMetadataRetriever;->getEmbeddedPicture(I)[B
Landroid/media/MediaPlayer;->getMetadata(ZZ)Landroid/media/Metadata;
Landroid/media/MediaPlayer;->invoke(Landroid/os/Parcel;Landroid/os/Parcel;)V
+Landroid/media/MediaPlayer;->mEventHandler:Landroid/media/MediaPlayer$EventHandler;
Landroid/media/MediaPlayer;->newRequest()Landroid/os/Parcel;
Landroid/media/MediaPlayer;->setDataSource(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;Ljava/util/List;)V
Landroid/media/MediaPlayer;->setDataSource(Ljava/lang/String;Ljava/util/Map;Ljava/util/List;)V
@@ -482,12 +917,47 @@
Landroid/media/MediaRouter;->selectRouteInt(ILandroid/media/MediaRouter$RouteInfo;Z)V
Landroid/media/MediaScanner;->mClient:Landroid/media/MediaScanner$MyMediaScannerClient;
Landroid/media/MediaScanner;->scanSingleFile(Ljava/lang/String;Ljava/lang/String;)Landroid/net/Uri;
+Landroid/media/Metadata;->getBoolean(I)Z
+Landroid/media/Metadata;->has(I)Z
+Landroid/media/Metadata;->PAUSE_AVAILABLE:I
+Landroid/media/Metadata;->SEEK_BACKWARD_AVAILABLE:I
+Landroid/media/Metadata;->SEEK_FORWARD_AVAILABLE:I
+Landroid/media/MicrophoneInfo;-><init>(Ljava/lang/String;ILjava/lang/String;IIILandroid/media/MicrophoneInfo$Coordinate3F;Landroid/media/MicrophoneInfo$Coordinate3F;Ljava/util/List;Ljava/util/List;FFFI)V
Landroid/media/MiniThumbFile;->reset()V
+Landroid/media/PlaybackParams;->mAudioFallbackMode:I
+Landroid/media/PlaybackParams;->mAudioStretchMode:I
+Landroid/media/PlaybackParams;->mPitch:F
+Landroid/media/PlaybackParams;->mSet:I
+Landroid/media/PlaybackParams;->mSpeed:F
+Landroid/media/PlaybackParams;->SET_AUDIO_FALLBACK_MODE:I
+Landroid/media/PlaybackParams;->SET_AUDIO_STRETCH_MODE:I
+Landroid/media/PlaybackParams;->SET_PITCH:I
+Landroid/media/PlaybackParams;->SET_SPEED:I
+Landroid/media/RemoteDisplay;->notifyDisplayConnected(Landroid/view/Surface;IIII)V
+Landroid/media/RemoteDisplay;->notifyDisplayDisconnected()V
+Landroid/media/RemoteDisplay;->notifyDisplayError(I)V
Landroid/media/RingtoneManager;->getRingtone(Landroid/content/Context;Landroid/net/Uri;I)Landroid/media/Ringtone;
Landroid/media/Ringtone;->setLooping(Z)V
Landroid/media/Ringtone;->setVolume(F)V
+Landroid/media/session/MediaSessionLegacyHelper;->getHelper(Landroid/content/Context;)Landroid/media/session/MediaSessionLegacyHelper;
Landroid/media/SubtitleController;->mHandler:Landroid/os/Handler;
Landroid/media/ThumbnailUtils;->createImageThumbnail(Ljava/lang/String;I)Landroid/graphics/Bitmap;
+Landroid/media/ToneGenerator;->mNativeContext:J
+Landroid/media/VolumeShaper$Configuration;-><init>(IIIDI[F[F)V
+Landroid/media/VolumeShaper$Configuration;->mDurationMs:D
+Landroid/media/VolumeShaper$Configuration;->mId:I
+Landroid/media/VolumeShaper$Configuration;->mInterpolatorType:I
+Landroid/media/VolumeShaper$Configuration;->mOptionFlags:I
+Landroid/media/VolumeShaper$Configuration;->mTimes:[F
+Landroid/media/VolumeShaper$Configuration;->mType:I
+Landroid/media/VolumeShaper$Configuration;->mVolumes:[F
+Landroid/media/VolumeShaper$Operation;-><init>(IIF)V
+Landroid/media/VolumeShaper$Operation;->mFlags:I
+Landroid/media/VolumeShaper$Operation;->mReplaceId:I
+Landroid/media/VolumeShaper$Operation;->mXOffset:F
+Landroid/media/VolumeShaper$State;-><init>(FF)V
+Landroid/media/VolumeShaper$State;->mVolume:F
+Landroid/media/VolumeShaper$State;->mXOffset:F
Landroid/metrics/LogMaker;->getCategory()I
Landroid/metrics/LogMaker;->getCounterBucket()J
Landroid/metrics/LogMaker;->getCounterName()Ljava/lang/String;
@@ -519,8 +989,23 @@
Landroid/net/ConnectivityManager;->startTethering(IZLandroid/net/ConnectivityManager$OnStartTetheringCallback;Landroid/os/Handler;)V
Landroid/net/ConnectivityManager;->startTethering(IZLandroid/net/ConnectivityManager$OnStartTetheringCallback;)V
Landroid/net/ConnectivityManager;->stopTethering(I)V
+Landroid/net/ConnectivityManager;->TYPE_MOBILE_CBS:I
+Landroid/net/ConnectivityManager;->TYPE_MOBILE_EMERGENCY:I
+Landroid/net/ConnectivityManager;->TYPE_MOBILE_FOTA:I
+Landroid/net/ConnectivityManager;->TYPE_MOBILE_IA:I
+Landroid/net/ConnectivityManager;->TYPE_MOBILE_IMS:I
+Landroid/net/ConnectivityManager;->TYPE_NONE:I
+Landroid/net/ConnectivityManager;->TYPE_PROXY:I
+Landroid/net/ConnectivityManager;->TYPE_WIFI_P2P:I
+Landroid/net/IConnectivityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/IConnectivityManager;
+Landroid/net/IConnectivityManager$Stub$Proxy;->getAllNetworks()[Landroid/net/Network;
+Landroid/net/IConnectivityManager$Stub$Proxy;->getTetherableIfaces()[Ljava/lang/String;
+Landroid/net/IConnectivityManager$Stub$Proxy;->getTetherableUsbRegexs()[Ljava/lang/String;
+Landroid/net/IConnectivityManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/net/INetworkStatsService$Stub$Proxy;->getMobileIfaces()[Ljava/lang/String;
Landroid/net/LinkProperties;->setHttpProxy(Landroid/net/ProxyInfo;)V
+Landroid/net/LocalSocketImpl;->inboundFileDescriptors:[Ljava/io/FileDescriptor;
+Landroid/net/LocalSocketImpl;->outboundFileDescriptors:[Ljava/io/FileDescriptor;
Landroid/net/NetworkKey;-><init>(Landroid/net/WifiKey;)V
Landroid/net/NetworkPolicyManager;->mService:Landroid/net/INetworkPolicyManager;
Landroid/net/NetworkRecommendationProvider;-><init>(Landroid/content/Context;Ljava/util/concurrent/Executor;)V
@@ -541,6 +1026,7 @@
Landroid/net/NetworkStats;->txBytes:[J
Landroid/net/NetworkStats;->txPackets:[J
Landroid/net/NetworkStats;->uid:[I
+Landroid/net/ProxyInfo;-><init>(Ljava/lang/String;ILjava/lang/String;)V
Landroid/net/RssiCurve;-><init>(II[BI)V
Landroid/net/RssiCurve;-><init>(II[B)V
Landroid/net/RssiCurve;->lookupScore(IZ)B
@@ -571,11 +1057,17 @@
Landroid/net/SSLCertificateSocketFactory;->TAG:Ljava/lang/String;
Landroid/net/SSLCertificateSocketFactory;->toLengthPrefixedList([[[B)[B
Landroid/net/SSLCertificateSocketFactory;->verifyHostname(Ljava/net/Socket;Ljava/lang/String;)V
+Landroid/net/SSLSessionCache;->mSessionCache:Lcom/android/org/conscrypt/SSLClientSessionCache;
+Landroid/net/TrafficStats;->getRxBytes(Ljava/lang/String;)J
Landroid/net/TrafficStats;->getStatsService()Landroid/net/INetworkStatsService;
+Landroid/net/TrafficStats;->getTxBytes(Ljava/lang/String;)J
Landroid/net/TrafficStats;->setThreadStatsTagBackup()V
Landroid/net/TrafficStats;->setThreadStatsTagRestore()V
Landroid/net/TrafficStats;->setThreadStatsUid(I)V
+Landroid/net/Uri;-><init>()V
Landroid/net/WebAddress;-><init>(Ljava/lang/String;)V
+Landroid/net/wifi/IWifiManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/IWifiManager;
+Landroid/net/wifi/IWifiManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/net/WifiKey;-><init>(Ljava/lang/String;Ljava/lang/String;)V
Landroid/net/wifi/p2p/WifiP2pGroup;->getNetworkId()I
Landroid/net/wifi/p2p/WifiP2pGroupList;->getGroupList()Ljava/util/Collection;
@@ -585,13 +1077,30 @@
Landroid/net/wifi/RttManager;->getRttCapabilities()Landroid/net/wifi/RttManager$RttCapabilities;
Landroid/net/wifi/RttManager$RttParams;-><init>()V
Landroid/net/wifi/RttManager;->startRanging([Landroid/net/wifi/RttManager$RttParams;Landroid/net/wifi/RttManager$RttListener;)V
+Landroid/net/wifi/ScanResult;->anqpDomainId:I
+Landroid/net/wifi/ScanResult;->anqpLines:Ljava/util/List;
+Landroid/net/wifi/ScanResult;->distanceCm:I
+Landroid/net/wifi/ScanResult;->distanceSdCm:I
+Landroid/net/wifi/ScanResult;->flags:J
+Landroid/net/wifi/ScanResult;->hessid:J
+Landroid/net/wifi/ScanResult;->numUsage:I
+Landroid/net/wifi/ScanResult;->seen:J
+Landroid/net/wifi/ScanResult;->untrusted:Z
+Landroid/net/wifi/ScanResult;->wifiSsid:Landroid/net/wifi/WifiSsid;
Landroid/net/wifi/WifiConfiguration;->apBand:I
Landroid/net/wifi/WifiConfiguration;->apChannel:I
+Landroid/net/wifi/WifiConfiguration;->creatorUid:I
Landroid/net/wifi/WifiConfiguration;->hasNoInternetAccess()Z
Landroid/net/wifi/WifiConfiguration;->isEphemeral()Z
Landroid/net/wifi/WifiConfiguration;->isNoInternetAccessExpected()Z
+Landroid/net/wifi/WifiConfiguration;->lastUpdateUid:I
Landroid/net/wifi/WifiConfiguration;->mIpConfiguration:Landroid/net/IpConfiguration;
+Landroid/net/wifi/WifiConfiguration;->numAssociation:I
Landroid/net/wifi/WifiConfiguration;->validatedInternetAccess:Z
+Landroid/net/wifi/WifiEnterpriseConfig;->getCaCertificateAlias()Ljava/lang/String;
+Landroid/net/wifi/WifiEnterpriseConfig;->getClientCertificateAlias()Ljava/lang/String;
+Landroid/net/wifi/WifiInfo;->getMeteredHint()Z
+Landroid/net/wifi/WifiManager;->cancelLocalOnlyHotspotRequest()V
Landroid/net/wifi/WifiManager;->connect(ILandroid/net/wifi/WifiManager$ActionListener;)V
Landroid/net/wifi/WifiManager;->connect(Landroid/net/wifi/WifiConfiguration;Landroid/net/wifi/WifiManager$ActionListener;)V
Landroid/net/wifi/WifiManager;->EXTRA_WIFI_AP_STATE:Ljava/lang/String;
@@ -636,6 +1145,7 @@
Landroid/os/AsyncTask;->mWorker:Landroid/os/AsyncTask$WorkerRunnable;
Landroid/os/AsyncTask;->sDefaultExecutor:Ljava/util/concurrent/Executor;
Landroid/os/AsyncTask;->setDefaultExecutor(Ljava/util/concurrent/Executor;)V
+Landroid/os/BatteryStats;->getUidStats()Landroid/util/SparseArray;
Landroid/os/BatteryStats$HistoryItem;->states2:I
Landroid/os/BatteryStats;->NUM_DATA_CONNECTION_TYPES:I
Landroid/os/BatteryStats$Timer;->getTotalTimeLocked(JI)J
@@ -650,18 +1160,45 @@
Landroid/os/BatteryStats$Uid$Proc;->getUserTime(I)J
Landroid/os/BatteryStats$Uid$Sensor;->getHandle()I
Landroid/os/BatteryStats$Uid$Sensor;->getSensorTime()Landroid/os/BatteryStats$Timer;
+Landroid/os/Binder;->execTransact(IJJI)Z
+Landroid/os/Binder;->mObject:J
Landroid/os/Build;->getString(Ljava/lang/String;)Ljava/lang/String;
+Landroid/os/Build$VERSION;->ACTIVE_CODENAMES:[Ljava/lang/String;
+Landroid/os/Build$VERSION;->RESOURCES_SDK_INT:I
Landroid/os/Bundle;->getIBinder(Ljava/lang/String;)Landroid/os/IBinder;
Landroid/os/Bundle;->putIBinder(Ljava/lang/String;Landroid/os/IBinder;)V
Landroid/os/Debug;->countInstancesOfClass(Ljava/lang/Class;)J
Landroid/os/Debug;->dumpReferenceTables()V
+Landroid/os/Debug$MemoryInfo;->dalvikPrivateClean:I
+Landroid/os/Debug$MemoryInfo;->dalvikRss:I
+Landroid/os/Debug$MemoryInfo;->dalvikSharedClean:I
+Landroid/os/Debug$MemoryInfo;->dalvikSwappablePss:I
+Landroid/os/Debug$MemoryInfo;->dalvikSwappedOut:I
+Landroid/os/Debug$MemoryInfo;->dalvikSwappedOutPss:I
Landroid/os/Debug$MemoryInfo;->getOtherLabel(I)Ljava/lang/String;
Landroid/os/Debug$MemoryInfo;->getOtherPrivateDirty(I)I
+Landroid/os/Debug$MemoryInfo;->getOtherPrivate(I)I
Landroid/os/Debug$MemoryInfo;->getOtherPss(I)I
Landroid/os/Debug$MemoryInfo;->getOtherSharedDirty(I)I
+Landroid/os/Debug$MemoryInfo;->getTotalUss()I
+Landroid/os/Debug$MemoryInfo;->hasSwappedOutPss:Z
+Landroid/os/Debug$MemoryInfo;->nativePrivateClean:I
+Landroid/os/Debug$MemoryInfo;->nativeRss:I
+Landroid/os/Debug$MemoryInfo;->nativeSharedClean:I
+Landroid/os/Debug$MemoryInfo;->nativeSwappablePss:I
+Landroid/os/Debug$MemoryInfo;->nativeSwappedOut:I
+Landroid/os/Debug$MemoryInfo;->nativeSwappedOutPss:I
Landroid/os/Debug$MemoryInfo;->NUM_DVK_STATS:I
Landroid/os/Debug$MemoryInfo;->NUM_OTHER_STATS:I
+Landroid/os/Debug$MemoryInfo;->otherPrivateClean:I
+Landroid/os/Debug$MemoryInfo;->otherRss:I
+Landroid/os/Debug$MemoryInfo;->otherSharedClean:I
+Landroid/os/Debug$MemoryInfo;->otherStats:[I
+Landroid/os/Debug$MemoryInfo;->otherSwappablePss:I
+Landroid/os/Debug$MemoryInfo;->otherSwappedOut:I
+Landroid/os/Debug$MemoryInfo;->otherSwappedOutPss:I
Landroid/os/Environment;->buildExternalStorageAppDataDirs(Ljava/lang/String;)[Ljava/io/File;
+Landroid/os/FileObserver$ObserverThread;->onEvent(IILjava/lang/String;)V
Landroid/os/FileUtils;->checksumCrc32(Ljava/io/File;)J
Landroid/os/FileUtils;->copyFile(Ljava/io/File;Ljava/io/File;)Z
Landroid/os/FileUtils;->copyToFile(Ljava/io/InputStream;Ljava/io/File;)Z
@@ -676,21 +1213,40 @@
Landroid/os/Handler;->hasCallbacks(Ljava/lang/Runnable;)Z
Landroid/os/Handler;->mCallback:Landroid/os/Handler$Callback;
Landroid/os/Handler;->mMessenger:Landroid/os/IMessenger;
+Landroid/os/HwParcel;-><init>(Z)V
+Landroid/os/IPermissionController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPermissionController;
+Landroid/os/IPermissionController$Stub$Proxy;->checkPermission(Ljava/lang/String;II)Z
Landroid/os/IPowerManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPowerManager;
+Landroid/os/IPowerManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/os/IPowerManager$Stub$Proxy;->isLightDeviceIdleMode()Z
Landroid/os/IPowerManager;->userActivity(JII)V
+Landroid/os/IServiceManager;->getService(Ljava/lang/String;)Landroid/os/IBinder;
+Landroid/os/IUserManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/os/Looper;->mQueue:Landroid/os/MessageQueue;
+Landroid/os/Looper;->setTraceTag(J)V
+Landroid/os/Looper;->sThreadLocal:Ljava/lang/ThreadLocal;
Landroid/os/MemoryFile;->getFileDescriptor()Ljava/io/FileDescriptor;
Landroid/os/Message;->callback:Ljava/lang/Runnable;
Landroid/os/Message;->flags:I
+Landroid/os/Message;->markInUse()V
Landroid/os/Message;->next:Landroid/os/Message;
+Landroid/os/MessageQueue;->dispatchEvents(II)I
Landroid/os/MessageQueue;->mIdleHandlers:Ljava/util/ArrayList;
Landroid/os/MessageQueue;->mMessages:Landroid/os/Message;
+Landroid/os/MessageQueue;->mPtr:J
Landroid/os/MessageQueue;->mQuitAllowed:Z
+Landroid/os/MessageQueue;->nativePollOnce(JI)V
Landroid/os/MessageQueue;->next()Landroid/os/Message;
+Landroid/os/Message;->recycleUnchecked()V
Landroid/os/Message;->target:Landroid/os/Handler;
+Landroid/os/Message;->when:J
+Landroid/os/ParcelFileDescriptor;-><init>(Ljava/io/FileDescriptor;)V
+Landroid/os/Parcel;->mNativePtr:J
+Landroid/os/Parcel$ReadWriteHelper;-><init>()V
Landroid/os/PowerManager;->getMaximumScreenBrightnessSetting()I
Landroid/os/PowerManager;->getMinimumScreenBrightnessSetting()I
Landroid/os/PowerManager;->isLightDeviceIdleMode()Z
+Landroid/os/PowerManager;->mService:Landroid/os/IPowerManager;
Landroid/os/PowerManager;->userActivity(JII)V
Landroid/os/PowerManager;->userActivity(JZ)V
Landroid/os/PowerManager;->validateWakeLockParameters(ILjava/lang/String;)V
@@ -698,6 +1254,7 @@
Landroid/os/PowerManager;->wakeUp(J)V
Landroid/os/Process;->getParentPid(I)I
Landroid/os/Process;->getPids(Ljava/lang/String;[I)[I
+Landroid/os/Process;->getTotalMemory()J
Landroid/os/Process;->getUidForPid(I)I
Landroid/os/Process;->isIsolated(I)Z
Landroid/os/Process;->isIsolated()Z
@@ -711,18 +1268,30 @@
Landroid/os/RecoverySystem;->scheduleUpdateOnBoot(Landroid/content/Context;Ljava/io/File;)V
Landroid/os/SELinux;->isSELinuxEnabled()Z
Landroid/os/SELinux;->isSELinuxEnforced()Z
+Landroid/os/ServiceManager;->addService(Ljava/lang/String;Landroid/os/IBinder;)V
Landroid/os/ServiceManager;->checkService(Ljava/lang/String;)Landroid/os/IBinder;
+Landroid/os/ServiceManager;->getIServiceManager()Landroid/os/IServiceManager;
Landroid/os/ServiceManager;->getService(Ljava/lang/String;)Landroid/os/IBinder;
+Landroid/os/ServiceManager;-><init>()V
+Landroid/os/ServiceManager;->listServices()[Ljava/lang/String;
+Landroid/os/ServiceManagerNative;->asInterface(Landroid/os/IBinder;)Landroid/os/IServiceManager;
+Landroid/os/ServiceManager;->sCache:Ljava/util/HashMap;
+Landroid/os/ServiceManager;->sServiceManager:Landroid/os/IServiceManager;
Landroid/os/storage/DiskInfo;->getDescription()Ljava/lang/String;
+Landroid/os/storage/IStorageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/storage/IStorageManager;
+Landroid/os/storage/IStorageManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/os/storage/StorageManager;->findVolumeByUuid(Ljava/lang/String;)Landroid/os/storage/VolumeInfo;
Landroid/os/storage/StorageManager;->getBestVolumeDescription(Landroid/os/storage/VolumeInfo;)Ljava/lang/String;
Landroid/os/storage/StorageManager;->getDisks()Ljava/util/List;
Landroid/os/storage/StorageManager;->getStorageBytesUntilLow(Ljava/io/File;)J
+Landroid/os/storage/StorageManager;->getStorageLowBytes(Ljava/io/File;)J
Landroid/os/storage/StorageManager;->getVolumeList(II)[Landroid/os/storage/StorageVolume;
Landroid/os/storage/StorageManager;->getVolumeList()[Landroid/os/storage/StorageVolume;
Landroid/os/storage/StorageManager;->getVolumePaths()[Ljava/lang/String;
Landroid/os/storage/StorageManager;->getVolumes()Ljava/util/List;
Landroid/os/storage/StorageManager;->getVolumeState(Ljava/lang/String;)Ljava/lang/String;
+Landroid/os/storage/StorageVolume;->allowMassStorage()Z
+Landroid/os/storage/StorageVolume;->getMaxFileSize()J
Landroid/os/storage/StorageVolume;->getPathFile()Ljava/io/File;
Landroid/os/storage/StorageVolume;->getPath()Ljava/lang/String;
Landroid/os/storage/StorageVolume;->getUserLabel()Ljava/lang/String;
@@ -733,6 +1302,9 @@
Landroid/os/storage/VolumeInfo;->getType()I
Landroid/os/storage/VolumeInfo;->isPrimary()Z
Landroid/os/storage/VolumeInfo;->isVisible()Z
+Landroid/os/StrictMode;->disableDeathOnFileUriExposure()V
+Landroid/os/StrictMode;->getThreadPolicyMask()I
+Landroid/os/StrictMode;->onBinderStrictModePolicyChange(I)V
Landroid/os/StrictMode;->violationsBeingTimed:Ljava/lang/ThreadLocal;
Landroid/os/SystemProperties;->addChangeCallback(Ljava/lang/Runnable;)V
Landroid/os/SystemProperties;->getBoolean(Ljava/lang/String;Z)Z
@@ -740,6 +1312,8 @@
Landroid/os/SystemProperties;->get(Ljava/lang/String;)Ljava/lang/String;
Landroid/os/SystemProperties;->get(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
Landroid/os/SystemProperties;->getLong(Ljava/lang/String;J)J
+Landroid/os/SystemProperties;-><init>()V
+Landroid/os/SystemProperties;->native_get(Ljava/lang/String;)Ljava/lang/String;
Landroid/os/SystemProperties;->PROP_NAME_MAX:I
Landroid/os/SystemProperties;->set(Ljava/lang/String;Ljava/lang/String;)V
Landroid/os/Trace;->asyncTraceBegin(JLjava/lang/String;I)V
@@ -764,16 +1338,19 @@
Landroid/os/UpdateLock;->isHeld()Z
Landroid/os/UpdateLock;->NOW_IS_CONVENIENT:Ljava/lang/String;
Landroid/os/UpdateLock;->release()V
+Landroid/os/UpdateLock;->TIMESTAMP:Ljava/lang/String;
Landroid/os/UpdateLock;->UPDATE_LOCK_CHANGED:Ljava/lang/String;
Landroid/os/UserHandle;->ALL:Landroid/os/UserHandle;
Landroid/os/UserHandle;->getAppIdFromSharedAppGid(I)I
Landroid/os/UserHandle;->getCallingUserId()I
Landroid/os/UserHandle;->getIdentifier()I
+Landroid/os/UserHandle;->getUid(II)I
Landroid/os/UserHandle;->getUserId(I)I
Landroid/os/UserHandle;-><init>(I)V
Landroid/os/UserHandle;->isOwner()Z
Landroid/os/UserHandle;->myUserId()I
Landroid/os/UserHandle;->of(I)Landroid/os/UserHandle;
+Landroid/os/UserHandle;->PER_USER_RANGE:I
Landroid/os/UserHandle;->USER_OWNER:I
Landroid/os/UserManager;->getBadgedLabelForUser(Ljava/lang/CharSequence;Landroid/os/UserHandle;)Ljava/lang/CharSequence;
Landroid/os/UserManager;->get(Landroid/content/Context;)Landroid/os/UserManager;
@@ -789,10 +1366,14 @@
Landroid/os/UserManager;->isLinkedUser()Z
Landroid/os/UserManager;->isManagedProfile()Z
Landroid/os/UserManager;->isUserUnlocked(I)Z
+Landroid/os/VintfObject;->report()[Ljava/lang/String;
Landroid/os/WorkSource;->add(ILjava/lang/String;)Z
Landroid/os/WorkSource;->add(I)Z
Landroid/os/WorkSource;->get(I)I
Landroid/os/WorkSource;->getName(I)Ljava/lang/String;
+Landroid/os/WorkSource;->mNames:[Ljava/lang/String;
+Landroid/os/WorkSource;->mNum:I
+Landroid/os/WorkSource;->mUids:[I
Landroid/os/WorkSource;->size()I
Landroid/preference/DialogPreference;->mBuilder:Landroid/app/AlertDialog$Builder;
Landroid/preference/DialogPreference;->mDialogIcon:Landroid/graphics/drawable/Drawable;
@@ -812,6 +1393,7 @@
Landroid/preference/PreferenceManager;->getPreferenceScreen()Landroid/preference/PreferenceScreen;
Landroid/preference/PreferenceManager;->inflateFromIntent(Landroid/content/Intent;Landroid/preference/PreferenceScreen;)Landroid/preference/PreferenceScreen;
Landroid/preference/PreferenceManager;->inflateFromResource(Landroid/content/Context;ILandroid/preference/PreferenceScreen;)Landroid/preference/PreferenceScreen;
+Landroid/preference/PreferenceManager;-><init>(Landroid/app/Activity;I)V
Landroid/preference/PreferenceManager;->mActivityDestroyListeners:Ljava/util/List;
Landroid/preference/PreferenceManager;->mOnPreferenceTreeClickListener:Landroid/preference/PreferenceManager$OnPreferenceTreeClickListener;
Landroid/preference/PreferenceManager;->mSharedPreferences:Landroid/content/SharedPreferences;
@@ -828,20 +1410,34 @@
Landroid/print/PrinterId;->getServiceName()Landroid/content/ComponentName;
Landroid/print/PrintJobInfo;->getAdvancedOptions()Landroid/os/Bundle;
Landroid/print/PrintJobInfo;->getDocumentInfo()Landroid/print/PrintDocumentInfo;
+Landroid/provider/Browser;->BOOKMARKS_URI:Landroid/net/Uri;
Landroid/provider/Browser;->canClearHistory(Landroid/content/ContentResolver;)Z
Landroid/provider/Browser;->clearHistory(Landroid/content/ContentResolver;)V
Landroid/provider/Browser;->clearSearches(Landroid/content/ContentResolver;)V
Landroid/provider/Browser;->deleteFromHistory(Landroid/content/ContentResolver;Ljava/lang/String;)V
Landroid/provider/Browser;->getVisitedHistory(Landroid/content/ContentResolver;)[Ljava/lang/String;
Landroid/provider/Browser;->sendString(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)V
+Landroid/provider/Settings$ContentProviderHolder;->mContentProvider:Landroid/content/IContentProvider;
+Landroid/provider/Settings$Global;->ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED:Ljava/lang/String;
Landroid/provider/Settings$Global;->OTA_DISABLE_AUTOMATIC_UPDATE:Ljava/lang/String;
Landroid/provider/Settings$Global;->PACKAGE_VERIFIER_ENABLE:Ljava/lang/String;
+Landroid/provider/Settings$Global;->sNameValueCache:Landroid/provider/Settings$NameValueCache;
+Landroid/provider/Settings$NameValueCache;->mProviderHolder:Landroid/provider/Settings$ContentProviderHolder;
+Landroid/provider/Settings$Secure;->ACCESSIBILITY_AUTOCLICK_ENABLED:Ljava/lang/String;
+Landroid/provider/Settings$Secure;->ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED:Ljava/lang/String;
Landroid/provider/Settings$Secure;->ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED:Ljava/lang/String;
+Landroid/provider/Settings$Secure;->ACCESSIBILITY_LARGE_POINTER_ICON:Ljava/lang/String;
+Landroid/provider/Settings$Secure;->INCALL_POWER_BUTTON_BEHAVIOR:Ljava/lang/String;
+Landroid/provider/Settings$Secure;->LONG_PRESS_TIMEOUT:Ljava/lang/String;
Landroid/provider/Settings$Secure;->PACKAGE_VERIFIER_USER_CONSENT:Ljava/lang/String;
+Landroid/provider/Settings$Secure;->sNameValueCache:Landroid/provider/Settings$NameValueCache;
Landroid/provider/Settings$Secure;->USER_SETUP_COMPLETE:Ljava/lang/String;
Landroid/provider/Settings$System;->AIRPLANE_MODE_TOGGLEABLE_RADIOS:Ljava/lang/String;
Landroid/provider/Settings$System;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
+Landroid/provider/Settings$System;->HEARING_AID:Ljava/lang/String;
+Landroid/provider/Settings$System;->MASTER_MONO:Ljava/lang/String;
Landroid/provider/Settings$System;->putStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;I)Z
+Landroid/provider/Settings$System;->sNameValueCache:Landroid/provider/Settings$NameValueCache;
Landroid/provider/Telephony$Sms;->addMessageToUri(ILandroid/content/ContentResolver;Landroid/net/Uri;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;ZZJ)Landroid/net/Uri;
Landroid/provider/Telephony$Sms;->addMessageToUri(ILandroid/content/ContentResolver;Landroid/net/Uri;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;ZZ)Landroid/net/Uri;
Landroid/provider/Telephony$Sms;->addMessageToUri(Landroid/content/ContentResolver;Landroid/net/Uri;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;ZZJ)Landroid/net/Uri;
@@ -850,6 +1446,7 @@
Landroid/provider/Telephony$Sms$Inbox;->addMessage(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Z)Landroid/net/Uri;
Landroid/provider/Telephony$Sms$Sent;->addMessage(ILandroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;)Landroid/net/Uri;
Landroid/provider/Telephony$Sms$Sent;->addMessage(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;)Landroid/net/Uri;
+Landroid/renderscript/RenderScriptCacheDir;->mCacheDir:Ljava/io/File;
Landroid/renderscript/RenderScript;->create(Landroid/content/Context;I)Landroid/renderscript/RenderScript;
Landroid/renderscript/RenderScript;->create(Landroid/content/Context;ILandroid/renderscript/RenderScript$ContextType;I)Landroid/renderscript/RenderScript;
Landroid/renderscript/RenderScript;->getMinorID()J
@@ -857,14 +1454,17 @@
Landroid/R$styleable;->TextAppearance_textColor:I
Landroid/R$styleable;->TextAppearance_textSize:I
Landroid/security/KeyStore;->getInstance()Landroid/security/KeyStore;
+Landroid/security/net/config/RootTrustManager;->checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;Ljava/lang/String;)Ljava/util/List;
Landroid/service/media/IMediaBrowserServiceCallbacks;->onConnectFailed()V
Landroid/service/media/IMediaBrowserServiceCallbacks;->onConnect(Ljava/lang/String;Landroid/media/session/MediaSession$Token;Landroid/os/Bundle;)V
Landroid/service/media/IMediaBrowserServiceCallbacks;->onLoadChildren(Ljava/lang/String;Landroid/content/pm/ParceledListSlice;)V
Landroid/service/media/IMediaBrowserServiceCallbacks;->onLoadChildrenWithOptions(Ljava/lang/String;Landroid/content/pm/ParceledListSlice;Landroid/os/Bundle;)V
+Landroid/service/media/IMediaBrowserServiceCallbacks$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/media/IMediaBrowserServiceCallbacks;
Landroid/service/media/MediaBrowserService;->KEY_MEDIA_ITEM:Ljava/lang/String;
Landroid/service/media/MediaBrowserService$Result;->mFlags:I
Landroid/service/notification/NotificationListenerService;->registerAsSystemService(Landroid/content/Context;Landroid/content/ComponentName;I)V
Landroid/service/notification/NotificationListenerService;->unregisterAsSystemService()V
+Landroid/service/persistentdata/PersistentDataBlockManager;->getFlashLockState()I
Landroid/service/persistentdata/PersistentDataBlockManager;->getMaximumDataBlockSize()J
Landroid/service/persistentdata/PersistentDataBlockManager;->read()[B
Landroid/service/persistentdata/PersistentDataBlockManager;->write([B)I
@@ -879,6 +1479,7 @@
Landroid/service/voice/VoiceInteractionService;->isKeyphraseAndLocaleSupportedForHotword(Ljava/lang/String;Ljava/util/Locale;)Z
Landroid/service/wallpaper/WallpaperService$Engine;->setFixedSizeAllowed(Z)V
Landroid/speech/tts/TextToSpeech;->getCurrentEngine()Ljava/lang/String;
+Landroid/system/Int32Ref;->value:I
Landroid/system/StructTimeval;->fromMillis(J)Landroid/system/StructTimeval;
Landroid/telecom/AudioState;->getRoute()I
Landroid/telecom/AudioState;->getSupportedRouteMask()I
@@ -896,16 +1497,32 @@
Landroid/telecom/Phone;->setMuted(Z)V
Landroid/telecom/TelecomManager;->endCall()Z
Landroid/telecom/TelecomManager;->EXTRA_IS_HANDOVER:Ljava/lang/String;
+Landroid/telecom/TelecomManager;->getUserSelectedOutgoingPhoneAccount()Landroid/telecom/PhoneAccountHandle;
+Landroid/telecom/TelecomManager;->setUserSelectedOutgoingPhoneAccount(Landroid/telecom/PhoneAccountHandle;)V
+Landroid/telephony/CellSignalStrengthLte;->mCqi:I
+Landroid/telephony/CellSignalStrengthLte;->mRsrp:I
+Landroid/telephony/CellSignalStrengthLte;->mRsrq:I
+Landroid/telephony/CellSignalStrengthLte;->mRssnr:I
Landroid/telephony/PhoneStateListener;->mSubId:Ljava/lang/Integer;
Landroid/telephony/ServiceState;->newFromBundle(Landroid/os/Bundle;)Landroid/telephony/ServiceState;
+Landroid/telephony/SignalStrength;->getAsuLevel()I
Landroid/telephony/SignalStrength;->getCdmaLevel()I
+Landroid/telephony/SignalStrength;->getDbm()I
Landroid/telephony/SignalStrength;->getLteDbm()I
Landroid/telephony/SignalStrength;->getLteRsrp()I
+Landroid/telephony/SignalStrength;->getLteRsrq()I
Landroid/telephony/SignalStrength;->getLteRssnr()I
Landroid/telephony/SignalStrength;->getLteSignalStrength()I
+Landroid/telephony/SignalStrength;->SIGNAL_STRENGTH_GOOD:I
+Landroid/telephony/SignalStrength;->SIGNAL_STRENGTH_GREAT:I
+Landroid/telephony/SignalStrength;->SIGNAL_STRENGTH_MODERATE:I
+Landroid/telephony/SignalStrength;->SIGNAL_STRENGTH_NONE_OR_UNKNOWN:I
+Landroid/telephony/SignalStrength;->SIGNAL_STRENGTH_POOR:I
Landroid/telephony/SmsManager;->RESULT_ERROR_FDN_CHECK_FAILURE:I
Landroid/telephony/SmsMessage;->getSubId()I
Landroid/telephony/SmsMessage;->mWrappedSmsMessage:Lcom/android/internal/telephony/SmsMessageBase;
+Landroid/telephony/SubscriptionManager;->getAllSubscriptionInfoCount()I
+Landroid/telephony/SubscriptionManager;->getDefaultDataSubscriptionInfo()Landroid/telephony/SubscriptionInfo;
Landroid/telephony/SubscriptionManager;->getDefaultSmsPhoneId()I
Landroid/telephony/SubscriptionManager;->getPhoneId(I)I
Landroid/telephony/SubscriptionManager;->getSlotIndex(I)I
@@ -913,26 +1530,43 @@
Landroid/telephony/SubscriptionManager;->setDefaultSmsSubId(I)V
Landroid/telephony/TelephonyManager;->checkCarrierPrivilegesForPackage(Ljava/lang/String;)I
Landroid/telephony/TelephonyManager;->from(Landroid/content/Context;)Landroid/telephony/TelephonyManager;
+Landroid/telephony/TelephonyManager;->getCallState(I)I
Landroid/telephony/TelephonyManager;->getCarrierPackageNamesForIntent(Landroid/content/Intent;)Ljava/util/List;
Landroid/telephony/TelephonyManager;->getCurrentPhoneType()I
Landroid/telephony/TelephonyManager;->getCurrentPhoneType(I)I
Landroid/telephony/TelephonyManager;->getDataEnabled(I)Z
Landroid/telephony/TelephonyManager;->getDataEnabled()Z
+Landroid/telephony/TelephonyManager;->getDataNetworkType(I)I
Landroid/telephony/TelephonyManager;->getDefault()Landroid/telephony/TelephonyManager;
+Landroid/telephony/TelephonyManager;->getGroupIdLevel1(I)Ljava/lang/String;
Landroid/telephony/TelephonyManager;->getITelephony()Lcom/android/internal/telephony/ITelephony;
Landroid/telephony/TelephonyManager;->getLine1Number(I)Ljava/lang/String;
+Landroid/telephony/TelephonyManager;->getMultiSimConfiguration()Landroid/telephony/TelephonyManager$MultiSimVariants;
Landroid/telephony/TelephonyManager;->getNetworkClass(I)I
Landroid/telephony/TelephonyManager;->getNetworkCountryIso(I)Ljava/lang/String;
+Landroid/telephony/TelephonyManager;->getNetworkOperatorForPhone(I)Ljava/lang/String;
Landroid/telephony/TelephonyManager;->getNetworkOperator(I)Ljava/lang/String;
Landroid/telephony/TelephonyManager;->getNetworkOperatorName(I)Ljava/lang/String;
Landroid/telephony/TelephonyManager;->getNetworkType(I)I
+Landroid/telephony/TelephonyManager;->getNetworkTypeName(I)Ljava/lang/String;
+Landroid/telephony/TelephonyManager;->getPhoneType(I)I
+Landroid/telephony/TelephonyManager;->getSimCount()I
Landroid/telephony/TelephonyManager;->getSimOperator(I)Ljava/lang/String;
+Landroid/telephony/TelephonyManager;->getSimOperatorNameForPhone(I)Ljava/lang/String;
Landroid/telephony/TelephonyManager;->getSimOperatorName(I)Ljava/lang/String;
+Landroid/telephony/TelephonyManager;->getSimOperatorNumericForPhone(I)Ljava/lang/String;
Landroid/telephony/TelephonyManager;->getSimSerialNumber(I)Ljava/lang/String;
+Landroid/telephony/TelephonyManager;->getSubIdForPhoneAccount(Landroid/telecom/PhoneAccount;)I
Landroid/telephony/TelephonyManager;->getSubscriberId(I)Ljava/lang/String;
+Landroid/telephony/TelephonyManager;->getSubscriberInfo()Lcom/android/internal/telephony/IPhoneSubInfo;
+Landroid/telephony/TelephonyManager;->hasIccCard(I)Z
+Landroid/telephony/TelephonyManager;-><init>(Landroid/content/Context;)V
+Landroid/telephony/TelephonyManager;-><init>()V
Landroid/telephony/TelephonyManager;->isMultiSimEnabled()Z
+Landroid/telephony/TelephonyManager;->isNetworkRoaming(I)Z
Landroid/telephony/TelephonyManager;->setDataEnabled(IZ)V
Landroid/text/AndroidBidi;->bidi(I[C[B)I
+Landroid/text/DynamicLayout;-><init>(Ljava/lang/CharSequence;Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;Landroid/text/TextDirectionHeuristic;FFZIIILandroid/text/TextUtils$TruncateAt;I)V
Landroid/text/DynamicLayout;->sStaticLayout:Landroid/text/StaticLayout;
Landroid/text/Html;->withinStyle(Ljava/lang/StringBuilder;Ljava/lang/CharSequence;II)V
Landroid/text/Layout;->DIRS_ALL_LEFT_TO_RIGHT:Landroid/text/Layout$Directions;
@@ -975,64 +1609,158 @@
Landroid/text/SpannableStringInternal;->setSpan(Ljava/lang/Object;IIIZ)V
Landroid/text/SpannableStringInternal;->START:I
Landroid/text/StaticLayout;-><init>(Ljava/lang/CharSequence;IILandroid/text/TextPaint;ILandroid/text/Layout$Alignment;Landroid/text/TextDirectionHeuristic;FFZLandroid/text/TextUtils$TruncateAt;II)V
+Landroid/text/StaticLayout$LineBreaks;->ascents:[F
+Landroid/text/StaticLayout$LineBreaks;->breaks:[I
+Landroid/text/StaticLayout$LineBreaks;->descents:[F
+Landroid/text/StaticLayout$LineBreaks;->flags:[I
+Landroid/text/StaticLayout$LineBreaks;->widths:[F
Landroid/text/StaticLayout;->mColumns:I
Landroid/text/StaticLayout;->mLineCount:I
Landroid/text/StaticLayout;->mLines:[I
Landroid/text/TextLine;->obtain()Landroid/text/TextLine;
Landroid/text/TextLine;->sCached:[Landroid/text/TextLine;
Landroid/text/TextPaint;->setUnderlineText(IF)V
+Landroid/transition/ChangeBounds;->BOTTOM_RIGHT_ONLY_PROPERTY:Landroid/util/Property;
+Landroid/transition/ChangeBounds;->POSITION_PROPERTY:Landroid/util/Property;
+Landroid/util/ArrayMap;->mBaseCacheSize:I
+Landroid/util/ArrayMap;->mTwiceBaseCacheSize:I
+Landroid/util/DisplayMetrics;->noncompatHeightPixels:I
+Landroid/util/DisplayMetrics;->noncompatWidthPixels:I
+Landroid/util/EventLog$Event;-><init>([B)V
Landroid/util/Log;->wtf(ILjava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;ZZ)I
Landroid/util/Pools$SynchronizedPool;->acquire()Ljava/lang/Object;
+Landroid/util/Rational;->readObject(Ljava/io/ObjectInputStream;)V
+Landroid/util/Singleton;->mInstance:Ljava/lang/Object;
Landroid/view/accessibility/AccessibilityManager;->getInstance(Landroid/content/Context;)Landroid/view/accessibility/AccessibilityManager;
Landroid/view/accessibility/AccessibilityManager;->isHighTextContrastEnabled()Z
+Landroid/view/accessibility/AccessibilityManager;->mIsHighTextContrastEnabled:Z
Landroid/view/accessibility/AccessibilityManager;->sInstance:Landroid/view/accessibility/AccessibilityManager;
Landroid/view/accessibility/AccessibilityManager;->sInstanceSync:Ljava/lang/Object;
Landroid/view/accessibility/AccessibilityNodeInfo;->refresh(Landroid/os/Bundle;Z)Z
+Landroid/view/accessibility/IAccessibilityManager;->getEnabledAccessibilityServiceList(II)Ljava/util/List;
+Landroid/view/accessibility/IAccessibilityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/accessibility/IAccessibilityManager;
+Landroid/view/accessibility/IAccessibilityManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/view/ActionMode;->isUiFocusable()Z
Landroid/view/animation/Animation;->mListener:Landroid/view/animation/Animation$AnimationListener;
Landroid/view/Choreographer;->doFrame(JI)V
Landroid/view/Choreographer;->getFrameTime()J
Landroid/view/Choreographer;->mCallbackQueues:[Landroid/view/Choreographer$CallbackQueue;
+Landroid/view/Choreographer;->mLastFrameTimeNanos:J
Landroid/view/Choreographer;->postCallback(ILjava/lang/Runnable;Ljava/lang/Object;)V
Landroid/view/Choreographer;->removeCallbacks(ILjava/lang/Runnable;Ljava/lang/Object;)V
Landroid/view/Choreographer;->scheduleVsyncLocked()V
+Landroid/view/Choreographer;->USE_VSYNC:Z
Landroid/view/ContextThemeWrapper;->mResources:Landroid/content/res/Resources;
Landroid/view/ContextThemeWrapper;->mTheme:Landroid/content/res/Resources$Theme;
Landroid/view/ContextThemeWrapper;->mThemeResource:I
+Landroid/view/DisplayEventReceiver;->dispatchHotplug(JIZ)V
+Landroid/view/DisplayEventReceiver;->dispatchVsync(JII)V
+Landroid/view/Display$HdrCapabilities;-><init>([IFFF)V
+Landroid/view/DisplayListCanvas;->callDrawGLFunction2(J)V
+Landroid/view/DisplayListCanvas;->drawGLFunctor2(JLjava/lang/Runnable;)V
+Landroid/view/FrameMetrics;->mTimingData:[J
+Landroid/view/FrameMetricsObserver;->mFrameMetrics:Landroid/view/FrameMetrics;
+Landroid/view/FrameMetricsObserver;->mMessageQueue:Landroid/os/MessageQueue;
+Landroid/view/FrameMetricsObserver;->notifyDataAvailable(I)V
+Landroid/view/GestureDetector;->mMinimumFlingVelocity:I
+Landroid/view/GestureDetector;->mTouchSlopSquare:I
+Landroid/view/GhostView;->addGhost(Landroid/view/View;Landroid/view/ViewGroup;Landroid/graphics/Matrix;)Landroid/view/GhostView;
+Landroid/view/GhostView;->removeGhost(Landroid/view/View;)V
+Landroid/view/IGraphicsStats$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/view/InputChannel;-><init>()V
+Landroid/view/InputChannel;->mPtr:J
+Landroid/view/InputDevice;->addMotionRange(IIFFFFF)V
+Landroid/view/InputDevice;-><init>(IIILjava/lang/String;IILjava/lang/String;ZIILandroid/view/KeyCharacterMap;ZZZ)V
Landroid/view/InputDevice;->isExternal()Z
+Landroid/view/InputEventReceiver;->dispatchBatchedInputEventPending()V
+Landroid/view/InputEventReceiver;->dispatchInputEvent(ILandroid/view/InputEvent;I)V
+Landroid/view/InputEventSender;->dispatchInputEventFinished(IZ)V
Landroid/view/inputmethod/InputMethodManager;->finishInputLocked()V
Landroid/view/inputmethod/InputMethodManager;->focusIn(Landroid/view/View;)V
Landroid/view/inputmethod/InputMethodManager;->getInputMethodWindowVisibleHeight()I
Landroid/view/inputmethod/InputMethodManager;->mCurId:Ljava/lang/String;
Landroid/view/inputmethod/InputMethodManager;->mCurRootView:Landroid/view/View;
+Landroid/view/inputmethod/InputMethodManager;->mH:Landroid/view/inputmethod/InputMethodManager$H;
Landroid/view/inputmethod/InputMethodManager;->mNextServedView:Landroid/view/View;
Landroid/view/inputmethod/InputMethodManager;->mServedView:Landroid/view/View;
+Landroid/view/inputmethod/InputMethodManager;->mService:Lcom/android/internal/view/IInputMethodManager;
Landroid/view/inputmethod/InputMethodManager;->notifyUserAction()V
Landroid/view/inputmethod/InputMethodManager;->showSoftInputUnchecked(ILandroid/os/ResultReceiver;)V
+Landroid/view/inputmethod/InputMethodManager;->sInstance:Landroid/view/inputmethod/InputMethodManager;
Landroid/view/inputmethod/InputMethodManager;->windowDismissed(Landroid/os/IBinder;)V
+Landroid/view/InputQueue;->finishInputEvent(JZ)V
Landroid/view/IWindowManager;->getAnimationScale(I)F
Landroid/view/IWindowManager;->hasNavigationBar()Z
Landroid/view/IWindowManager;->setAnimationScale(IF)V
Landroid/view/IWindowManager;->setStrictModeVisualIndicatorPreference(Ljava/lang/String;)V
Landroid/view/IWindowManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IWindowManager;
+Landroid/view/IWindowManager$Stub$Proxy;->getBaseDisplayDensity(I)I
+Landroid/view/IWindowManager$Stub$Proxy;->getInitialDisplayDensity(I)I
+Landroid/view/IWindowManager$Stub$Proxy;->hasNavigationBar()Z
+Landroid/view/IWindowManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/view/IWindowSession$Stub$Proxy;->relayout(Landroid/view/IWindow;ILandroid/view/WindowManager$LayoutParams;IIIILandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/util/MergedConfiguration;Landroid/view/Surface;)I
+Landroid/view/KeyCharacterMap$FallbackAction;->keyCode:I
+Landroid/view/KeyCharacterMap$FallbackAction;->metaState:I
+Landroid/view/KeyCharacterMap;-><init>(J)V
+Landroid/view/KeyEvent;->mAction:I
+Landroid/view/KeyEvent;->mCharacters:Ljava/lang/String;
+Landroid/view/KeyEvent;->mDeviceId:I
+Landroid/view/KeyEvent;->mDownTime:J
+Landroid/view/KeyEvent;->mEventTime:J
+Landroid/view/KeyEvent;->mFlags:I
+Landroid/view/KeyEvent;->mKeyCode:I
+Landroid/view/KeyEvent;->mMetaState:I
+Landroid/view/KeyEvent;->mRepeatCount:I
+Landroid/view/KeyEvent;->mScanCode:I
+Landroid/view/KeyEvent;->mSource:I
+Landroid/view/KeyEvent;->obtain(JJIIIIIIIILjava/lang/String;)Landroid/view/KeyEvent;
+Landroid/view/KeyEvent;->recycle()V
Landroid/view/LayoutInflater;->createViewFromTag(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
Landroid/view/LayoutInflater;->createViewFromTag(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;Z)Landroid/view/View;
Landroid/view/LayoutInflater;->mConstructorArgs:[Ljava/lang/Object;
+Landroid/view/LayoutInflater;->mContext:Landroid/content/Context;
Landroid/view/LayoutInflater;->mFactory2:Landroid/view/LayoutInflater$Factory2;
Landroid/view/LayoutInflater;->mFactory:Landroid/view/LayoutInflater$Factory;
Landroid/view/LayoutInflater;->mFactorySet:Z
+Landroid/view/LayoutInflater;->mPrivateFactory:Landroid/view/LayoutInflater$Factory2;
Landroid/view/LayoutInflater;->sConstructorMap:Ljava/util/HashMap;
Landroid/view/LayoutInflater;->setPrivateFactory(Landroid/view/LayoutInflater$Factory2;)V
Landroid/view/MotionEvent;->HISTORY_CURRENT:I
Landroid/view/MotionEvent;->mNativePtr:J
Landroid/view/MotionEvent;->nativeGetRawAxisValue(JIII)F
+Landroid/view/MotionEvent;->obtain()Landroid/view/MotionEvent;
+Landroid/view/MotionEvent$PointerCoords;->mPackedAxisBits:J
+Landroid/view/MotionEvent$PointerCoords;->mPackedAxisValues:[F
Landroid/view/MotionEvent;->scale(F)V
+Landroid/view/PointerIcon;->load(Landroid/content/Context;)Landroid/view/PointerIcon;
+Landroid/view/PointerIcon;->mBitmapFrames:[Landroid/graphics/Bitmap;
+Landroid/view/PointerIcon;->mBitmap:Landroid/graphics/Bitmap;
+Landroid/view/PointerIcon;->mDurationPerFrame:I
+Landroid/view/PointerIcon;->mHotSpotX:F
+Landroid/view/PointerIcon;->mHotSpotY:F
+Landroid/view/PointerIcon;->mType:I
+Landroid/view/RenderNodeAnimator;->callOnFinished(Landroid/view/RenderNodeAnimator;)V
Landroid/view/ScaleGestureDetector;->mListener:Landroid/view/ScaleGestureDetector$OnScaleGestureListener;
+Landroid/view/SurfaceControl$PhysicalDisplayInfo;->appVsyncOffsetNanos:J
+Landroid/view/SurfaceControl$PhysicalDisplayInfo;->density:F
+Landroid/view/SurfaceControl$PhysicalDisplayInfo;->height:I
+Landroid/view/SurfaceControl$PhysicalDisplayInfo;-><init>()V
+Landroid/view/SurfaceControl$PhysicalDisplayInfo;->presentationDeadlineNanos:J
+Landroid/view/SurfaceControl$PhysicalDisplayInfo;->refreshRate:F
+Landroid/view/SurfaceControl$PhysicalDisplayInfo;->secure:Z
+Landroid/view/SurfaceControl$PhysicalDisplayInfo;->width:I
+Landroid/view/SurfaceControl$PhysicalDisplayInfo;->xDpi:F
+Landroid/view/SurfaceControl$PhysicalDisplayInfo;->yDpi:F
+Landroid/view/Surface;-><init>(J)V
+Landroid/view/Surface;->mLock:Ljava/lang/Object;
+Landroid/view/Surface;->mNativeObject:J
+Landroid/view/SurfaceSession;->mNativeClient:J
Landroid/view/SurfaceView;->mCallbacks:Ljava/util/ArrayList;
Landroid/view/SurfaceView;->mFormat:I
Landroid/view/SurfaceView;->mRequestedFormat:I
Landroid/view/SurfaceView;->mSurfaceHolder:Landroid/view/SurfaceHolder;
+Landroid/view/SurfaceView;->surfacePositionLost_uiRtSync(J)V
+Landroid/view/SurfaceView;->updateSurfacePosition_renderWorker(JIIII)V
Landroid/view/textclassifier/logging/SmartSelectionEventTracker;-><init>(Landroid/content/Context;I)V
Landroid/view/textclassifier/logging/SmartSelectionEventTracker;->logEvent(Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;)V
Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionAction(III)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;
@@ -1043,10 +1771,18 @@
Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionStarted(I)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;
Landroid/view/textservice/TextServicesManager;->isSpellCheckerEnabled()Z
Landroid/view/TextureView;->mLayer:Landroid/view/HardwareLayer;
+Landroid/view/TextureView;->mNativeWindow:J
Landroid/view/TextureView;->mSurface:Landroid/graphics/SurfaceTexture;
Landroid/view/TextureView;->mUpdateListener:Landroid/graphics/SurfaceTexture$OnFrameAvailableListener;
Landroid/view/TouchDelegate;->mDelegateTargeted:Z
+Landroid/view/VelocityTracker$Estimator;->confidence:F
+Landroid/view/VelocityTracker$Estimator;->degree:I
+Landroid/view/VelocityTracker$Estimator;->xCoeff:[F
+Landroid/view/VelocityTracker$Estimator;->yCoeff:[F
Landroid/view/VelocityTracker;->obtain(Ljava/lang/String;)Landroid/view/VelocityTracker;
+Landroid/view/View;->applyDrawableToTransparentRegion(Landroid/graphics/drawable/Drawable;Landroid/graphics/Region;)V
+Landroid/view/View$AttachInfo;->mDrawingTime:J
+Landroid/view/View$AttachInfo;->mStableInsets:Landroid/graphics/Rect;
Landroid/view/View;->clearAccessibilityFocus()V
Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z
Landroid/view/View;->computeOpaqueFlags()V
@@ -1059,28 +1795,37 @@
Landroid/view/View;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V
Landroid/view/View;->dispatchDetachedFromWindow()V
Landroid/view/View;->fitsSystemWindows()Z
+Landroid/view/View;->getAccessibilityDelegate()Landroid/view/View$AccessibilityDelegate;
Landroid/view/View;->getListenerInfo()Landroid/view/View$ListenerInfo;
+Landroid/view/View;->getTransitionAlpha()F
Landroid/view/View;->getViewRootImpl()Landroid/view/ViewRootImpl;
+Landroid/view/ViewGroup;->dispatchViewAdded(Landroid/view/View;)V
+Landroid/view/ViewGroup;->dispatchViewRemoved(Landroid/view/View;)V
Landroid/view/ViewGroup;->FLAG_SUPPORT_STATIC_TRANSFORMATIONS:I
Landroid/view/ViewGroup;->FLAG_USE_CHILD_DRAWING_ORDER:I
Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V
Landroid/view/ViewGroup$MarginLayoutParams;->endMargin:I
Landroid/view/ViewGroup$MarginLayoutParams;->startMargin:I
+Landroid/view/ViewGroup;->mChildrenCount:I
Landroid/view/ViewGroup;->mChildren:[Landroid/view/View;
Landroid/view/ViewGroup;->mFirstTouchTarget:Landroid/view/ViewGroup$TouchTarget;
Landroid/view/ViewGroup;->mGroupFlags:I
Landroid/view/ViewGroup;->mOnHierarchyChangeListener:Landroid/view/ViewGroup$OnHierarchyChangeListener;
+Landroid/view/ViewGroup;->suppressLayout(Z)V
Landroid/view/View;->initializeScrollbars(Landroid/content/res/TypedArray;)V
+Landroid/view/View;->internalSetPadding(IIII)V
Landroid/view/View;->isPaddingResolved()Z
Landroid/view/View;->isVisibleToUser(Landroid/graphics/Rect;)Z
Landroid/view/View;->isVisibleToUser()Z
Landroid/view/View$ListenerInfo;->mOnClickListener:Landroid/view/View$OnClickListener;
+Landroid/view/View$ListenerInfo;->mOnLongClickListener:Landroid/view/View$OnLongClickListener;
Landroid/view/View$ListenerInfo;->mOnTouchListener:Landroid/view/View$OnTouchListener;
Landroid/view/View;->mAccessibilityDelegate:Landroid/view/View$AccessibilityDelegate;
Landroid/view/View;->mAttachInfo:Landroid/view/View$AttachInfo;
Landroid/view/View;->mBottom:I
Landroid/view/View;->mContext:Landroid/content/Context;
Landroid/view/View;->mDrawingCache:Landroid/graphics/Bitmap;
+Landroid/view/View;->mLayoutParams:Landroid/view/ViewGroup$LayoutParams;
Landroid/view/View;->mLeft:I
Landroid/view/View;->mListenerInfo:Landroid/view/View$ListenerInfo;
Landroid/view/View;->mMinHeight:I
@@ -1099,6 +1844,7 @@
Landroid/view/View;->mTag:Ljava/lang/Object;
Landroid/view/View;->mTop:I
Landroid/view/View;->mUnscaledDrawingCache:Landroid/graphics/Bitmap;
+Landroid/view/View;->mViewFlags:I
Landroid/view/View;->notifySubtreeAccessibilityStateChangedIfNeeded()V
Landroid/view/View;->recomputePadding()V
Landroid/view/View;->requestAccessibilityFocus()Z
@@ -1106,9 +1852,15 @@
Landroid/view/ViewRootImpl;->detachFunctor(J)V
Landroid/view/ViewRootImpl;->invokeFunctor(JZ)V
Landroid/view/ViewRootImpl;->mStopped:Z
+Landroid/view/ViewRootImpl;->mView:Landroid/view/View;
+Landroid/view/View$ScrollabilityCache;->scrollBar:Landroid/widget/ScrollBarDrawable;
+Landroid/view/View;->setAlphaNoInvalidation(F)Z
+Landroid/view/View;->setAnimationMatrix(Landroid/graphics/Matrix;)V
Landroid/view/View;->setAssistBlocked(Z)V
Landroid/view/View;->setFrame(IIII)Z
Landroid/view/View;->setIsRootNamespace(Z)V
+Landroid/view/View;->setLeftTopRightBottom(IIII)V
+Landroid/view/View;->setTransitionAlpha(F)V
Landroid/view/View;->startActivityForResult(Landroid/content/Intent;I)V
Landroid/view/View;->STATUS_BAR_DISABLE_BACK:I
Landroid/view/View;->STATUS_BAR_DISABLE_EXPAND:I
@@ -1116,20 +1868,32 @@
Landroid/view/View;->STATUS_BAR_DISABLE_RECENT:I
Landroid/view/View;->toGlobalMotionEvent(Landroid/view/MotionEvent;)Z
Landroid/view/View;->toLocalMotionEvent(Landroid/view/MotionEvent;)Z
+Landroid/view/View;->transformMatrixToGlobal(Landroid/graphics/Matrix;)V
+Landroid/view/View;->transformMatrixToLocal(Landroid/graphics/Matrix;)V
Landroid/view/ViewTreeObserver;->addOnComputeInternalInsetsListener(Landroid/view/ViewTreeObserver$OnComputeInternalInsetsListener;)V
Landroid/view/ViewTreeObserver$InternalInsetsInfo;->setTouchableInsets(I)V
Landroid/view/ViewTreeObserver$InternalInsetsInfo;->TOUCHABLE_INSETS_REGION:I
Landroid/view/ViewTreeObserver$InternalInsetsInfo;->touchableRegion:Landroid/graphics/Region;
Landroid/view/ViewTreeObserver;->removeOnComputeInternalInsetsListener(Landroid/view/ViewTreeObserver$OnComputeInternalInsetsListener;)V
+Landroid/view/WindowAnimationFrameStats;->init(J[J)V
+Landroid/view/WindowContentFrameStats;->init(J[J[J[J)V
Landroid/view/WindowManagerGlobal;->getInstance()Landroid/view/WindowManagerGlobal;
Landroid/view/WindowManagerGlobal;->getRootView(Ljava/lang/String;)Landroid/view/View;
Landroid/view/WindowManagerGlobal;->getViewRootNames()[Ljava/lang/String;
Landroid/view/WindowManagerGlobal;->getWindowManagerService()Landroid/view/IWindowManager;
Landroid/view/WindowManagerGlobal;->mLock:Ljava/lang/Object;
+Landroid/view/WindowManagerGlobal;->mParams:Ljava/util/ArrayList;
+Landroid/view/WindowManagerGlobal;->mRoots:Ljava/util/ArrayList;
Landroid/view/WindowManagerGlobal;->mViews:Ljava/util/ArrayList;
+Landroid/view/WindowManagerGlobal;->sDefaultWindowManager:Landroid/view/WindowManagerGlobal;
+Landroid/view/WindowManagerGlobal;->sWindowManagerService:Landroid/view/IWindowManager;
+Landroid/view/WindowManagerGlobal;->sWindowSession:Landroid/view/IWindowSession;
Landroid/view/WindowManagerGlobal;->trimMemory(I)V
+Landroid/view/WindowManagerImpl;->mGlobal:Landroid/view/WindowManagerGlobal;
+Landroid/view/WindowManager$LayoutParams;->hideTimeoutMilliseconds:J
Landroid/view/WindowManager$LayoutParams;->needsMenuKey:I
Landroid/view/WindowManager$LayoutParams;->NEEDS_MENU_SET_TRUE:I
+Landroid/view/WindowManager$LayoutParams;->PRIVATE_FLAG_NO_MOVE_ANIMATION:I
Landroid/view/WindowManager$LayoutParams;->privateFlags:I
Landroid/view/WindowManager$LayoutParams;->userActivityTimeout:J
Landroid/view/Window;->mAppName:Ljava/lang/String;
@@ -1142,6 +1906,7 @@
Landroid/webkit/FindActionModeCallback;->showSoftInput()V
Landroid/webkit/GeolocationPermissions;-><init>()V
Landroid/webkit/HttpAuthHandler;-><init>()V
+Landroid/webkit/IWebViewUpdateService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/webkit/JsDialogHelper;-><init>(Landroid/webkit/JsPromptResult;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
Landroid/webkit/JsDialogHelper;->showDialog(Landroid/content/Context;)V
Landroid/webkit/JsPromptResult;->getStringResult()Ljava/lang/String;
@@ -1153,12 +1918,14 @@
Landroid/webkit/WebMessagePort;-><init>()V
Landroid/webkit/WebResourceError;-><init>()V
Landroid/webkit/WebResourceResponse;-><init>(ZLjava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/util/Map;Ljava/io/InputStream;)V
+Landroid/webkit/WebResourceResponse;->mImmutable:Z
Landroid/webkit/WebSettings;->getAcceptThirdPartyCookies()Z
Landroid/webkit/WebSettings;->setAcceptThirdPartyCookies(Z)V
Landroid/webkit/WebSettings;->setNavDump(Z)V
Landroid/webkit/WebSettings;->setPluginsEnabled(Z)V
Landroid/webkit/WebStorage;-><init>()V
Landroid/webkit/WebStorage$Origin;-><init>(Ljava/lang/String;JJ)V
+Landroid/webkit/WebSyncManager;->mHandler:Landroid/os/Handler;
Landroid/webkit/WebView;->debugDump()V
Landroid/webkit/WebViewDelegate;->addWebViewAssetPath(Landroid/content/Context;)V
Landroid/webkit/WebViewDelegate;->callDrawGlFunction(Landroid/graphics/Canvas;JLjava/lang/Runnable;)V
@@ -1178,8 +1945,12 @@
Landroid/webkit/WebView;->enablePlatformNotifications()V
Landroid/webkit/WebViewFactory;->getLoadedPackageInfo()Landroid/content/pm/PackageInfo;
Landroid/webkit/WebViewFactory;->getProvider()Landroid/webkit/WebViewFactoryProvider;
+Landroid/webkit/WebViewFactory;->getWebViewContextAndSetProvider()Landroid/content/Context;
Landroid/webkit/WebViewFactory;->loadWebViewNativeLibraryFromPackage(Ljava/lang/String;Ljava/lang/ClassLoader;)I
+Landroid/webkit/WebViewFactoryProvider;->getStatics()Landroid/webkit/WebViewFactoryProvider$Statics;
+Landroid/webkit/WebViewFactoryProvider$Statics;->getDefaultUserAgent(Landroid/content/Context;)Ljava/lang/String;
Landroid/webkit/WebViewFactory;->sPackageInfo:Landroid/content/pm/PackageInfo;
+Landroid/webkit/WebViewFactory;->sProviderInstance:Landroid/webkit/WebViewFactoryProvider;
Landroid/webkit/WebView;->getVisibleTitleHeight()I
Landroid/webkit/WebView;->getWebViewProvider()Landroid/webkit/WebViewProvider;
Landroid/webkit/WebView$HitTestResult;-><init>()V
@@ -1204,7 +1975,10 @@
Landroid/webkit/WebView;->restorePicture(Landroid/os/Bundle;Ljava/io/File;)Z
Landroid/webkit/WebView;->savePicture(Landroid/os/Bundle;Ljava/io/File;)Z
Landroid/webkit/WebView;->sEnforceThreadChecking:Z
+Landroid/webkit/WebViewUpdateService;->getCurrentWebViewPackageName()Ljava/lang/String;
Landroid/widget/AbsListView$FlingRunnable;->endFling()V
+Landroid/widget/AbsListView$FlingRunnable;->mScroller:Landroid/widget/OverScroller;
+Landroid/widget/AbsListView$FlingRunnable;->start(I)V
Landroid/widget/AbsListView;->invokeOnItemScrollListener()V
Landroid/widget/AbsListView;->isVerticalScrollBarHidden()Z
Landroid/widget/AbsListView;->mAdapter:Landroid/widget/ListAdapter;
@@ -1225,6 +1999,9 @@
Landroid/widget/AbsListView;->mVelocityTracker:Landroid/view/VelocityTracker;
Landroid/widget/AbsListView;->performLongPress(Landroid/view/View;IJFF)Z
Landroid/widget/AbsListView;->performLongPress(Landroid/view/View;IJ)Z
+Landroid/widget/AbsListView$RecycleBin;->clear()V
+Landroid/widget/AbsListView$RecycleBin;->mRecyclerListener:Landroid/widget/AbsListView$RecyclerListener;
+Landroid/widget/AbsListView;->reportScrollStateChange(I)V
Landroid/widget/AbsListView;->smoothScrollBy(IIZZ)V
Landroid/widget/AbsListView;->trackMotionScroll(II)Z
Landroid/widget/AbsSeekBar;->mIsDragging:Z
@@ -1233,6 +2010,7 @@
Landroid/widget/AbsSeekBar;->mTouchProgressOffset:F
Landroid/widget/ActivityChooserView;->setExpandActivityOverflowButtonDrawable(Landroid/graphics/drawable/Drawable;)V
Landroid/widget/AdapterView;->mDataChanged:Z
+Landroid/widget/AdapterView;->mFirstPosition:I
Landroid/widget/AdapterView;->setNextSelectedPositionInt(I)V
Landroid/widget/AdapterView;->setSelectedPositionInt(I)V
Landroid/widget/AutoCompleteTextView;->doAfterTextChanged()V
@@ -1247,23 +2025,41 @@
Landroid/widget/ExpandableListView;->mChildDivider:Landroid/graphics/drawable/Drawable;
Landroid/widget/FastScroller;->mThumbDrawable:Landroid/graphics/drawable/Drawable;
Landroid/widget/FastScroller;->mTrackDrawable:Landroid/graphics/drawable/Drawable;
+Landroid/widget/Gallery;->fillToGalleryLeft()V
+Landroid/widget/Gallery;->fillToGalleryRight()V
+Landroid/widget/Gallery$FlingRunnable;->startUsingVelocity(I)V
+Landroid/widget/Gallery;->makeAndAddView(IIIZ)Landroid/view/View;
+Landroid/widget/Gallery;->mDownTouchPosition:I
Landroid/widget/Gallery;->mDownTouchView:Landroid/view/View;
+Landroid/widget/Gallery;->mFlingRunnable:Landroid/widget/Gallery$FlingRunnable;
+Landroid/widget/Gallery;->moveDirection(I)Z
+Landroid/widget/Gallery;->mSpacing:I
+Landroid/widget/GridView;->fillDown(II)Landroid/view/View;
+Landroid/widget/GridView;->fillUp(II)Landroid/view/View;
Landroid/widget/GridView;->mColumnWidth:I
Landroid/widget/GridView;->mHorizontalSpacing:I
Landroid/widget/GridView;->mNumColumns:I
Landroid/widget/GridView;->mRequestedNumColumns:I
Landroid/widget/GridView;->mVerticalSpacing:I
+Landroid/widget/HorizontalScrollView;->mChildToScrollTo:Landroid/view/View;
Landroid/widget/HorizontalScrollView;->mEdgeGlowLeft:Landroid/widget/EdgeEffect;
Landroid/widget/HorizontalScrollView;->mEdgeGlowRight:Landroid/widget/EdgeEffect;
Landroid/widget/HorizontalScrollView;->mScroller:Landroid/widget/OverScroller;
Landroid/widget/ImageView;->mAdjustViewBounds:Z
Landroid/widget/ImageView;->mAlpha:I
+Landroid/widget/ImageView;->mDrawMatrix:Landroid/graphics/Matrix;
Landroid/widget/ImageView;->mMaxHeight:I
Landroid/widget/ImageView;->mMaxWidth:I
+Landroid/widget/ImageView;->mResource:I
+Landroid/widget/ImageView;->mUri:Landroid/net/Uri;
+Landroid/widget/ImageView;->updateDrawable(Landroid/graphics/drawable/Drawable;)V
Landroid/widget/LinearLayout;->mGravity:I
Landroid/widget/LinearLayout;->mUseLargestChild:Z
Landroid/widget/ListPopupWindow;->mPopup:Landroid/widget/PopupWindow;
Landroid/widget/ListPopupWindow;->setForceIgnoreOutsideTouch(Z)V
+Landroid/widget/ListView;->fillDown(II)Landroid/view/View;
+Landroid/widget/ListView;->fillSpecific(II)Landroid/view/View;
+Landroid/widget/ListView;->fillUp(II)Landroid/view/View;
Landroid/widget/ListView;->mAreAllItemsSelectable:Z
Landroid/widget/ListView;->setSelectionInt(I)V
Landroid/widget/MediaController;->mAnchor:Landroid/view/View;
@@ -1273,6 +2069,8 @@
Landroid/widget/NumberPicker;->mInputText:Landroid/widget/EditText;
Landroid/widget/NumberPicker;->mSelectionDivider:Landroid/graphics/drawable/Drawable;
Landroid/widget/NumberPicker;->mSelectorWheelPaint:Landroid/graphics/Paint;
+Landroid/widget/OverScroller;->mScrollerY:Landroid/widget/OverScroller$SplineOverScroller;
+Landroid/widget/OverScroller$SplineOverScroller;->mCurrVelocity:F
Landroid/widget/PopupMenu;->mPopup:Lcom/android/internal/view/menu/MenuPopupHelper;
Landroid/widget/PopupWindow;->computeAnimationResource()I
Landroid/widget/PopupWindow;->createPopupLayoutParams(Landroid/os/IBinder;)Landroid/view/WindowManager$LayoutParams;
@@ -1288,8 +2086,12 @@
Landroid/widget/PopupWindow;->mLastHeight:I
Landroid/widget/PopupWindow;->mLastWidth:I
Landroid/widget/PopupWindow;->mOnScrollChangedListener:Landroid/view/ViewTreeObserver$OnScrollChangedListener;
+Landroid/widget/PopupWindow;->mOverlapAnchor:Z
Landroid/widget/PopupWindow;->mWidthMode:I
+Landroid/widget/PopupWindow;->mWindowLayoutType:I
Landroid/widget/PopupWindow;->preparePopup(Landroid/view/WindowManager$LayoutParams;)V
+Landroid/widget/PopupWindow;->setClipToScreenEnabled(Z)V
+Landroid/widget/PopupWindow;->setEpicenterBounds(Landroid/graphics/Rect;)V
Landroid/widget/PopupWindow;->setLayoutInScreenEnabled(Z)V
Landroid/widget/PopupWindow;->setLayoutInsetDecor(Z)V
Landroid/widget/PopupWindow;->setTouchModal(Z)V
@@ -1306,9 +2108,16 @@
Landroid/widget/RelativeLayout;->mGravity:I
Landroid/widget/RemoteViews$Action;->mergeBehavior()I
Landroid/widget/RemoteViews$Action;->viewId:I
+Landroid/widget/RemoteViews$BitmapCache;->mBitmaps:Ljava/util/ArrayList;
Landroid/widget/RemoteViews;->mActions:Ljava/util/ArrayList;
Landroid/widget/RemoteViews;->mApplication:Landroid/content/pm/ApplicationInfo;
+Landroid/widget/RemoteViews;->mBitmapCache:Landroid/widget/RemoteViews$BitmapCache;
+Landroid/widget/RemoteViews;->mergeRemoteViews(Landroid/widget/RemoteViews;)V
Landroid/widget/RemoteViews$ReflectionAction;->methodName:Ljava/lang/String;
+Landroid/widget/ScrollBarDrawable;->mVerticalThumb:Landroid/graphics/drawable/Drawable;
+Landroid/widget/ScrollBarDrawable;->setHorizontalThumbDrawable(Landroid/graphics/drawable/Drawable;)V
+Landroid/widget/ScrollBarDrawable;->setVerticalThumbDrawable(Landroid/graphics/drawable/Drawable;)V
+Landroid/widget/ScrollView;->mChildToScrollTo:Landroid/view/View;
Landroid/widget/ScrollView;->mEdgeGlowBottom:Landroid/widget/EdgeEffect;
Landroid/widget/ScrollView;->mEdgeGlowTop:Landroid/widget/EdgeEffect;
Landroid/widget/ScrollView;->mIsBeingDragged:Z
@@ -1324,6 +2133,7 @@
Landroid/widget/Spinner;->mPopup:Landroid/widget/Spinner$SpinnerPopup;
Landroid/widget/Switch;->mThumbDrawable:Landroid/graphics/drawable/Drawable;
Landroid/widget/Switch;->mTrackDrawable:Landroid/graphics/drawable/Drawable;
+Landroid/widget/TabHost$TabSpec;->mContentStrategy:Landroid/widget/TabHost$ContentStrategy;
Landroid/widget/TabWidget;->setTabSelectionListener(Landroid/widget/TabWidget$OnTabSelectionChanged;)V
Landroid/widget/TextView;->assumeLayout()V
Landroid/widget/TextView;->createEditorIfNeeded()V
@@ -1335,14 +2145,21 @@
Landroid/widget/TextView;->mMaximum:I
Landroid/widget/TextView;->mMaxMode:I
Landroid/widget/TextView;->mSingleLine:Z
+Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;Landroid/widget/TextView$BufferType;ZI)V
+Landroid/widget/Toast;->getService()Landroid/app/INotificationManager;
+Landroid/widget/Toast;->sService:Landroid/app/INotificationManager;
Landroid/widget/VideoView;->mCurrentBufferPercentage:I
Landroid/widget/VideoView;->mMediaController:Landroid/widget/MediaController;
Landroid/widget/VideoView;->mSHCallback:Landroid/view/SurfaceHolder$Callback;
Landroid/widget/VideoView;->mUri:Landroid/net/Uri;
Landroid/widget/VideoView;->mVideoHeight:I
Landroid/widget/VideoView;->mVideoWidth:I
+Lcom/android/internal/app/IAppOpsService$Stub$Proxy;->checkOperation(IILjava/lang/String;)I
+Lcom/android/internal/app/IAppOpsService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Lcom/android/internal/app/IBatteryStats;->getStatistics()[B
Lcom/android/internal/app/IBatteryStats$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IBatteryStats;
+Lcom/android/internal/app/IVoiceInteractionManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IVoiceInteractionManagerService;
+Lcom/android/internal/app/IVoiceInteractionManagerService$Stub$Proxy;->showSessionFromSession(Landroid/os/IBinder;Landroid/os/Bundle;I)Z
Lcom/android/internal/os/BatterySipper;->add(Lcom/android/internal/os/BatterySipper;)V
Lcom/android/internal/os/BatterySipper;->drainType:Lcom/android/internal/os/BatterySipper$DrainType;
Lcom/android/internal/os/BatterySipper;->getUid()I
@@ -1387,15 +2204,32 @@
Lcom/android/internal/os/PowerProfile;->getAveragePower(Ljava/lang/String;)D
Lcom/android/internal/os/PowerProfile;->getAveragePower(Ljava/lang/String;I)D
Lcom/android/internal/os/PowerProfile;->getBatteryCapacity()D
+Lcom/android/internal/os/PowerProfile;-><init>(Landroid/content/Context;)V
Lcom/android/internal/R$array;->config_mobile_hotspot_provision_app:I
Lcom/android/internal/R$array;->config_tether_wifi_regexs:I
+Lcom/android/internal/R$array;->maps_starting_lat_lng:I
+Lcom/android/internal/R$array;->maps_starting_zoom:I
+Lcom/android/internal/R$attr;->mapViewStyle:I
+Lcom/android/internal/R$attr;->state_focused:I
+Lcom/android/internal/R$attr;->state_pressed:I
+Lcom/android/internal/R$attr;->state_selected:I
Lcom/android/internal/R$attr;->switchStyle:I
Lcom/android/internal/R$bool;->config_mms_content_disposition_support:I
Lcom/android/internal/R$bool;->config_showNavigationBar:I
+Lcom/android/internal/R$dimen;-><init>()V
Lcom/android/internal/R$dimen;->navigation_bar_height:I
Lcom/android/internal/R$dimen;->navigation_bar_height_landscape:I
Lcom/android/internal/R$dimen;->status_bar_height:I
+Lcom/android/internal/R$dimen;->toast_y_offset:I
+Lcom/android/internal/R$drawable;->btn_check_off:I
+Lcom/android/internal/R$drawable;->compass_arrow:I
+Lcom/android/internal/R$drawable;->compass_base:I
+Lcom/android/internal/R$drawable;->ic_maps_indicator_current_position_anim:I
Lcom/android/internal/R$drawable;->ic_menu_close_clear_cancel:I
+Lcom/android/internal/R$drawable;->loading_tile_android:I
+Lcom/android/internal/R$drawable;->maps_google_logo:I
+Lcom/android/internal/R$drawable;->no_tile_256:I
+Lcom/android/internal/R$drawable;->reticle:I
Lcom/android/internal/R$id;->amPm:I
Lcom/android/internal/R$id;->edittext_container:I
Lcom/android/internal/R$id;->icon:I
@@ -1408,12 +2242,37 @@
Lcom/android/internal/R$id;->title_container:I
Lcom/android/internal/R$id;->title:I
Lcom/android/internal/R$integer;->config_screenBrightnessDim:I
+Lcom/android/internal/R$integer;->config_toastDefaultGravity:I
Lcom/android/internal/R$layout;->screen_title:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_enabled:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_hardwareAccelerated:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication:[I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_label:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_largeHeap:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_name:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_permission:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_process:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_supportsRtl:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_theme:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_uiOptions:I
+Lcom/android/internal/R$styleable;->AndroidManifest:[I
+Lcom/android/internal/R$styleable;->AndroidManifest_installLocation:I
+Lcom/android/internal/R$styleable;->AndroidManifest_sharedUserId:I
+Lcom/android/internal/R$styleable;->AndroidManifestUsesPermission:[I
+Lcom/android/internal/R$styleable;->AndroidManifestUsesPermission_name:I
+Lcom/android/internal/R$styleable;->AndroidManifestUsesSdk:[I
+Lcom/android/internal/R$styleable;->AndroidManifestUsesSdk_minSdkVersion:I
+Lcom/android/internal/R$styleable;->AndroidManifestUsesSdk_targetSdkVersion:I
+Lcom/android/internal/R$styleable;->AndroidManifest_versionCode:I
+Lcom/android/internal/R$styleable;->AndroidManifest_versionName:I
Lcom/android/internal/R$styleable;->CompoundButton_button:I
Lcom/android/internal/R$styleable;->CompoundButton:[I
+Lcom/android/internal/R$styleable;->EdgeEffect_colorEdgeEffect:I
+Lcom/android/internal/R$styleable;->EdgeEffect:[I
Lcom/android/internal/R$styleable;->IconMenuView:[I
Lcom/android/internal/R$styleable;->ImageView:[I
Lcom/android/internal/R$styleable;->ImageView_src:I
+Lcom/android/internal/R$styleable;->ScrollView_fillViewport:I
Lcom/android/internal/R$styleable;->ScrollView:[I
Lcom/android/internal/R$styleable;->TabWidget:[I
Lcom/android/internal/R$styleable;->TextView_drawableBottom:I
@@ -1422,31 +2281,56 @@
Lcom/android/internal/R$styleable;->TextView_drawableTop:I
Lcom/android/internal/R$styleable;->TextView:[I
Lcom/android/internal/R$styleable;->View_background:I
+Lcom/android/internal/R$styleable;->ViewGroup_Layout:[I
+Lcom/android/internal/R$styleable;->ViewGroup_Layout_layout_height:I
+Lcom/android/internal/R$styleable;->ViewGroup_Layout_layout_width:I
Lcom/android/internal/R$styleable;->View:[I
Lcom/android/internal/R$styleable;->View_id:I
Lcom/android/internal/R$styleable;->ViewStub:[I
Lcom/android/internal/R$styleable;->ViewStub_inflatedId:I
Lcom/android/internal/R$styleable;->ViewStub_layout:I
Lcom/android/internal/R$styleable;->Window_windowActionBarFullscreenDecorLayout:I
+Lcom/android/internal/R$style;->Theme:I
Lcom/android/internal/R$xml;->power_profile:I
Lcom/android/internal/telephony/IPhoneSubInfo$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IPhoneSubInfo;
+Lcom/android/internal/telephony/IPhoneSubInfo$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Lcom/android/internal/telephony/ISms$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ISms;
+Lcom/android/internal/telephony/ISub$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Lcom/android/internal/telephony/ITelephony;->call(Ljava/lang/String;Ljava/lang/String;)V
Lcom/android/internal/telephony/ITelephony;->endCall()Z
Lcom/android/internal/telephony/ITelephony;->isIdle(Ljava/lang/String;)Z
Lcom/android/internal/telephony/ITelephony;->silenceRinger()V
Lcom/android/internal/telephony/ITelephony$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephony;
+Lcom/android/internal/telephony/ITelephony$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_getDeviceId:I
Lcom/android/internal/util/XmlUtils;->readMapXml(Ljava/io/InputStream;)Ljava/util/HashMap;
+Lcom/android/internal/view/IInputMethodManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodManager;
+Lcom/android/internal/view/IInputMethodManager$Stub$Proxy;->getEnabledInputMethodList()Ljava/util/List;
+Lcom/android/internal/view/IInputMethodManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Lcom/android/internal/view/InputBindResult;->CREATOR:Landroid/os/Parcelable$Creator;
Lcom/android/internal/view/menu/MenuBuilder;->mContext:Landroid/content/Context;
Lcom/android/internal/view/menu/MenuBuilder;->setCurrentMenuInfo(Landroid/view/ContextMenu$ContextMenuInfo;)V
Lcom/android/internal/view/menu/MenuBuilder;->setOptionalIconsVisible(Z)V
Lcom/android/internal/view/menu/MenuItemImpl;->mIconResId:I
Lcom/android/internal/view/menu/MenuItemImpl;->setMenuInfo(Landroid/view/ContextMenu$ContextMenuInfo;)V
+Lcom/android/internal/view/menu/MenuView$ItemView;->getItemData()Lcom/android/internal/view/menu/MenuItemImpl;
+Lcom/android/okhttp/ConnectionPool;->keepAliveDurationNs:J
Lcom/android/okhttp/ConnectionPool;->maxIdleConnections:I
Lcom/android/okhttp/ConnectionPool;->systemDefault:Lcom/android/okhttp/ConnectionPool;
+Lcom/android/okhttp/internal/http/HttpEngine;->httpStream:Lcom/android/okhttp/internal/http/HttpStream;
+Lcom/android/okhttp/OkHttpClient;->connectionPool:Lcom/android/okhttp/ConnectionPool;
+Lcom/android/okhttp/OkHttpClient;->DEFAULT_PROTOCOLS:Ljava/util/List;
+Lcom/android/okhttp/OkHttpClient;->dns:Lcom/android/okhttp/Dns;
+Lcom/android/okhttp/OkHttpClient;->setProtocols(Ljava/util/List;)Lcom/android/okhttp/OkHttpClient;
+Lcom/android/okhttp/okio/ByteString;->readObject(Ljava/io/ObjectInputStream;)V
+Lcom/android/okhttp/okio/ByteString;->writeObject(Ljava/io/ObjectOutputStream;)V
Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getAlpnSelectedProtocol()[B
+Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getNpnSelectedProtocol()[B
Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([B)V
+Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setHostname(Ljava/lang/String;)V
+Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setNpnProtocols([B)V
+Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setUseSessionTickets(Z)V
+Lcom/android/org/conscrypt/TrustManagerImpl;-><init>(Ljava/security/KeyStore;)V
Ldalvik/system/BaseDexClassLoader;->getLdLibraryPath()Ljava/lang/String;
Ldalvik/system/BaseDexClassLoader;->pathList:Ldalvik/system/DexPathList;
Ldalvik/system/BlockGuard;->getThreadPolicy()Ldalvik/system/BlockGuard$Policy;
@@ -1459,15 +2343,22 @@
Ldalvik/system/DexFile;->mCookie:Ljava/lang/Object;
Ldalvik/system/DexFile;->mFileName:Ljava/lang/String;
Ldalvik/system/DexFile;->openDexFile(Ljava/lang/String;Ljava/lang/String;ILjava/lang/ClassLoader;[Ldalvik/system/DexPathList$Element;)Ljava/lang/Object;
+Ldalvik/system/DexPathList;->addDexPath(Ljava/lang/String;Ljava/io/File;)V
Ldalvik/system/DexPathList;->dexElements:[Ldalvik/system/DexPathList$Element;
Ldalvik/system/DexPathList$Element;->dexFile:Ldalvik/system/DexFile;
+Ldalvik/system/DexPathList$Element;-><init>(Ldalvik/system/DexFile;Ljava/io/File;)V
+Ldalvik/system/DexPathList$Element;-><init>(Ljava/io/File;ZLjava/io/File;Ldalvik/system/DexFile;)V
+Ldalvik/system/DexPathList;-><init>(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;Ljava/io/File;)V
Ldalvik/system/DexPathList;->makeDexElements(Ljava/util/List;Ljava/io/File;Ljava/util/List;Ljava/lang/ClassLoader;)[Ldalvik/system/DexPathList$Element;
Ldalvik/system/DexPathList;->makePathElements(Ljava/util/List;)[Ldalvik/system/DexPathList$NativeLibraryElement;
Ldalvik/system/DexPathList;->makePathElements(Ljava/util/List;Ljava/io/File;Ljava/util/List;)[Ldalvik/system/DexPathList$Element;
Ldalvik/system/DexPathList;->nativeLibraryDirectories:Ljava/util/List;
+Ldalvik/system/DexPathList$NativeLibraryElement;-><init>(Ljava/io/File;)V
Ldalvik/system/DexPathList;->nativeLibraryPathElements:[Ldalvik/system/DexPathList$NativeLibraryElement;
+Ldalvik/system/DexPathList;->splitPaths(Ljava/lang/String;Z)Ljava/util/List;
Ldalvik/system/DexPathList;->systemNativeLibraryDirectories:Ljava/util/List;
Ldalvik/system/VMDebug;->dumpReferenceTables()V
+Ldalvik/system/VMRuntime;->addressOf(Ljava/lang/Object;)J
Ldalvik/system/VMRuntime;->clearGrowthLimit()V
Ldalvik/system/VMRuntime;->getCurrentInstructionSet()Ljava/lang/String;
Ldalvik/system/VMRuntime;->getRuntime()Ldalvik/system/VMRuntime;
@@ -1480,32 +2371,68 @@
Ldalvik/system/VMRuntime;->setTargetHeapUtilization(F)F
Ldalvik/system/VMRuntime;->trackExternalAllocation(J)Z
Ldalvik/system/VMRuntime;->trackExternalFree(J)V
+Ldalvik/system/VMRuntime;->vmInstructionSet()Ljava/lang/String;
+Ldalvik/system/VMRuntime;->vmLibrary()Ljava/lang/String;
Ldalvik/system/VMStack;->getCallingClassLoader()Ljava/lang/ClassLoader;
Ldalvik/system/VMStack;->getStackClass2()Ljava/lang/Class;
+Ljava/awt/font/NumericShaper;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/beans/PropertyChangeSupport;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/beans/PropertyChangeSupport;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/io/FileDescriptor;->descriptor:I
Ljava/io/FileDescriptor;->getInt$()I
Ljava/io/FileDescriptor;->setInt$(I)V
+Ljava/io/FileInputStream;->fd:Ljava/io/FileDescriptor;
+Ljava/io/FileOutputStream;->fd:Ljava/io/FileDescriptor;
+Ljava/io/File;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/io/File;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/io/ObjectStreamClass;->getConstructorId(Ljava/lang/Class;)J
Ljava/io/ObjectStreamClass;->newInstance(Ljava/lang/Class;J)Ljava/lang/Object;
Ljava/io/ObjectStreamClass;->newInstance()Ljava/lang/Object;
+Ljava/io/UncheckedIOException;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/lang/AbstractStringBuilder;->value:[C
+Ljava/lang/Boolean;->value:Z
+Ljava/lang/Byte;->value:B
+Ljava/lang/Character;->value:C
Ljava/lang/Class;->dexCache:Ljava/lang/Object;
Ljava/lang/Class;->dexClassDefIndex:I
Ljava/lang/ClassLoader;->parent:Ljava/lang/ClassLoader;
+Ljava/lang/Daemons$Daemon;->isRunning()Z
+Ljava/lang/Daemons$Daemon;->start()V
Ljava/lang/Daemons$Daemon;->stop()V
Ljava/lang/Daemons$Daemon;->thread:Ljava/lang/Thread;
Ljava/lang/Daemons$FinalizerDaemon;->finalizingObject:Ljava/lang/Object;
Ljava/lang/Daemons$FinalizerDaemon;->INSTANCE:Ljava/lang/Daemons$FinalizerDaemon;
Ljava/lang/Daemons$FinalizerWatchdogDaemon;->INSTANCE:Ljava/lang/Daemons$FinalizerWatchdogDaemon;
+Ljava/lang/Daemons;->MAX_FINALIZE_NANOS:J
+Ljava/lang/Daemons$ReferenceQueueDaemon;->INSTANCE:Ljava/lang/Daemons$ReferenceQueueDaemon;
Ljava/lang/Daemons;->requestHeapTrim()V
Ljava/lang/Daemons;->start()V
Ljava/lang/Daemons;->stop()V
+Ljava/lang/Double;->value:D
+Ljava/lang/Enum;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/lang/Float;->value:F
+Ljava/lang/Integer;->value:I
+Ljava/lang/invoke/MethodType;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/lang/invoke/MethodType;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/lang/Long;->value:J
Ljava/lang/ref/FinalizerReference;->add(Ljava/lang/Object;)V
+Ljava/lang/ref/FinalizerReference;->head:Ljava/lang/ref/FinalizerReference;
+Ljava/lang/ref/FinalizerReference;->next:Ljava/lang/ref/FinalizerReference;
+Ljava/lang/ref/FinalizerReference;->queue:Ljava/lang/ref/ReferenceQueue;
+Ljava/lang/ref/FinalizerReference;->remove(Ljava/lang/ref/FinalizerReference;)V
Ljava/lang/reflect/Executable;->artMethod:J
Ljava/lang/reflect/Parameter;-><init>(Ljava/lang/String;ILjava/lang/reflect/Executable;I)V
+Ljava/lang/reflect/Proxy;->invoke(Ljava/lang/reflect/Proxy;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
Ljava/lang/ref/ReferenceQueue;->add(Ljava/lang/ref/Reference;)V
+Ljava/lang/ref/Reference;->referent:Ljava/lang/Object;
Ljava/lang/Runtime;->loadLibrary(Ljava/lang/String;Ljava/lang/ClassLoader;)V
Ljava/lang/Runtime;->load(Ljava/lang/String;Ljava/lang/ClassLoader;)V
Ljava/lang/Runtime;->nativeLoad(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/String;
+Ljava/lang/Short;->value:S
+Ljava/lang/StringBuffer;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/lang/StringBuffer;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/lang/StringBuilder;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/lang/StringBuilder;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/lang/String;-><init>(II[C)V
Ljava/lang/Thread;->daemon:Z
Ljava/lang/Thread;->dispatchUncaughtException(Ljava/lang/Throwable;)V
@@ -1527,37 +2454,245 @@
Ljava/lang/Throwable;->backtrace:Ljava/lang/Object;
Ljava/lang/Throwable;->cause:Ljava/lang/Throwable;
Ljava/lang/Throwable;->detailMessage:Ljava/lang/String;
+Ljava/lang/Throwable;->readObject(Ljava/io/ObjectInputStream;)V
Ljava/lang/Throwable;->stackTrace:[Ljava/lang/StackTraceElement;
Ljava/lang/Throwable;->suppressedExceptions:Ljava/util/List;
+Ljava/lang/Throwable;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/lang/Void;-><init>()V
+Ljava/math/BigDecimal;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/math/BigDecimal;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/math/BigInteger;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/math/BigInteger;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/math/MathContext;->readObject(Ljava/io/ObjectInputStream;)V
Ljava/net/Authenticator;->theAuthenticator:Ljava/net/Authenticator;
Ljava/net/DatagramSocket;->impl:Ljava/net/DatagramSocketImpl;
+Ljava/net/HttpCookie;->httpOnly:Z
+Ljava/net/HttpCookie;->whenCreated:J
+Ljava/net/Inet4Address;-><init>()V
+Ljava/net/Inet6Address;->holder6:Ljava/net/Inet6Address$Inet6AddressHolder;
+Ljava/net/Inet6Address$Inet6AddressHolder;->ipaddress:[B
+Ljava/net/Inet6Address$Inet6AddressHolder;->scope_id:I
+Ljava/net/Inet6Address$Inet6AddressHolder;->scope_id_set:Z
+Ljava/net/Inet6Address$Inet6AddressHolder;->scope_ifname:Ljava/net/NetworkInterface;
+Ljava/net/Inet6Address;-><init>()V
+Ljava/net/Inet6Address;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/net/Inet6Address;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/net/InetAddress;->clearDnsCache()V
+Ljava/net/InetAddress;->holder:Ljava/net/InetAddress$InetAddressHolder;
+Ljava/net/InetAddress$InetAddressHolder;->address:I
+Ljava/net/InetAddress$InetAddressHolder;->family:I
+Ljava/net/InetAddress$InetAddressHolder;->hostName:Ljava/lang/String;
+Ljava/net/InetAddress$InetAddressHolder;->originalHostName:Ljava/lang/String;
Ljava/net/InetAddress;->isNumeric(Ljava/lang/String;)Z
Ljava/net/InetAddress;->parseNumericAddress(Ljava/lang/String;)Ljava/net/InetAddress;
+Ljava/net/InetAddress;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/net/InetAddress;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/net/InetSocketAddress;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/net/InetSocketAddress;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/net/Socket;->getFileDescriptor$()Ljava/io/FileDescriptor;
Ljava/net/Socket;->impl:Ljava/net/SocketImpl;
Ljava/net/URI;->host:Ljava/lang/String;
+Ljava/net/URI;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/net/URI;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/net/URL;->handlers:Ljava/util/Hashtable;
+Ljava/net/URL;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/net/URL;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/nio/Buffer;->address:J
Ljava/nio/Buffer;->capacity:I
+Ljava/nio/Buffer;->_elementSizeShift:I
Ljava/nio/Buffer;->limit:I
+Ljava/nio/Buffer;->position:I
Ljava/nio/ByteBuffer;->hb:[B
Ljava/nio/ByteBuffer;->isReadOnly:Z
Ljava/nio/ByteBuffer;->offset:I
Ljava/nio/charset/CharsetEncoder;->canEncode(Ljava/nio/CharBuffer;)Z
Ljava/nio/DirectByteBuffer;-><init>(JI)V
+Ljava/nio/file/DirectoryIteratorException;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/nio/NIOAccess;->getBaseArray(Ljava/nio/Buffer;)Ljava/lang/Object;
+Ljava/nio/NIOAccess;->getBaseArrayOffset(Ljava/nio/Buffer;)I
+Ljava/nio/NIOAccess;->getBasePointer(Ljava/nio/Buffer;)J
+Ljava/security/cert/CertificateRevokedException;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/security/cert/CertificateRevokedException;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/security/cert/CertPathValidatorException;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/security/CodeSigner;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/security/GuardedObject;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/security/Provider;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/security/SignedObject;->readObject(Ljava/io/ObjectInputStream;)V
Ljava/security/spec/ECParameterSpec;->getCurveName()Ljava/lang/String;
Ljava/security/spec/ECParameterSpec;->setCurveName(Ljava/lang/String;)V
+Ljava/security/Timestamp;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/text/ChoiceFormat;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/text/DateFormatSymbols;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/text/DateFormatSymbols;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/text/DecimalFormat;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/text/DecimalFormatSymbols;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/text/DecimalFormatSymbols;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/text/DecimalFormat;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/text/MessageFormat;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/text/NumberFormat;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/text/NumberFormat;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/text/SimpleDateFormat;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/chrono/AbstractChronology;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/chrono/HijrahChronology;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/chrono/HijrahDate;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/chrono/IsoChronology;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/chrono/JapaneseChronology;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/chrono/JapaneseDate;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/chrono/JapaneseEra;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/chrono/MinguoChronology;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/chrono/MinguoDate;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/chrono/ThaiBuddhistChronology;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/chrono/ThaiBuddhistDate;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/Duration;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/Instant;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/LocalDate;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/LocalDateTime;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/LocalTime;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/MonthDay;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/OffsetDateTime;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/OffsetTime;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/Period;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/temporal/ValueRange;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/temporal/WeekFields;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/YearMonth;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/Year;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/ZonedDateTime;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/ZoneId;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/ZoneOffset;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/zone/ZoneOffsetTransition;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/zone/ZoneOffsetTransitionRule;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/time/zone/ZoneRules;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/ArrayDeque;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/ArrayDeque;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/util/ArrayList;->elementData:[Ljava/lang/Object;
+Ljava/util/ArrayList;->readObject(Ljava/io/ObjectInputStream;)V
Ljava/util/ArrayList;->size:I
Ljava/util/ArrayList$SubList;->parent:Ljava/util/AbstractList;
Ljava/util/ArrayList$SubList;->parentOffset:I
Ljava/util/ArrayList$SubList;->size:I
+Ljava/util/ArrayList;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/util/Arrays$ArrayList;->a:[Ljava/lang/Object;
+Ljava/util/BitSet;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/BitSet;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/Calendar;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/Calendar;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/util/Calendar;->zone:Ljava/util/TimeZone;
+Ljava/util/Collections$EmptyList;-><init>()V
+Ljava/util/Collections$SetFromMap;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/Collections$SynchronizedCollection;->c:Ljava/util/Collection;
+Ljava/util/Collections$SynchronizedCollection;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/Collections$SynchronizedMap;->m:Ljava/util/Map;
+Ljava/util/Collections$SynchronizedMap;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/Collections$UnmodifiableCollection;->c:Ljava/util/Collection;
+Ljava/util/Collections$UnmodifiableMap;->m:Ljava/util/Map;
+Ljava/util/concurrent/atomic/AtomicReferenceArray;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/atomic/DoubleAccumulator;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/atomic/DoubleAdder;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/atomic/LongAccumulator;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/atomic/LongAdder;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/ConcurrentHashMap;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/ConcurrentHashMap;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/concurrent/ConcurrentLinkedDeque;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/ConcurrentLinkedDeque;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/concurrent/ConcurrentLinkedQueue;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/ConcurrentLinkedQueue;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/concurrent/ConcurrentSkipListMap;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/ConcurrentSkipListMap;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/concurrent/CopyOnWriteArrayList;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/CopyOnWriteArrayList;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/concurrent/ForkJoinTask;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/ForkJoinTask;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/util/concurrent/FutureTask;->callable:Ljava/util/concurrent/Callable;
+Ljava/util/concurrent/LinkedBlockingDeque;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/LinkedBlockingDeque;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/concurrent/LinkedBlockingQueue;->capacity:I
+Ljava/util/concurrent/LinkedBlockingQueue;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/LinkedBlockingQueue;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/concurrent/LinkedTransferQueue;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/LinkedTransferQueue;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/concurrent/locks/ReentrantLock$Sync;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/locks/ReentrantReadWriteLock$Sync;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/locks/StampedLock;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/PriorityBlockingQueue;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/PriorityBlockingQueue;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/concurrent/SynchronousQueue;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/concurrent/SynchronousQueue;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/concurrent/ThreadLocalRandom;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/Date;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/Date;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/EnumMap;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/EnumMap;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/EnumSet;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/GregorianCalendar;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/HashMap$HashIterator;->hasNext()Z
+Ljava/util/HashMap;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/HashMap;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/HashSet;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/HashSet;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/Hashtable;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/Hashtable;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/IdentityHashMap;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/IdentityHashMap;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/InvalidPropertiesFormatException;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/InvalidPropertiesFormatException;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/LinkedHashMap;->eldest()Ljava/util/Map$Entry;
+Ljava/util/LinkedList;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/LinkedList;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/util/Locale;->createConstant(Ljava/lang/String;Ljava/lang/String;)Ljava/util/Locale;
+Ljava/util/Locale;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/Locale;->readResolve()Ljava/lang/Object;
+Ljava/util/Locale;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/logging/LogRecord;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/logging/LogRecord;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/prefs/NodeChangeEvent;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/prefs/NodeChangeEvent;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/prefs/PreferenceChangeEvent;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/prefs/PreferenceChangeEvent;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/PriorityQueue;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/PriorityQueue;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/Random;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/Random;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/regex/Matcher;->appendPos:I
+Ljava/util/regex/Pattern;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/SimpleTimeZone;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/SimpleTimeZone;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/TreeMap;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/TreeMap;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/TreeSet;->readObject(Ljava/io/ObjectInputStream;)V
+Ljava/util/TreeSet;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/Vector;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljava/util/zip/Deflater;->buf:[B
+Ljava/util/zip/Deflater;->finished:Z
+Ljava/util/zip/Deflater;->finish:Z
+Ljava/util/zip/Deflater;->len:I
+Ljava/util/zip/Deflater;->level:I
+Ljava/util/zip/Deflater;->off:I
+Ljava/util/zip/Deflater;->setParams:Z
+Ljava/util/zip/Deflater;->strategy:I
+Ljava/util/zip/Inflater;->buf:[B
+Ljava/util/zip/Inflater;->finished:Z
+Ljava/util/zip/Inflater;->len:I
+Ljava/util/zip/Inflater;->needDict:Z
+Ljava/util/zip/Inflater;->off:I
+Ljava/util/zip/ZipEntry;-><init>(Ljava/lang/String;Ljava/lang/String;JJJII[BJ)V
+Ljava/util/zip/ZipFile;->jzfile:J
+Ljavax/crypto/SealedObject;->readObject(Ljava/io/ObjectInputStream;)V
Ljavax/net/ssl/SSLServerSocketFactory;->defaultServerSocketFactory:Ljavax/net/ssl/SSLServerSocketFactory;
Ljavax/net/ssl/SSLSocketFactory;->defaultSocketFactory:Ljavax/net/ssl/SSLSocketFactory;
+Ljavax/security/auth/Subject;->readObject(Ljava/io/ObjectInputStream;)V
+Ljavax/security/auth/Subject$SecureSet;->readObject(Ljava/io/ObjectInputStream;)V
+Ljavax/security/auth/Subject$SecureSet;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljavax/security/auth/Subject;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljavax/security/auth/x500/X500Principal;->readObject(Ljava/io/ObjectInputStream;)V
+Ljavax/security/auth/x500/X500Principal;->writeObject(Ljava/io/ObjectOutputStream;)V
+Ljavax/xml/datatype/DatatypeConfigurationException;->readObject(Ljava/io/ObjectInputStream;)V
+Ljavax/xml/namespace/QName;->readObject(Ljava/io/ObjectInputStream;)V
Llibcore/util/ZoneInfo;->mTransitions:[J
+Llibcore/util/ZoneInfo;->readObject(Ljava/io/ObjectInputStream;)V
Lorg/apache/http/conn/ssl/SSLSocketFactory;-><init>(Ljavax/net/ssl/SSLSocketFactory;)V
+Lorg/apache/http/conn/ssl/SSLSocketFactory;-><init>()V
Lorg/json/JSONArray;->values:Ljava/util/List;
+Lorg/json/JSONObject;->writeTo(Lorg/json/JSONStringer;)V
Lsun/misc/Unsafe;->theUnsafe:Lsun/misc/Unsafe;
+Lsun/security/util/ObjectIdentifier;->readObject(Ljava/io/ObjectInputStream;)V
+Lsun/security/util/ObjectIdentifier;->writeObject(Ljava/io/ObjectOutputStream;)V
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 4626cb2..b365d52 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -219,6 +219,9 @@
/**
* Start activity {@code intents} as if {@code packageName} on user {@code userId} did it.
*
+ * - DO NOT call it with the calling UID cleared.
+ * - All the necessary caller permission checks must be done at callsites.
+ *
* @return error codes used by {@link IActivityManager#startActivity} and its siblings.
*/
public abstract int startActivitiesAsPackage(String packageName,
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index c805658..e80610b 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -8862,6 +8862,7 @@
private static final String EXTRA_CONTENT_INTENT = "content_intent";
private static final String EXTRA_DELETE_INTENT = "delete_intent";
private static final String EXTRA_CHANNEL_ID = "channel_id";
+ private static final String EXTRA_SUPPRESS_SHOW_OVER_APPS = "suppressShowOverApps";
// Flags bitwise-ored to mFlags
private static final int FLAG_AVAILABLE_ON_TV = 0x1;
@@ -8870,6 +8871,7 @@
private String mChannelId;
private PendingIntent mContentIntent;
private PendingIntent mDeleteIntent;
+ private boolean mSuppressShowOverApps;
/**
* Create a {@link TvExtender} with default options.
@@ -8889,6 +8891,7 @@
if (bundle != null) {
mFlags = bundle.getInt(EXTRA_FLAGS);
mChannelId = bundle.getString(EXTRA_CHANNEL_ID);
+ mSuppressShowOverApps = bundle.getBoolean(EXTRA_SUPPRESS_SHOW_OVER_APPS);
mContentIntent = bundle.getParcelable(EXTRA_CONTENT_INTENT);
mDeleteIntent = bundle.getParcelable(EXTRA_DELETE_INTENT);
}
@@ -8905,6 +8908,7 @@
bundle.putInt(EXTRA_FLAGS, mFlags);
bundle.putString(EXTRA_CHANNEL_ID, mChannelId);
+ bundle.putBoolean(EXTRA_SUPPRESS_SHOW_OVER_APPS, mSuppressShowOverApps);
if (mContentIntent != null) {
bundle.putParcelable(EXTRA_CONTENT_INTENT, mContentIntent);
}
@@ -8997,6 +9001,23 @@
public PendingIntent getDeleteIntent() {
return mDeleteIntent;
}
+
+ /**
+ * Specifies whether this notification should suppress showing a message over top of apps
+ * outside of the launcher.
+ */
+ public TvExtender setSuppressShowOverApps(boolean suppress) {
+ mSuppressShowOverApps = suppress;
+ return this;
+ }
+
+ /**
+ * Returns true if this notification should not show messages over top of apps
+ * outside of the launcher.
+ */
+ public boolean getSuppressShowOverApps() {
+ return mSuppressShowOverApps;
+ }
}
/**
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index ea0fd75..256c479 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -471,6 +471,14 @@
* {@link #onStart} and returns either {@link #START_STICKY}
* or {@link #START_STICKY_COMPATIBILITY}.
*
+ * <p>If you need your application to run on platform versions prior to API
+ * level 5, you can use the following model to handle the older {@link #onStart}
+ * callback in that case. The <code>handleCommand</code> method is implemented by
+ * you as appropriate:
+ *
+ * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
+ * start_compatibility}
+ *
* <p class="caution">Note that the system calls this on your
* service's main thread. A service's main thread is the same
* thread where UI operations take place for Activities running in the
@@ -679,10 +687,6 @@
* {@link #startService(Intent)} first to tell the system it should keep the service running,
* and then use this method to tell it to keep it running harder.</p>
*
- * <p>Apps targeting API {@link android.os.Build.VERSION_CODES#P} or later must request
- * the permission {@link android.Manifest.permission#FOREGROUND_SERVICE} in order to use
- * this API.</p>
- *
* @param id The identifier for this notification as per
* {@link NotificationManager#notify(int, Notification)
* NotificationManager.notify(int, Notification)}; must not be 0.
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index 28e845a..8c30fc4 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -19,6 +19,8 @@
import android.accounts.AccountManager;
import android.annotation.BroadcastBehavior;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
@@ -34,9 +36,6 @@
import android.os.UserHandle;
import android.security.KeyChain;
-import libcore.util.NonNull;
-import libcore.util.Nullable;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -928,29 +927,29 @@
int networkLogsCount) {
}
- /**
- * Called when a user or profile is created.
- *
- * <p>This callback is only applicable to device owners.
- *
- * @param context The running context as per {@link #onReceive}.
- * @param intent The received intent as per {@link #onReceive}.
- * @param newUser The {@link UserHandle} of the user that has just been added.
- */
- public void onUserAdded(Context context, Intent intent, UserHandle newUser) {
- }
+ /**
+ * Called when a user or profile is created.
+ *
+ * <p>This callback is only applicable to device owners.
+ *
+ * @param context The running context as per {@link #onReceive}.
+ * @param intent The received intent as per {@link #onReceive}.
+ * @param newUser The {@link UserHandle} of the user that has just been added.
+ */
+ public void onUserAdded(Context context, Intent intent, @NonNull UserHandle newUser) {
+ }
- /**
- * Called when a user or profile is removed.
- *
- * <p>This callback is only applicable to device owners.
- *
- * @param context The running context as per {@link #onReceive}.
- * @param intent The received intent as per {@link #onReceive}.
- * @param removedUser The {@link UserHandle} of the user that has just been removed.
- */
- public void onUserRemoved(Context context, Intent intent, UserHandle removedUser) {
- }
+ /**
+ * Called when a user or profile is removed.
+ *
+ * <p>This callback is only applicable to device owners.
+ *
+ * @param context The running context as per {@link #onReceive}.
+ * @param intent The received intent as per {@link #onReceive}.
+ * @param removedUser The {@link UserHandle} of the user that has just been removed.
+ */
+ public void onUserRemoved(Context context, Intent intent, @NonNull UserHandle removedUser) {
+ }
/**
* Called when a user or profile is started.
@@ -961,7 +960,7 @@
* @param intent The received intent as per {@link #onReceive}.
* @param startedUser The {@link UserHandle} of the user that has just been started.
*/
- public void onUserStarted(Context context, Intent intent, UserHandle startedUser) {
+ public void onUserStarted(Context context, Intent intent, @NonNull UserHandle startedUser) {
}
/**
@@ -973,7 +972,7 @@
* @param intent The received intent as per {@link #onReceive}.
* @param stoppedUser The {@link UserHandle} of the user that has just been stopped.
*/
- public void onUserStopped(Context context, Intent intent, UserHandle stoppedUser) {
+ public void onUserStopped(Context context, Intent intent, @NonNull UserHandle stoppedUser) {
}
/**
@@ -985,7 +984,7 @@
* @param intent The received intent as per {@link #onReceive}.
* @param switchedUser The {@link UserHandle} of the user that has just been switched to.
*/
- public void onUserSwitched(Context context, Intent intent, UserHandle switchedUser) {
+ public void onUserSwitched(Context context, Intent intent, @NonNull UserHandle switchedUser) {
}
/**
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 77e118c..b29644b 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -3444,9 +3444,6 @@
/**
* Flag for {@link #wipeData(int)}: also erase the device's eUICC data.
- *
- * TODO(b/35851809): make this public.
- * @hide
*/
public static final int WIPE_EUICC = 0x0004;
diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
index a1ad825c..ee13880 100644
--- a/core/java/android/app/job/JobInfo.java
+++ b/core/java/android/app/job/JobInfo.java
@@ -365,9 +365,7 @@
/** @hide */
public boolean isExemptedFromAppStandby() {
- return ((flags & FLAG_EXEMPT_FROM_APP_STANDBY) != 0)
- && !hasEarlyConstraint()
- && !hasLateConstraint();
+ return ((flags & FLAG_EXEMPT_FROM_APP_STANDBY) != 0) && !isPeriodic();
}
/**
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 15f3777..a738312 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3671,10 +3671,8 @@
*
* @see #getSystemService(String)
* @see android.telephony.euicc.EuiccManager
- * TODO(b/35851809): Unhide this API.
- * @hide
*/
- public static final String EUICC_SERVICE = "euicc_service";
+ public static final String EUICC_SERVICE = "euicc";
/**
* Use with {@link #getSystemService(String)} to retrieve a
@@ -3682,10 +3680,10 @@
*
* @see #getSystemService(String)
* @see android.telephony.euicc.EuiccCardManager
- * TODO(b/35851809): Make this a SystemApi.
* @hide
*/
- public static final String EUICC_CARD_SERVICE = "euicc_card_service";
+ @SystemApi
+ public static final String EUICC_CARD_SERVICE = "euicc_card";
/**
* Use with {@link #getSystemService(String)} to retrieve a
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 12d4079..e7aead1 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2498,6 +2498,9 @@
* off, not sleeping). Once the broadcast is complete, the final shutdown
* will proceed and all unsaved data lost. Apps will not normally need
* to handle this, since the foreground activity will be paused as well.
+ * <p>As of {@link Build.VERSION_CODES#P} this broadcast is only sent to receivers registered
+ * through {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
+ * Context.registerReceiver}.
*
* <p class="note">This is a protected intent that can only be sent
* by the system.
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 486c86c..08fccab 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2108,8 +2108,6 @@
/**
* Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device
* supports embedded subscriptions on eUICCs.
- * TODO(b/35851809): Make this public.
- * @hide
*/
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_TELEPHONY_EUICC = "android.hardware.telephony.euicc";
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 96d043c..3f8eaa9 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1372,9 +1372,6 @@
* <p>The origin for {@link CameraCharacteristics#LENS_POSE_TRANSLATION android.lens.poseTranslation}.</p>
* <p>Different calibration methods and use cases can produce better or worse results
* depending on the selected coordinate origin.</p>
- * <p>For devices designed to support the MOTION_TRACKING capability, the GYROSCOPE origin
- * makes device calibration and later usage by applications combining camera and gyroscope
- * information together simpler.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #LENS_POSE_REFERENCE_PRIMARY_CAMERA PRIMARY_CAMERA}</li>
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index df64401..fd285ae 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -145,37 +145,6 @@
*/
public static final int TEMPLATE_MANUAL = 6;
- /**
- * A template for selecting camera parameters that match TEMPLATE_PREVIEW as closely as
- * possible while improving the camera output for motion tracking use cases.
- *
- * <p>This template is best used by applications that are frequently switching between motion
- * tracking use cases and regular still capture use cases, to minimize the IQ changes
- * when swapping use cases.</p>
- *
- * <p>This template is guaranteed to be supported on camera devices that support the
- * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING MOTION_TRACKING}
- * capability.</p>
- *
- * @see #createCaptureRequest
- */
- public static final int TEMPLATE_MOTION_TRACKING_PREVIEW = 7;
-
- /**
- * A template for selecting camera parameters that maximize the quality of camera output for
- * motion tracking use cases.
- *
- * <p>This template is best used by applications dedicated to motion tracking applications,
- * which aren't concerned about fast switches between motion tracking and other use cases.</p>
- *
- * <p>This template is guaranteed to be supported on camera devices that support the
- * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING MOTION_TRACKING}
- * capability.</p>
- *
- * @see #createCaptureRequest
- */
- public static final int TEMPLATE_MOTION_TRACKING_BEST = 8;
-
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"TEMPLATE_"}, value =
@@ -184,9 +153,7 @@
TEMPLATE_RECORD,
TEMPLATE_VIDEO_SNAPSHOT,
TEMPLATE_ZERO_SHUTTER_LAG,
- TEMPLATE_MANUAL,
- TEMPLATE_MOTION_TRACKING_PREVIEW,
- TEMPLATE_MOTION_TRACKING_BEST})
+ TEMPLATE_MANUAL})
public @interface RequestTemplate {};
/**
@@ -420,27 +387,6 @@
* </table><br>
* </p>
*
- * <p>MOTION_TRACKING-capability ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES}
- * includes
- * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING MOTION_TRACKING})
- * devices support at least the below stream combinations in addition to those for
- * {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED LIMITED} devices. The
- * {@code FULL FOV 640} entry means that the device will support a resolution that's 640 pixels
- * wide, with the height set so that the resolution aspect ratio matches the MAXIMUM output
- * aspect ratio, rounded down. So for a device with a 4:3 image sensor, this will be 640x480,
- * and for a device with a 16:9 sensor, this will be 640x360, and so on. And the
- * {@code MAX 30FPS} entry means the largest JPEG resolution on the device for which
- * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration}
- * returns a value less than or equal to 1/30s.
- *
- * <table>
- * <tr><th colspan="7">MOTION_TRACKING-capability additional guaranteed configurations</th></tr>
- * <tr><th colspan="2" id="rb">Target 1</th><th colspan="2" id="rb">Target 2</th><th colspan="2" id="rb">Target 3</th><th rowspan="2">Sample use case(s)</th> </tr>
- * <tr><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th></tr>
- * <tr> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV }</td><td id="rb">{@code FULL FOV 640}</td> <td>{@code JPEG}</td><td id="rb">{@code MAX 30FPS}</td> <td>Preview with a tracking YUV output and a as-large-as-possible JPEG for still captures.</td> </tr>
- * </table><br>
- * </p>
- *
* <p>BURST-capability ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES} includes
* {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE BURST_CAPTURE}) devices
* support at least the below stream combinations in addition to those for
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index e7c8961..732f6a5 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -342,7 +342,7 @@
/**
* <p>The value of {@link CameraCharacteristics#LENS_POSE_TRANSLATION android.lens.poseTranslation} is relative to the optical center of
* the largest camera device facing the same direction as this camera.</p>
- * <p>This default value for API levels before Android P.</p>
+ * <p>This is the default value for API levels before Android P.</p>
*
* @see CameraCharacteristics#LENS_POSE_TRANSLATION
* @see CameraCharacteristics#LENS_POSE_REFERENCE
@@ -352,7 +352,6 @@
/**
* <p>The value of {@link CameraCharacteristics#LENS_POSE_TRANSLATION android.lens.poseTranslation} is relative to the position of the
* primary gyroscope of this Android device.</p>
- * <p>This is the value reported by all devices that support the MOTION_TRACKING capability.</p>
*
* @see CameraCharacteristics#LENS_POSE_TRANSLATION
* @see CameraCharacteristics#LENS_POSE_REFERENCE
@@ -801,46 +800,12 @@
public static final int REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO = 9;
/**
- * <p>The device supports controls and metadata required for accurate motion tracking for
- * use cases such as augmented reality, electronic image stabilization, and so on.</p>
- * <p>This means this camera device has accurate optical calibration and timestamps relative
- * to the inertial sensors.</p>
- * <p>This capability requires the camera device to support the following:</p>
- * <ul>
- * <li>Capture request templates {@link android.hardware.camera2.CameraDevice#TEMPLATE_MOTION_TRACKING_PREVIEW } and {@link android.hardware.camera2.CameraDevice#TEMPLATE_MOTION_TRACKING_BEST } are defined.</li>
- * <li>The stream configurations listed in {@link android.hardware.camera2.CameraDevice#createCaptureSession } for MOTION_TRACKING are
- * supported, either at 30 or 60fps maximum frame rate.</li>
- * <li>The following camera characteristics and capture result metadata are provided:<ul>
- * <li>{@link CameraCharacteristics#LENS_INTRINSIC_CALIBRATION android.lens.intrinsicCalibration}</li>
- * <li>{@link CameraCharacteristics#LENS_RADIAL_DISTORTION android.lens.radialDistortion}</li>
- * <li>{@link CameraCharacteristics#LENS_POSE_ROTATION android.lens.poseRotation}</li>
- * <li>{@link CameraCharacteristics#LENS_POSE_TRANSLATION android.lens.poseTranslation}</li>
- * <li>{@link CameraCharacteristics#LENS_POSE_REFERENCE android.lens.poseReference} with value GYROSCOPE</li>
- * </ul>
- * </li>
- * <li>The {@link CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE android.sensor.info.timestampSource} field has value <code>REALTIME</code>. When compared to
- * timestamps from the device's gyroscopes, the clock difference for events occuring at
- * the same actual time instant will be less than 1 ms.</li>
- * <li>The value of the {@link CaptureResult#SENSOR_ROLLING_SHUTTER_SKEW android.sensor.rollingShutterSkew} field is accurate to within 1 ms.</li>
- * <li>The value of {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime} is guaranteed to be available in the
- * capture result.</li>
- * <li>The {@link CaptureRequest#CONTROL_CAPTURE_INTENT android.control.captureIntent} control supports MOTION_TRACKING to limit maximum
- * exposure to 20 milliseconds.</li>
- * <li>The stream configurations required for MOTION_TRACKING (listed at {@link android.hardware.camera2.CameraDevice#createCaptureSession }) can operate at least at
- * 30fps; optionally, they can operate at 60fps, and '[60, 60]' is listed in
- * {@link CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES android.control.aeAvailableTargetFpsRanges}.</li>
- * </ul>
+ * <p>The camera device supports the MOTION_TRACKING value for
+ * {@link CaptureRequest#CONTROL_CAPTURE_INTENT android.control.captureIntent}, which limits maximum exposure time to 20 ms.</p>
+ * <p>This limits the motion blur of capture images, resulting in better image tracking
+ * results for use cases such as image stabilization or augmented reality.</p>
*
- * @see CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES
* @see CaptureRequest#CONTROL_CAPTURE_INTENT
- * @see CameraCharacteristics#LENS_INTRINSIC_CALIBRATION
- * @see CameraCharacteristics#LENS_POSE_REFERENCE
- * @see CameraCharacteristics#LENS_POSE_ROTATION
- * @see CameraCharacteristics#LENS_POSE_TRANSLATION
- * @see CameraCharacteristics#LENS_RADIAL_DISTORTION
- * @see CaptureRequest#SENSOR_EXPOSURE_TIME
- * @see CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE
- * @see CaptureResult#SENSOR_ROLLING_SHUTTER_SKEW
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
public static final int REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING = 10;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 481b764..3ed533a 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -2757,11 +2757,11 @@
new Key<Integer>("android.statistics.lensShadingMapMode", int.class);
/**
- * <p>Whether the camera device outputs the OIS data in output
+ * <p>A control for selecting whether OIS position information is included in output
* result metadata.</p>
* <p>When set to ON,
* {@link CaptureResult#STATISTICS_OIS_TIMESTAMPS android.statistics.oisTimestamps}, android.statistics.oisShiftPixelX,
- * android.statistics.oisShiftPixelY will provide OIS data in the output result metadata.</p>
+ * and android.statistics.oisShiftPixelY provide OIS data in the output result metadata.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #STATISTICS_OIS_DATA_MODE_OFF OFF}</li>
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index d730fa8..c332d30 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -3909,11 +3909,11 @@
new Key<Integer>("android.statistics.lensShadingMapMode", int.class);
/**
- * <p>Whether the camera device outputs the OIS data in output
+ * <p>A control for selecting whether OIS position information is included in output
* result metadata.</p>
* <p>When set to ON,
* {@link CaptureResult#STATISTICS_OIS_TIMESTAMPS android.statistics.oisTimestamps}, android.statistics.oisShiftPixelX,
- * android.statistics.oisShiftPixelY will provide OIS data in the output result metadata.</p>
+ * and android.statistics.oisShiftPixelY provide OIS data in the output result metadata.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #STATISTICS_OIS_DATA_MODE_OFF OFF}</li>
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index fc78861..48f5684 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -894,14 +894,6 @@
/**
* P.
- *
- * <p>Applications targeting this or a later release will get these
- * new changes in behavior:</p>
- * <ul>
- * <li>{@link android.app.Service#startForeground Service.startForeground} requires
- * that apps hold the permission
- * {@link android.Manifest.permission#FOREGROUND_SERVICE}.</li>
- * </ul>
*/
public static final int P = CUR_DEVELOPMENT; // STOPSHIP Replace with the real version.
}
diff --git a/core/java/android/preference/OWNERS b/core/java/android/preference/OWNERS
new file mode 100644
index 0000000..d20511f
--- /dev/null
+++ b/core/java/android/preference/OWNERS
@@ -0,0 +1,2 @@
+pavlis@google.com
+clarabayarri@google.com
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a183895..021c22c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8563,9 +8563,8 @@
*
* @see android.service.euicc.EuiccService
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+ @SystemApi
public static final String DEFAULT_SM_DP_PLUS = "default_sm_dp_plus";
/**
diff --git a/core/java/android/service/euicc/EuiccProfileInfo.java b/core/java/android/service/euicc/EuiccProfileInfo.java
index 8e752d1..cb4f104 100644
--- a/core/java/android/service/euicc/EuiccProfileInfo.java
+++ b/core/java/android/service/euicc/EuiccProfileInfo.java
@@ -17,6 +17,7 @@
import android.annotation.IntDef;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.service.carrier.CarrierIdentifier;
@@ -26,15 +27,15 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
+import java.util.List;
import java.util.Objects;
/**
* Information about an embedded profile (subscription) on an eUICC.
*
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+@SystemApi
public final class EuiccProfileInfo implements Parcelable {
/** Profile policy rules (bit mask) */
@@ -44,6 +45,7 @@
POLICY_RULE_DO_NOT_DELETE,
POLICY_RULE_DELETE_AFTER_DISABLING
})
+ /** @hide */
public @interface PolicyRule {}
/** Once this profile is enabled, it cannot be disabled. */
public static final int POLICY_RULE_DO_NOT_DISABLE = 1;
@@ -60,6 +62,7 @@
PROFILE_CLASS_OPERATIONAL,
PROFILE_CLASS_UNSET
})
+ /** @hide */
public @interface ProfileClass {}
/** Testing profiles */
public static final int PROFILE_CLASS_TESTING = 0;
@@ -80,6 +83,7 @@
PROFILE_STATE_ENABLED,
PROFILE_STATE_UNSET
})
+ /** @hide */
public @interface ProfileState {}
/** Disabled profiles */
public static final int PROFILE_STATE_DISABLED = 0;
@@ -92,34 +96,34 @@
public static final int PROFILE_STATE_UNSET = -1;
/** The iccid of the subscription. */
- public final String iccid;
+ private final String mIccid;
/** An optional nickname for the subscription. */
- public final @Nullable String nickname;
+ private final @Nullable String mNickname;
/** The service provider name for the subscription. */
- public final String serviceProviderName;
+ private final String mServiceProviderName;
/** The profile name for the subscription. */
- public final String profileName;
+ private final String mProfileName;
/** Profile class for the subscription. */
- @ProfileClass public final int profileClass;
+ @ProfileClass private final int mProfileClass;
/** The profile state of the subscription. */
- @ProfileState public final int state;
+ @ProfileState private final int mState;
/** The operator Id of the subscription. */
- public final CarrierIdentifier carrierIdentifier;
+ private final CarrierIdentifier mCarrierIdentifier;
/** The policy rules of the subscription. */
- @PolicyRule public final int policyRules;
+ @PolicyRule private final int mPolicyRules;
/**
* Optional access rules defining which apps can manage this subscription. If unset, only the
* platform can manage it.
*/
- public final @Nullable UiccAccessRule[] accessRules;
+ private final @Nullable UiccAccessRule[] mAccessRules;
public static final Creator<EuiccProfileInfo> CREATOR = new Creator<EuiccProfileInfo>() {
@Override
@@ -144,51 +148,51 @@
if (!TextUtils.isDigitsOnly(iccid)) {
throw new IllegalArgumentException("iccid contains invalid characters: " + iccid);
}
- this.iccid = iccid;
- this.accessRules = accessRules;
- this.nickname = nickname;
+ this.mIccid = iccid;
+ this.mAccessRules = accessRules;
+ this.mNickname = nickname;
- this.serviceProviderName = null;
- this.profileName = null;
- this.profileClass = PROFILE_CLASS_UNSET;
- this.state = PROFILE_CLASS_UNSET;
- this.carrierIdentifier = null;
- this.policyRules = 0;
+ this.mServiceProviderName = null;
+ this.mProfileName = null;
+ this.mProfileClass = PROFILE_CLASS_UNSET;
+ this.mState = PROFILE_STATE_UNSET;
+ this.mCarrierIdentifier = null;
+ this.mPolicyRules = 0;
}
private EuiccProfileInfo(Parcel in) {
- iccid = in.readString();
- nickname = in.readString();
- serviceProviderName = in.readString();
- profileName = in.readString();
- profileClass = in.readInt();
- state = in.readInt();
+ mIccid = in.readString();
+ mNickname = in.readString();
+ mServiceProviderName = in.readString();
+ mProfileName = in.readString();
+ mProfileClass = in.readInt();
+ mState = in.readInt();
byte exist = in.readByte();
if (exist == (byte) 1) {
- carrierIdentifier = CarrierIdentifier.CREATOR.createFromParcel(in);
+ mCarrierIdentifier = CarrierIdentifier.CREATOR.createFromParcel(in);
} else {
- carrierIdentifier = null;
+ mCarrierIdentifier = null;
}
- policyRules = in.readInt();
- accessRules = in.createTypedArray(UiccAccessRule.CREATOR);
+ mPolicyRules = in.readInt();
+ mAccessRules = in.createTypedArray(UiccAccessRule.CREATOR);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(iccid);
- dest.writeString(nickname);
- dest.writeString(serviceProviderName);
- dest.writeString(profileName);
- dest.writeInt(profileClass);
- dest.writeInt(state);
- if (carrierIdentifier != null) {
+ dest.writeString(mIccid);
+ dest.writeString(mNickname);
+ dest.writeString(mServiceProviderName);
+ dest.writeString(mProfileName);
+ dest.writeInt(mProfileClass);
+ dest.writeInt(mState);
+ if (mCarrierIdentifier != null) {
dest.writeByte((byte) 1);
- carrierIdentifier.writeToParcel(dest, flags);
+ mCarrierIdentifier.writeToParcel(dest, flags);
} else {
dest.writeByte((byte) 0);
}
- dest.writeInt(policyRules);
- dest.writeTypedArray(accessRules, flags);
+ dest.writeInt(mPolicyRules);
+ dest.writeTypedArray(mAccessRules, flags);
}
@Override
@@ -198,45 +202,50 @@
/** The builder to build a new {@link EuiccProfileInfo} instance. */
public static final class Builder {
- public String iccid;
- public UiccAccessRule[] accessRules;
- public String nickname;
- public String serviceProviderName;
- public String profileName;
- @ProfileClass public int profileClass;
- @ProfileState public int state;
- public CarrierIdentifier carrierIdentifier;
- @PolicyRule public int policyRules;
+ private String mIccid;
+ private List<UiccAccessRule> mAccessRules;
+ private String mNickname;
+ private String mServiceProviderName;
+ private String mProfileName;
+ @ProfileClass private int mProfileClass;
+ @ProfileState private int mState;
+ private CarrierIdentifier mCarrierIdentifier;
+ @PolicyRule private int mPolicyRules;
- public Builder() {}
+ public Builder(String value) {
+ if (!TextUtils.isDigitsOnly(value)) {
+ throw new IllegalArgumentException("iccid contains invalid characters: " + value);
+ }
+ mIccid = value;
+ }
public Builder(EuiccProfileInfo baseProfile) {
- iccid = baseProfile.iccid;
- nickname = baseProfile.nickname;
- serviceProviderName = baseProfile.serviceProviderName;
- profileName = baseProfile.profileName;
- profileClass = baseProfile.profileClass;
- state = baseProfile.state;
- carrierIdentifier = baseProfile.carrierIdentifier;
- policyRules = baseProfile.policyRules;
- accessRules = baseProfile.accessRules;
+ mIccid = baseProfile.mIccid;
+ mNickname = baseProfile.mNickname;
+ mServiceProviderName = baseProfile.mServiceProviderName;
+ mProfileName = baseProfile.mProfileName;
+ mProfileClass = baseProfile.mProfileClass;
+ mState = baseProfile.mState;
+ mCarrierIdentifier = baseProfile.mCarrierIdentifier;
+ mPolicyRules = baseProfile.mPolicyRules;
+ mAccessRules = Arrays.asList(baseProfile.mAccessRules);
}
/** Builds the profile instance. */
public EuiccProfileInfo build() {
- if (iccid == null) {
+ if (mIccid == null) {
throw new IllegalStateException("ICCID must be set for a profile.");
}
return new EuiccProfileInfo(
- iccid,
- nickname,
- serviceProviderName,
- profileName,
- profileClass,
- state,
- carrierIdentifier,
- policyRules,
- accessRules);
+ mIccid,
+ mNickname,
+ mServiceProviderName,
+ mProfileName,
+ mProfileClass,
+ mState,
+ mCarrierIdentifier,
+ mPolicyRules,
+ mAccessRules);
}
/** Sets the iccId of the subscription. */
@@ -244,55 +253,55 @@
if (!TextUtils.isDigitsOnly(value)) {
throw new IllegalArgumentException("iccid contains invalid characters: " + value);
}
- iccid = value;
+ mIccid = value;
return this;
}
/** Sets the nickname of the subscription. */
public Builder setNickname(String value) {
- nickname = value;
+ mNickname = value;
return this;
}
/** Sets the service provider name of the subscription. */
public Builder setServiceProviderName(String value) {
- serviceProviderName = value;
+ mServiceProviderName = value;
return this;
}
/** Sets the profile name of the subscription. */
public Builder setProfileName(String value) {
- profileName = value;
+ mProfileName = value;
return this;
}
/** Sets the profile class of the subscription. */
public Builder setProfileClass(@ProfileClass int value) {
- profileClass = value;
+ mProfileClass = value;
return this;
}
/** Sets the state of the subscription. */
public Builder setState(@ProfileState int value) {
- state = value;
+ mState = value;
return this;
}
/** Sets the carrier identifier of the subscription. */
public Builder setCarrierIdentifier(CarrierIdentifier value) {
- carrierIdentifier = value;
+ mCarrierIdentifier = value;
return this;
}
/** Sets the policy rules of the subscription. */
public Builder setPolicyRules(@PolicyRule int value) {
- policyRules = value;
+ mPolicyRules = value;
return this;
}
/** Sets the access rules of the subscription. */
- public Builder setUiccAccessRule(@Nullable UiccAccessRule[] value) {
- accessRules = value;
+ public Builder setUiccAccessRule(@Nullable List<UiccAccessRule> value) {
+ mAccessRules = value;
return this;
}
}
@@ -306,75 +315,81 @@
@ProfileState int state,
CarrierIdentifier carrierIdentifier,
@PolicyRule int policyRules,
- @Nullable UiccAccessRule[] accessRules) {
- this.iccid = iccid;
- this.nickname = nickname;
- this.serviceProviderName = serviceProviderName;
- this.profileName = profileName;
- this.profileClass = profileClass;
- this.state = state;
- this.carrierIdentifier = carrierIdentifier;
- this.policyRules = policyRules;
- this.accessRules = accessRules;
+ @Nullable List<UiccAccessRule> accessRules) {
+ this.mIccid = iccid;
+ this.mNickname = nickname;
+ this.mServiceProviderName = serviceProviderName;
+ this.mProfileName = profileName;
+ this.mProfileClass = profileClass;
+ this.mState = state;
+ this.mCarrierIdentifier = carrierIdentifier;
+ this.mPolicyRules = policyRules;
+ if (accessRules != null && accessRules.size() > 0) {
+ this.mAccessRules = accessRules.toArray(new UiccAccessRule[accessRules.size()]);
+ } else {
+ this.mAccessRules = null;
+ }
}
/** Gets the ICCID string. */
public String getIccid() {
- return iccid;
+ return mIccid;
}
/** Gets the access rules. */
@Nullable
- public UiccAccessRule[] getUiccAccessRules() {
- return accessRules;
+ public List<UiccAccessRule> getUiccAccessRules() {
+ if (mAccessRules == null) return null;
+ return Arrays.asList(mAccessRules);
}
/** Gets the nickname. */
+ @Nullable
public String getNickname() {
- return nickname;
+ return mNickname;
}
/** Gets the service provider name. */
public String getServiceProviderName() {
- return serviceProviderName;
+ return mServiceProviderName;
}
/** Gets the profile name. */
public String getProfileName() {
- return profileName;
+ return mProfileName;
}
/** Gets the profile class. */
@ProfileClass
public int getProfileClass() {
- return profileClass;
+ return mProfileClass;
}
/** Gets the state of the subscription. */
@ProfileState
public int getState() {
- return state;
+ return mState;
}
/** Gets the carrier identifier. */
public CarrierIdentifier getCarrierIdentifier() {
- return carrierIdentifier;
+ return mCarrierIdentifier;
}
/** Gets the policy rules. */
@PolicyRule
public int getPolicyRules() {
- return policyRules;
+ return mPolicyRules;
}
/** Returns whether any policy rule exists. */
public boolean hasPolicyRules() {
- return policyRules != 0;
+ return mPolicyRules != 0;
}
/** Checks whether a certain policy rule exists. */
public boolean hasPolicyRule(@PolicyRule int policy) {
- return (policyRules & policy) != 0;
+ return (mPolicyRules & policy) != 0;
}
@Override
@@ -387,50 +402,50 @@
}
EuiccProfileInfo that = (EuiccProfileInfo) obj;
- return Objects.equals(iccid, that.iccid)
- && Objects.equals(nickname, that.nickname)
- && Objects.equals(serviceProviderName, that.serviceProviderName)
- && Objects.equals(profileName, that.profileName)
- && profileClass == that.profileClass
- && state == that.state
- && Objects.equals(carrierIdentifier, that.carrierIdentifier)
- && policyRules == that.policyRules
- && Arrays.equals(accessRules, that.accessRules);
+ return Objects.equals(mIccid, that.mIccid)
+ && Objects.equals(mNickname, that.mNickname)
+ && Objects.equals(mServiceProviderName, that.mServiceProviderName)
+ && Objects.equals(mProfileName, that.mProfileName)
+ && mProfileClass == that.mProfileClass
+ && mState == that.mState
+ && Objects.equals(mCarrierIdentifier, that.mCarrierIdentifier)
+ && mPolicyRules == that.mPolicyRules
+ && Arrays.equals(mAccessRules, that.mAccessRules);
}
@Override
public int hashCode() {
int result = 1;
- result = 31 * result + Objects.hashCode(iccid);
- result = 31 * result + Objects.hashCode(nickname);
- result = 31 * result + Objects.hashCode(serviceProviderName);
- result = 31 * result + Objects.hashCode(profileName);
- result = 31 * result + profileClass;
- result = 31 * result + state;
- result = 31 * result + Objects.hashCode(carrierIdentifier);
- result = 31 * result + policyRules;
- result = 31 * result + Arrays.hashCode(accessRules);
+ result = 31 * result + Objects.hashCode(mIccid);
+ result = 31 * result + Objects.hashCode(mNickname);
+ result = 31 * result + Objects.hashCode(mServiceProviderName);
+ result = 31 * result + Objects.hashCode(mProfileName);
+ result = 31 * result + mProfileClass;
+ result = 31 * result + mState;
+ result = 31 * result + Objects.hashCode(mCarrierIdentifier);
+ result = 31 * result + mPolicyRules;
+ result = 31 * result + Arrays.hashCode(mAccessRules);
return result;
}
@Override
public String toString() {
return "EuiccProfileInfo (nickname="
- + nickname
+ + mNickname
+ ", serviceProviderName="
- + serviceProviderName
+ + mServiceProviderName
+ ", profileName="
- + profileName
+ + mProfileName
+ ", profileClass="
- + profileClass
+ + mProfileClass
+ ", state="
- + state
+ + mState
+ ", CarrierIdentifier="
- + carrierIdentifier.toString()
+ + mCarrierIdentifier.toString()
+ ", policyRules="
- + policyRules
+ + mPolicyRules
+ ", accessRules="
- + Arrays.toString(accessRules)
+ + Arrays.toString(mAccessRules)
+ ")";
}
}
diff --git a/core/java/android/service/euicc/EuiccService.java b/core/java/android/service/euicc/EuiccService.java
index be85800..b87faef 100644
--- a/core/java/android/service/euicc/EuiccService.java
+++ b/core/java/android/service/euicc/EuiccService.java
@@ -17,6 +17,7 @@
import android.annotation.CallSuper;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
@@ -41,8 +42,11 @@
* <p>To implement the LPA backend, you must extend this class and declare this service in your
* manifest file. The service must require the
* {@link android.Manifest.permission#BIND_EUICC_SERVICE} permission and include an intent filter
- * with the {@link #EUICC_SERVICE_INTERFACE} action. The priority of the intent filter must be set
- * to a non-zero value in case multiple implementations are present on the device. For example:
+ * with the {@link #EUICC_SERVICE_INTERFACE} action. It's suggested that the priority of the intent
+ * filter to be set to a non-zero value in case multiple implementations are present on the device.
+ * See the below example. Note that there will be problem if two LPAs are present and they have the
+ * same priority.
+ * Example:
*
* <pre>{@code
* <service android:name=".MyEuiccService"
@@ -65,9 +69,9 @@
* filter with the appropriate action, the {@link #CATEGORY_EUICC_UI} category, and a non-zero
* priority.
*
- * TODO(b/35851809): Make this a SystemApi.
* @hide
*/
+@SystemApi
public abstract class EuiccService extends Service {
/** Action which must be included in this service's intent filter. */
public static final String EUICC_SERVICE_INTERFACE = "android.service.euicc.EuiccService";
@@ -77,7 +81,10 @@
// LUI actions. These are passthroughs of the corresponding EuiccManager actions.
- /** @see android.telephony.euicc.EuiccManager#ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS */
+ /**
+ * @see android.telephony.euicc.EuiccManager#ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS
+ * The difference is this one is used by system to bring up the LUI.
+ */
public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS =
"android.service.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS";
/** @see android.telephony.euicc.EuiccManager#ACTION_PROVISION_EMBEDDED_SUBSCRIPTION */
@@ -88,7 +95,10 @@
// require user interaction.
// TODO(b/33075886): Define extras for any input parameters to these dialogs once they are
// more scoped out.
- /** Alert the user that this action will result in an active SIM being deactivated. */
+ /**
+ * Alert the user that this action will result in an active SIM being deactivated.
+ * To implement the LUI triggered by the system, you need to define this in AndroidManifest.xml.
+ */
public static final String ACTION_RESOLVE_DEACTIVATE_SIM =
"android.service.euicc.action.RESOLVE_DEACTIVATE_SIM";
/**
@@ -102,7 +112,11 @@
public static final String ACTION_RESOLVE_CONFIRMATION_CODE =
"android.service.euicc.action.RESOLVE_CONFIRMATION_CODE";
- /** Intent extra set for resolution requests containing the package name of the calling app. */
+ /**
+ * Intent extra set for resolution requests containing the package name of the calling app.
+ * This is used by the above actions including ACTION_RESOLVE_DEACTIVATE_SIM,
+ * ACTION_RESOLVE_NO_PRIVILEGES and ACTION_RESOLVE_CONFIRMATION_CODE.
+ */
public static final String EXTRA_RESOLUTION_CALLING_PACKAGE =
"android.service.euicc.extra.RESOLUTION_CALLING_PACKAGE";
@@ -136,10 +150,18 @@
RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_CONFIRMATION_CODE);
}
- /** Boolean extra for resolution actions indicating whether the user granted consent. */
- public static final String RESOLUTION_EXTRA_CONSENT = "consent";
- /** String extra for resolution actions indicating the carrier confirmation code. */
- public static final String RESOLUTION_EXTRA_CONFIRMATION_CODE = "confirmation_code";
+ /**
+ * Boolean extra for resolution actions indicating whether the user granted consent.
+ * This is used and set by the implementation and used in {@code EuiccOperation}.
+ */
+ public static final String EXTRA_RESOLUTION_CONSENT =
+ "android.service.euicc.extra.RESOLUTION_CONSENT";
+ /**
+ * String extra for resolution actions indicating the carrier confirmation code.
+ * This is used and set by the implementation and used in {@code EuiccOperation}.
+ */
+ public static final String EXTRA_RESOLUTION_CONFIRMATION_CODE =
+ "android.service.euicc.extra.RESOLUTION_CONFIRMATION_CODE";
private final IEuiccService.Stub mStubWrapper;
@@ -199,9 +221,9 @@
*
* @see IEuiccService#startOtaIfNecessary
*/
- public interface OtaStatusChangedCallback {
+ public abstract static class OtaStatusChangedCallback {
/** Called when OTA status is changed. */
- void onOtaStatusChanged(int status);
+ public abstract void onOtaStatusChanged(int status);
}
/**
@@ -238,8 +260,7 @@
/**
* Populate {@link DownloadableSubscription} metadata for the given downloadable subscription.
*
- * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
- * but is here to future-proof the APIs.
+ * @param slotId ID of the SIM slot to use for the operation.
* @param subscription A subscription whose metadata needs to be populated.
* @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the
* eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM)}
@@ -267,8 +288,7 @@
/**
* Download the given subscription.
*
- * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
- * but is here to future-proof the APIs.
+ * @param slotId ID of the SIM slot to use for the operation.
* @param subscription The subscription to download.
* @param switchAfterDownload If true, the subscription should be enabled upon successful
* download.
@@ -286,8 +306,7 @@
/**
* Return a list of all @link EuiccProfileInfo}s.
*
- * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
- * but is here to future-proof the APIs.
+ * @param slotId ID of the SIM slot to use for the operation.
* @return The result of the operation.
* @see android.telephony.SubscriptionManager#getAvailableSubscriptionInfoList
* @see android.telephony.SubscriptionManager#getAccessibleSubscriptionInfoList
@@ -297,8 +316,7 @@
/**
* Return info about the eUICC chip/device.
*
- * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
- * but is here to future-proof the APIs.
+ * @param slotId ID of the SIM slot to use for the operation.
* @return the {@link EuiccInfo} for the eUICC chip/device.
* @see android.telephony.euicc.EuiccManager#getEuiccInfo
*/
@@ -310,8 +328,7 @@
* <p>If the subscription is currently active, it should be deactivated first (equivalent to a
* physical SIM being ejected).
*
- * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
- * but is here to future-proof the APIs.
+ * @param slotId ID of the SIM slot to use for the operation.
* @param iccid the ICCID of the subscription to delete.
* @return the result of the delete operation. May be one of the predefined {@code RESULT_}
* constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
@@ -322,8 +339,7 @@
/**
* Switch to the given subscription.
*
- * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
- * but is here to future-proof the APIs.
+ * @param slotId ID of the SIM slot to use for the operation.
* @param iccid the ICCID of the subscription to enable. May be null, in which case the current
* profile should be deactivated and no profile should be activated to replace it - this is
* equivalent to a physical SIM being ejected.
@@ -340,8 +356,7 @@
/**
* Update the nickname of the given subscription.
*
- * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
- * but is here to future-proof the APIs.
+ * @param slotId ID of the SIM slot to use for the operation.
* @param iccid the ICCID of the subscription to update.
* @param nickname the new nickname to apply.
* @return the result of the update operation. May be one of the predefined {@code RESULT_}
diff --git a/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java b/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java
index 5a24492..e2171ae 100644
--- a/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java
+++ b/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java
@@ -16,16 +16,19 @@
package android.service.euicc;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.euicc.DownloadableSubscription;
+import java.util.Arrays;
+import java.util.List;
+
/**
* Result of a {@link EuiccService#onGetDefaultDownloadableSubscriptionList} operation.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+@SystemApi
public final class GetDefaultDownloadableSubscriptionListResult implements Parcelable {
public static final Creator<GetDefaultDownloadableSubscriptionListResult> CREATOR =
@@ -42,20 +45,35 @@
};
/**
- * Result of the operation.
+ * @hide
+ * @deprecated - Do no use. Use getResult() instead.
+ */
+ @Deprecated
+ public final int result;
+
+ @Nullable
+ private final DownloadableSubscription[] mSubscriptions;
+
+ /**
+ * Gets the result of the operation.
*
* <p>May be one of the predefined {@code RESULT_} constants in EuiccService or any
* implementation-specific code starting with {@link EuiccService#RESULT_FIRST_USER}.
*/
- public final int result;
+ public int getResult() {
+ return result;
+ }
/**
- * The available {@link DownloadableSubscription}s (with filled-in metadata).
+ * Gets the available {@link DownloadableSubscription}s (with filled-in metadata).
*
* <p>Only non-null if {@link #result} is {@link EuiccService#RESULT_OK}.
*/
@Nullable
- public final DownloadableSubscription[] subscriptions;
+ public List<DownloadableSubscription> getDownloadableSubscriptions() {
+ if (mSubscriptions == null) return null;
+ return Arrays.asList(mSubscriptions);
+ }
/**
* Construct a new {@link GetDefaultDownloadableSubscriptionListResult}.
@@ -70,25 +88,25 @@
@Nullable DownloadableSubscription[] subscriptions) {
this.result = result;
if (this.result == EuiccService.RESULT_OK) {
- this.subscriptions = subscriptions;
+ this.mSubscriptions = subscriptions;
} else {
if (subscriptions != null) {
throw new IllegalArgumentException(
"Error result with non-null subscriptions: " + result);
}
- this.subscriptions = null;
+ this.mSubscriptions = null;
}
}
private GetDefaultDownloadableSubscriptionListResult(Parcel in) {
this.result = in.readInt();
- this.subscriptions = in.createTypedArray(DownloadableSubscription.CREATOR);
+ this.mSubscriptions = in.createTypedArray(DownloadableSubscription.CREATOR);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(result);
- dest.writeTypedArray(subscriptions, flags);
+ dest.writeTypedArray(mSubscriptions, flags);
}
@Override
diff --git a/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java b/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java
index de8a307..1edb539 100644
--- a/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java
+++ b/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java
@@ -16,6 +16,7 @@
package android.service.euicc;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.euicc.DownloadableSubscription;
@@ -23,9 +24,8 @@
/**
* Result of a {@link EuiccService#onGetDownloadableSubscriptionMetadata} operation.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+@SystemApi
public final class GetDownloadableSubscriptionMetadataResult implements Parcelable {
public static final Creator<GetDownloadableSubscriptionMetadataResult> CREATOR =
@@ -42,20 +42,34 @@
};
/**
- * Result of the operation.
+ * @hide
+ * @deprecated - Do no use. Use getResult() instead.
+ */
+ @Deprecated
+ public final int result;
+
+ @Nullable
+ private final DownloadableSubscription mSubscription;
+
+ /**
+ * Gets the result of the operation.
*
* <p>May be one of the predefined {@code RESULT_} constants in EuiccService or any
* implementation-specific code starting with {@link EuiccService#RESULT_FIRST_USER}.
*/
- public final int result;
+ public int getResult() {
+ return result;
+ }
/**
- * The {@link DownloadableSubscription} with filled-in metadata.
+ * Gets the {@link DownloadableSubscription} with filled-in metadata.
*
* <p>Only non-null if {@link #result} is {@link EuiccService#RESULT_OK}.
*/
@Nullable
- public final DownloadableSubscription subscription;
+ public DownloadableSubscription getDownloadableSubscription() {
+ return mSubscription;
+ }
/**
* Construct a new {@link GetDownloadableSubscriptionMetadataResult}.
@@ -70,25 +84,25 @@
@Nullable DownloadableSubscription subscription) {
this.result = result;
if (this.result == EuiccService.RESULT_OK) {
- this.subscription = subscription;
+ this.mSubscription = subscription;
} else {
if (subscription != null) {
throw new IllegalArgumentException(
"Error result with non-null subscription: " + result);
}
- this.subscription = null;
+ this.mSubscription = null;
}
}
private GetDownloadableSubscriptionMetadataResult(Parcel in) {
this.result = in.readInt();
- this.subscription = in.readTypedObject(DownloadableSubscription.CREATOR);
+ this.mSubscription = in.readTypedObject(DownloadableSubscription.CREATOR);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(result);
- dest.writeTypedObject(this.subscription, flags);
+ dest.writeTypedObject(this.mSubscription, flags);
}
@Override
diff --git a/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java b/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java
index 7ad8488..464d136 100644
--- a/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java
+++ b/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java
@@ -16,15 +16,18 @@
package android.service.euicc;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
+import java.util.Arrays;
+import java.util.List;
+
/**
* Result of a {@link EuiccService#onGetEuiccProfileInfoList} operation.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+@SystemApi
public final class GetEuiccProfileInfoListResult implements Parcelable {
public static final Creator<GetEuiccProfileInfoListResult> CREATOR =
@@ -41,19 +44,38 @@
};
/**
- * Result of the operation.
+ * @hide
+ * @deprecated - Do no use. Use getResult() instead.
+ */
+ @Deprecated
+ public final int result;
+
+ @Nullable
+ private final EuiccProfileInfo[] mProfiles;
+
+ private final boolean mIsRemovable;
+
+ /**
+ * Gets the result of the operation.
*
* <p>May be one of the predefined {@code RESULT_} constants in EuiccService or any
* implementation-specific code starting with {@link EuiccService#RESULT_FIRST_USER}.
*/
- public final int result;
+ public int getResult() {
+ return result;
+ }
- /** The profile list (only upon success). */
+ /** Gets the profile list (only upon success). */
@Nullable
- public final EuiccProfileInfo[] profiles;
+ public List<EuiccProfileInfo> getProfiles() {
+ if (mProfiles == null) return null;
+ return Arrays.asList(mProfiles);
+ }
- /** Whether the eUICC is removable. */
- public final boolean isRemovable;
+ /** Gets whether the eUICC is removable. */
+ public boolean getIsRemovable() {
+ return mIsRemovable;
+ }
/**
* Construct a new {@link GetEuiccProfileInfoListResult}.
@@ -71,30 +93,29 @@
public GetEuiccProfileInfoListResult(
int result, @Nullable EuiccProfileInfo[] profiles, boolean isRemovable) {
this.result = result;
- this.isRemovable = isRemovable;
+ this.mIsRemovable = isRemovable;
if (this.result == EuiccService.RESULT_OK) {
- this.profiles = profiles;
+ this.mProfiles = profiles;
} else {
if (profiles != null) {
throw new IllegalArgumentException(
"Error result with non-null profiles: " + result);
}
- this.profiles = null;
+ this.mProfiles = null;
}
-
}
private GetEuiccProfileInfoListResult(Parcel in) {
this.result = in.readInt();
- this.profiles = in.createTypedArray(EuiccProfileInfo.CREATOR);
- this.isRemovable = in.readBoolean();
+ this.mProfiles = in.createTypedArray(EuiccProfileInfo.CREATOR);
+ this.mIsRemovable = in.readBoolean();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(result);
- dest.writeTypedArray(profiles, flags);
- dest.writeBoolean(isRemovable);
+ dest.writeTypedArray(mProfiles, flags);
+ dest.writeBoolean(mIsRemovable);
}
@Override
diff --git a/core/java/android/text/BoringLayout.java b/core/java/android/text/BoringLayout.java
index 6fa5312..dbe4157 100644
--- a/core/java/android/text/BoringLayout.java
+++ b/core/java/android/text/BoringLayout.java
@@ -322,6 +322,12 @@
*/
public static Metrics isBoring(CharSequence text, TextPaint paint,
TextDirectionHeuristic textDir, Metrics metrics) {
+ return isBoring(text, null /* precomputed */, paint, textDir, metrics);
+ }
+
+ /** @hide */
+ public static Metrics isBoring(CharSequence text, PrecomputedText precomputed, TextPaint paint,
+ TextDirectionHeuristic textDir, Metrics metrics) {
final int textLength = text.length();
if (hasAnyInterestingChars(text, textLength)) {
return null; // There are some interesting characters. Not boring.
@@ -344,18 +350,17 @@
fm.reset();
}
- TextLine line = TextLine.obtain();
- line.set(paint, text, 0, textLength, Layout.DIR_LEFT_TO_RIGHT,
- Layout.DIRS_ALL_LEFT_TO_RIGHT, false, null);
- if (text instanceof MeasuredText) {
- MeasuredText mt = (MeasuredText) text;
+ if (precomputed != null) {
// Reaching here means there is only one paragraph.
- MeasuredParagraph mp = mt.getMeasuredParagraph(0);
+ MeasuredParagraph mp = precomputed.getMeasuredParagraph(0);
fm.width = (int) Math.ceil(mp.getWidth(0, mp.getTextLength()));
} else {
+ TextLine line = TextLine.obtain();
+ line.set(paint, text, 0, textLength, Layout.DIR_LEFT_TO_RIGHT,
+ Layout.DIRS_ALL_LEFT_TO_RIGHT, false, null);
fm.width = (int) Math.ceil(line.metrics(fm));
+ TextLine.recycle(line);
}
- TextLine.recycle(line);
return fm;
}
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index 18431ca..10444f0 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -363,7 +363,7 @@
@JustificationMode int justificationMode,
@Nullable TextUtils.TruncateAt ellipsize,
@IntRange(from = 0) int ellipsizedWidth) {
- super(createEllipsizer(ellipsize, display),
+ super(createEllipsizer(ellipsize, display), null /* precomputed */,
paint, width, align, textDir, spacingmult, spacingadd);
final Builder b = Builder.obtain(base, paint, width)
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index aa97b2a..d5d3590 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -245,6 +245,13 @@
protected Layout(CharSequence text, TextPaint paint,
int width, Alignment align, TextDirectionHeuristic textDir,
float spacingMult, float spacingAdd) {
+ this(text, null /* precomputed */, paint, width, align, textDir, spacingMult, spacingAdd);
+ }
+
+ /** @hide */
+ protected Layout(CharSequence text, PrecomputedText precomputed, TextPaint paint,
+ int width, Alignment align, TextDirectionHeuristic textDir,
+ float spacingMult, float spacingAdd) {
if (width < 0)
throw new IllegalArgumentException("Layout: " + width + " < 0");
@@ -259,6 +266,7 @@
}
mText = text;
+ mPrecomputed = precomputed;
mPaint = paint;
mWidth = width;
mAlignment = align;
@@ -562,7 +570,7 @@
// XXX: assumes there's nothing additional to be done
canvas.drawText(buf, start, end, x, lbaseline, paint);
} else {
- tl.set(paint, buf, start, end, dir, directions, hasTab, tabStops);
+ tl.set(paint, buf, mPrecomputed, start, end, dir, directions, hasTab, tabStops);
if (justify) {
tl.justify(right - left - indentWidth);
}
@@ -2264,6 +2272,7 @@
}
private CharSequence mText;
+ private PrecomputedText mPrecomputed;
private TextPaint mPaint;
private TextPaint mWorkPaint = new TextPaint();
private int mWidth;
diff --git a/core/java/android/text/MeasuredText.java b/core/java/android/text/MeasuredText.java
deleted file mode 100644
index bb7a9e0..0000000
--- a/core/java/android/text/MeasuredText.java
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * Copyright (C) 2017 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 android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.util.IntArray;
-
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.Preconditions;
-
-import java.util.ArrayList;
-
-/**
- * A text which has already been measured.
- */
-public class MeasuredText implements Spanned {
- private static final char LINE_FEED = '\n';
-
- // The original text.
- private final @NonNull CharSequence mText;
-
- // The inclusive start offset of the measuring target.
- private final @IntRange(from = 0) int mStart;
-
- // The exclusive end offset of the measuring target.
- private final @IntRange(from = 0) int mEnd;
-
- // The TextPaint used for measurement.
- private final @NonNull TextPaint mPaint;
-
- // The requested text direction.
- private final @NonNull TextDirectionHeuristic mTextDir;
-
- // The measured paragraph texts.
- private final @NonNull MeasuredParagraph[] mMeasuredParagraphs;
-
- // The sorted paragraph end offsets.
- private final @NonNull int[] mParagraphBreakPoints;
-
- // The break strategy for this measured text.
- private final @Layout.BreakStrategy int mBreakStrategy;
-
- // The hyphenation frequency for this measured text.
- private final @Layout.HyphenationFrequency int mHyphenationFrequency;
-
- /**
- * A Builder for MeasuredText
- */
- public static final class Builder {
- // Mandatory parameters.
- private final @NonNull CharSequence mText;
- private final @NonNull TextPaint mPaint;
-
- // Members to be updated by setters.
- private @IntRange(from = 0) int mStart;
- private @IntRange(from = 0) int mEnd;
- private TextDirectionHeuristic mTextDir = TextDirectionHeuristics.FIRSTSTRONG_LTR;
- private @Layout.BreakStrategy int mBreakStrategy = Layout.BREAK_STRATEGY_HIGH_QUALITY;
- private @Layout.HyphenationFrequency int mHyphenationFrequency =
- Layout.HYPHENATION_FREQUENCY_NORMAL;
-
-
- /**
- * Builder constructor
- *
- * @param text The text to be measured.
- * @param paint The paint to be used for drawing.
- */
- public Builder(@NonNull CharSequence text, @NonNull TextPaint paint) {
- Preconditions.checkNotNull(text);
- Preconditions.checkNotNull(paint);
-
- mText = text;
- mPaint = paint;
- mStart = 0;
- mEnd = text.length();
- }
-
- /**
- * Set the range of measuring target.
- *
- * @param start The measuring target start offset in the text.
- * @param end The measuring target end offset in the text.
- */
- public @NonNull Builder setRange(@IntRange(from = 0) int start,
- @IntRange(from = 0) int end) {
- Preconditions.checkArgumentInRange(start, 0, mText.length(), "start");
- Preconditions.checkArgumentInRange(end, 0, mText.length(), "end");
- Preconditions.checkArgument(start <= end, "The range is reversed.");
-
- mStart = start;
- mEnd = end;
- return this;
- }
-
- /**
- * Set the text direction heuristic
- *
- * The default value is {@link TextDirectionHeuristics#FIRSTSTRONG_LTR}.
- *
- * @param textDir The text direction heuristic for resolving bidi behavior.
- * @return this builder, useful for chaining.
- */
- public @NonNull Builder setTextDirection(@NonNull TextDirectionHeuristic textDir) {
- Preconditions.checkNotNull(textDir);
- mTextDir = textDir;
- return this;
- }
-
- /**
- * Set the break strategy
- *
- * The default value is {@link Layout#BREAK_STRATEGY_HIGH_QUALITY}.
- *
- * @param breakStrategy The break strategy.
- * @return this builder, useful for chaining.
- */
- public @NonNull Builder setBreakStrategy(@Layout.BreakStrategy int breakStrategy) {
- mBreakStrategy = breakStrategy;
- return this;
- }
-
- /**
- * Set the hyphenation frequency
- *
- * The default value is {@link Layout#HYPHENATION_FREQUENCY_NORMAL}.
- *
- * @param hyphenationFrequency The hyphenation frequency.
- * @return this builder, useful for chaining.
- */
- public @NonNull Builder setHyphenationFrequency(
- @Layout.HyphenationFrequency int hyphenationFrequency) {
- mHyphenationFrequency = hyphenationFrequency;
- return this;
- }
-
- /**
- * Build the measured text
- *
- * @return the measured text.
- */
- public @NonNull MeasuredText build() {
- return build(true /* build full layout result */);
- }
-
- /** @hide */
- public @NonNull MeasuredText build(boolean computeLayout) {
- final boolean needHyphenation = mBreakStrategy != Layout.BREAK_STRATEGY_SIMPLE
- && mHyphenationFrequency != Layout.HYPHENATION_FREQUENCY_NONE;
-
- final IntArray paragraphEnds = new IntArray();
- final ArrayList<MeasuredParagraph> measuredTexts = new ArrayList<>();
-
- int paraEnd = 0;
- for (int paraStart = mStart; paraStart < mEnd; paraStart = paraEnd) {
- paraEnd = TextUtils.indexOf(mText, LINE_FEED, paraStart, mEnd);
- if (paraEnd < 0) {
- // No LINE_FEED(U+000A) character found. Use end of the text as the paragraph
- // end.
- paraEnd = mEnd;
- } else {
- paraEnd++; // Includes LINE_FEED(U+000A) to the prev paragraph.
- }
-
- paragraphEnds.add(paraEnd);
- measuredTexts.add(MeasuredParagraph.buildForStaticLayout(
- mPaint, mText, paraStart, paraEnd, mTextDir, needHyphenation,
- computeLayout, null /* no recycle */));
- }
-
- return new MeasuredText(mText, mStart, mEnd, mPaint, mTextDir, mBreakStrategy,
- mHyphenationFrequency, measuredTexts.toArray(
- new MeasuredParagraph[measuredTexts.size()]),
- paragraphEnds.toArray());
- }
- };
-
- // Use MeasuredText.Builder instead.
- private MeasuredText(@NonNull CharSequence text,
- @IntRange(from = 0) int start,
- @IntRange(from = 0) int end,
- @NonNull TextPaint paint,
- @NonNull TextDirectionHeuristic textDir,
- @Layout.BreakStrategy int breakStrategy,
- @Layout.HyphenationFrequency int frequency,
- @NonNull MeasuredParagraph[] measuredTexts,
- @NonNull int[] paragraphBreakPoints) {
- mText = text;
- mStart = start;
- mEnd = end;
- // Copy the paint so that we can keep the reference of typeface in native layout result.
- mPaint = new TextPaint(paint);
- mMeasuredParagraphs = measuredTexts;
- mParagraphBreakPoints = paragraphBreakPoints;
- mTextDir = textDir;
- mBreakStrategy = breakStrategy;
- mHyphenationFrequency = frequency;
- }
-
- /**
- * Return the underlying text.
- */
- public @NonNull CharSequence getText() {
- return mText;
- }
-
- /**
- * Returns the inclusive start offset of measured region.
- */
- public @IntRange(from = 0) int getStart() {
- return mStart;
- }
-
- /**
- * Returns the exclusive end offset of measured region.
- */
- public @IntRange(from = 0) int getEnd() {
- return mEnd;
- }
-
- /**
- * Returns the text direction associated with char sequence.
- */
- public @NonNull TextDirectionHeuristic getTextDir() {
- return mTextDir;
- }
-
- /**
- * Returns the paint used to measure this text.
- */
- public @NonNull TextPaint getPaint() {
- return mPaint;
- }
-
- /**
- * Returns the length of the paragraph of this text.
- */
- public @IntRange(from = 0) int getParagraphCount() {
- return mParagraphBreakPoints.length;
- }
-
- /**
- * Returns the paragraph start offset of the text.
- */
- public @IntRange(from = 0) int getParagraphStart(@IntRange(from = 0) int paraIndex) {
- Preconditions.checkArgumentInRange(paraIndex, 0, getParagraphCount(), "paraIndex");
- return paraIndex == 0 ? mStart : mParagraphBreakPoints[paraIndex - 1];
- }
-
- /**
- * Returns the paragraph end offset of the text.
- */
- public @IntRange(from = 0) int getParagraphEnd(@IntRange(from = 0) int paraIndex) {
- Preconditions.checkArgumentInRange(paraIndex, 0, getParagraphCount(), "paraIndex");
- return mParagraphBreakPoints[paraIndex];
- }
-
- /** @hide */
- public @NonNull MeasuredParagraph getMeasuredParagraph(@IntRange(from = 0) int paraIndex) {
- return mMeasuredParagraphs[paraIndex];
- }
-
- /**
- * Returns the break strategy for this text.
- */
- public @Layout.BreakStrategy int getBreakStrategy() {
- return mBreakStrategy;
- }
-
- /**
- * Returns the hyphenation frequency for this text.
- */
- public @Layout.HyphenationFrequency int getHyphenationFrequency() {
- return mHyphenationFrequency;
- }
-
- /**
- * Returns true if the given TextPaint gives the same result of text layout for this text.
- * @hide
- */
- public boolean canUseMeasuredResult(@NonNull TextPaint paint) {
- return mPaint.getTextSize() == paint.getTextSize()
- && mPaint.getTextSkewX() == paint.getTextSkewX()
- && mPaint.getTextScaleX() == paint.getTextScaleX()
- && mPaint.getLetterSpacing() == paint.getLetterSpacing()
- && mPaint.getWordSpacing() == paint.getWordSpacing()
- && mPaint.getFlags() == paint.getFlags() // Maybe not all flag affects text layout.
- && mPaint.getTextLocales() == paint.getTextLocales() // need to be equals?
- && mPaint.getFontVariationSettings() == paint.getFontVariationSettings()
- && mPaint.getTypeface() == paint.getTypeface()
- && TextUtils.equals(mPaint.getFontFeatureSettings(), paint.getFontFeatureSettings());
- }
-
- /** @hide */
- public int findParaIndex(@IntRange(from = 0) int pos) {
- // TODO: Maybe good to remove paragraph concept from MeasuredText and add substring layout
- // support to StaticLayout.
- for (int i = 0; i < mParagraphBreakPoints.length; ++i) {
- if (pos < mParagraphBreakPoints[i]) {
- return i;
- }
- }
- throw new IndexOutOfBoundsException(
- "pos must be less than " + mParagraphBreakPoints[mParagraphBreakPoints.length - 1]
- + ", gave " + pos);
- }
-
- /** @hide */
- public float getWidth(@IntRange(from = 0) int start, @IntRange(from = 0) int end) {
- final int paraIndex = findParaIndex(start);
- final int paraStart = getParagraphStart(paraIndex);
- final int paraEnd = getParagraphEnd(paraIndex);
- if (start < paraStart || paraEnd < end) {
- throw new RuntimeException("Cannot measured across the paragraph:"
- + "para: (" + paraStart + ", " + paraEnd + "), "
- + "request: (" + start + ", " + end + ")");
- }
- 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
- //
- // Just proxy for underlying mText if appropriate.
-
- @Override
- public <T> T[] getSpans(int start, int end, Class<T> type) {
- if (mText instanceof Spanned) {
- return ((Spanned) mText).getSpans(start, end, type);
- } else {
- return ArrayUtils.emptyArray(type);
- }
- }
-
- @Override
- public int getSpanStart(Object tag) {
- if (mText instanceof Spanned) {
- return ((Spanned) mText).getSpanStart(tag);
- } else {
- return -1;
- }
- }
-
- @Override
- public int getSpanEnd(Object tag) {
- if (mText instanceof Spanned) {
- return ((Spanned) mText).getSpanEnd(tag);
- } else {
- return -1;
- }
- }
-
- @Override
- public int getSpanFlags(Object tag) {
- if (mText instanceof Spanned) {
- return ((Spanned) mText).getSpanFlags(tag);
- } else {
- return 0;
- }
- }
-
- @Override
- public int nextSpanTransition(int start, int limit, Class type) {
- if (mText instanceof Spanned) {
- return ((Spanned) mText).nextSpanTransition(start, limit, type);
- } else {
- return mText.length();
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////
- // CharSequence overrides.
- //
- // Just proxy for underlying mText.
-
- @Override
- public int length() {
- return mText.length();
- }
-
- @Override
- public char charAt(int index) {
- // TODO: Should this be index + mStart ?
- return mText.charAt(index);
- }
-
- @Override
- public CharSequence subSequence(int start, int end) {
- // TODO: return MeasuredText.
- // TODO: Should this be index + mStart, end + mStart ?
- return mText.subSequence(start, end);
- }
-
- @Override
- public String toString() {
- return mText.toString();
- }
-}
diff --git a/core/java/android/text/PrecomputedText.java b/core/java/android/text/PrecomputedText.java
new file mode 100644
index 0000000..39fc2bd
--- /dev/null
+++ b/core/java/android/text/PrecomputedText.java
@@ -0,0 +1,412 @@
+/*
+ * Copyright (C) 2017 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 android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.util.IntArray;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+
+/**
+ * A text which has the character metrics data
+ *
+ * This text holds a part of the text layout result. You can accelerate
+ * {@link android.widget.TextView} or {@link StaticLayout} by using this text.
+ *
+ * <pre>
+ * Example of background measurement.
+ * <code>
+ * void asyncSetText(final TextView textView, final String expensiveLongString, Handler handler) {
+ * final PrecomputedText.Params params = textView.getTextParams();
+ * handler.post(() -> {
+ * final PrecomputedText precomputedText
+ * = PrecomputedText.create(expensiveLongString, params);
+ * textView.post(() -> {
+ * textView.setPrecomputedTextOrThrow(precomputedText);
+ * });
+ * });
+ * }
+ * </code>
+ * </pre>
+ *
+ * Note that the {@link PrecomputedText} created from different parameters of the target
+ * {@link android.widget.TextView} will be rejected internally and compute the text layout again
+ * with the current {@link android.widget.TextView} parameters.
+ */
+public class PrecomputedText {
+ private static final char LINE_FEED = '\n';
+
+ /**
+ * The information required for building {@link PrecomputedText}.
+ *
+ * Contains information required for precomputing text measurement metadata, so it can be done
+ * in isolation of a {@link android.widget.TextView} or {@link StaticLayout}, when final layout
+ * constraints are not known.
+ */
+ public static class Params {
+ // The TextPaint used for measurement.
+ private final @NonNull TextPaint mPaint;
+
+ // The requested text direction.
+ private final @NonNull TextDirectionHeuristic mTextDir;
+
+ // The break strategy for this measured text.
+ private final @Layout.BreakStrategy int mBreakStrategy;
+
+ // The hyphenation frequency for this measured text.
+ private final @Layout.HyphenationFrequency int mHyphenationFrequency;
+
+ /**
+ * A builder for creating {@link Params}.
+ */
+ public static class Builder {
+ // The TextPaint used for measurement.
+ private final @NonNull TextPaint mPaint;
+
+ // The requested text direction.
+ private TextDirectionHeuristic mTextDir = TextDirectionHeuristics.FIRSTSTRONG_LTR;
+
+ // The break strategy for this measured text.
+ private @Layout.BreakStrategy int mBreakStrategy = Layout.BREAK_STRATEGY_HIGH_QUALITY;
+
+ // The hyphenation frequency for this measured text.
+ private @Layout.HyphenationFrequency int mHyphenationFrequency =
+ Layout.HYPHENATION_FREQUENCY_NORMAL;
+
+ /**
+ * Builder constructor
+ *
+ * @param paint The paint to be used for drawing
+ */
+ public Builder(@NonNull TextPaint paint) {
+ mPaint = paint;
+ }
+
+ /**
+ * Set the line break strategy
+ *
+ * The default value is {@link Layout#BREAK_STRATEGY_HIGH_QUALITY}.
+ *
+ * @param strategy The break strategy
+ * @return this builder, useful for chaining
+ */
+ public Builder setBreakStrategy(@Layout.BreakStrategy int strategy) {
+ mBreakStrategy = strategy;
+ return this;
+ }
+
+ /**
+ * Set the hyphenation frequency
+ *
+ * The default value is {@link Layout#HYPHENATION_FREQUENCY_NORMAL}.
+ *
+ * @param frequency The hyphenation frequency
+ * @return this builder, useful for chaining
+ */
+ public Builder setHyphenationFrequency(@Layout.HyphenationFrequency int frequency) {
+ mHyphenationFrequency = frequency;
+ return this;
+ }
+
+ /**
+ * Set the text direction heuristic
+ *
+ * The default value is {@link TextDirectionHeuristics#FIRSTSTRONG_LTR}.
+ *
+ * @param textDir The text direction heuristic for resolving bidi behavior
+ * @return this builder, useful for chaining
+ */
+ public Builder setTextDirection(@NonNull TextDirectionHeuristic textDir) {
+ mTextDir = textDir;
+ return this;
+ }
+
+ /**
+ * Build the {@link Params}
+ *
+ * @return the layout parameter
+ */
+ public @NonNull Params build() {
+ return new Params(mPaint, mTextDir, mBreakStrategy, mHyphenationFrequency);
+ }
+ }
+
+ // Use Builder instead.
+ /** @hide */
+ public Params(@NonNull TextPaint paint, @NonNull TextDirectionHeuristic textDir,
+ @Layout.BreakStrategy int strategy, @Layout.HyphenationFrequency int frequency) {
+ mPaint = paint;
+ mTextDir = textDir;
+ mBreakStrategy = strategy;
+ mHyphenationFrequency = frequency;
+ }
+
+ /**
+ * Returns the {@link TextPaint} for this text
+ *
+ * @return A {@link TextPaint}
+ */
+ public @NonNull TextPaint getTextPaint() {
+ return mPaint;
+ }
+
+ /**
+ * Returns the {@link TextDirectionHeuristic} for this text
+ *
+ * @return A {@link TextDirectionHeuristic}
+ */
+ public @NonNull TextDirectionHeuristic getTextDirection() {
+ return mTextDir;
+ }
+
+ /**
+ * Returns the break strategy for this text
+ *
+ * @return A line break strategy
+ */
+ public @Layout.BreakStrategy int getBreakStrategy() {
+ return mBreakStrategy;
+ }
+
+ /**
+ * Returns the hyphenation frequency for this text
+ *
+ * @return A hyphenation frequency
+ */
+ public @Layout.HyphenationFrequency int getHyphenationFrequency() {
+ return mHyphenationFrequency;
+ }
+
+ private boolean sameTextMetricsInternal(@NonNull TextPaint paint,
+ @NonNull TextDirectionHeuristic textDir, @Layout.BreakStrategy int strategy,
+ @Layout.HyphenationFrequency int frequency) {
+ return mTextDir == textDir
+ && mBreakStrategy == strategy
+ && mHyphenationFrequency == frequency
+ && mPaint.equalsForTextMeasurement(paint);
+ }
+
+ /**
+ * Check if the same text layout.
+ *
+ * @return true if this and the given param result in the same text layout
+ */
+ public boolean sameTextMetrics(@NonNull Params param) {
+ return sameTextMetricsInternal(param.mPaint, param.mTextDir, param.mBreakStrategy,
+ param.mHyphenationFrequency);
+ }
+ };
+
+ // The original text.
+ private final @NonNull CharSequence mText;
+
+ // The inclusive start offset of the measuring target.
+ private final @IntRange(from = 0) int mStart;
+
+ // The exclusive end offset of the measuring target.
+ private final @IntRange(from = 0) int mEnd;
+
+ private final @NonNull Params mParams;
+
+ // The measured paragraph texts.
+ private final @NonNull MeasuredParagraph[] mMeasuredParagraphs;
+
+ // The sorted paragraph end offsets.
+ private final @NonNull int[] mParagraphBreakPoints;
+
+ /**
+ * Create a new {@link PrecomputedText} which will pre-compute text measurement and glyph
+ * positioning information.
+ * <p>
+ * This can be expensive, so computing this on a background thread before your text will be
+ * presented can save work on the UI thread.
+ * </p>
+ *
+ * @param text The text to be measured
+ * @param param Parameters that define how text will be precomputed
+ * @return A {@link PrecomputedText}
+ */
+ public static PrecomputedText create(@NonNull CharSequence text, @NonNull Params param) {
+ return createInternal(text, param, 0, text.length(), true /* compute full Layout */);
+ }
+
+
+ /** @hide */
+ public static PrecomputedText createWidthOnly(@NonNull CharSequence text, @NonNull Params param,
+ @IntRange(from = 0) int start, @IntRange(from = 0) int end) {
+ return createInternal(text, param, start, end, false /* compute width only */);
+ }
+
+ private static PrecomputedText createInternal(@NonNull CharSequence text, @NonNull Params param,
+ @IntRange(from = 0) int start, @IntRange(from = 0) int end, boolean computeLayout) {
+ Preconditions.checkNotNull(text);
+ Preconditions.checkNotNull(param);
+ final boolean needHyphenation = param.getBreakStrategy() != Layout.BREAK_STRATEGY_SIMPLE
+ && param.getHyphenationFrequency() != Layout.HYPHENATION_FREQUENCY_NONE;
+
+ final IntArray paragraphEnds = new IntArray();
+ final ArrayList<MeasuredParagraph> measuredTexts = new ArrayList<>();
+
+ int paraEnd = 0;
+ for (int paraStart = start; paraStart < end; paraStart = paraEnd) {
+ paraEnd = TextUtils.indexOf(text, LINE_FEED, paraStart, end);
+ if (paraEnd < 0) {
+ // No LINE_FEED(U+000A) character found. Use end of the text as the paragraph
+ // end.
+ paraEnd = end;
+ } else {
+ paraEnd++; // Includes LINE_FEED(U+000A) to the prev paragraph.
+ }
+
+ paragraphEnds.add(paraEnd);
+ measuredTexts.add(MeasuredParagraph.buildForStaticLayout(
+ param.getTextPaint(), text, paraStart, paraEnd, param.getTextDirection(),
+ needHyphenation, computeLayout, null /* no recycle */));
+ }
+
+ return new PrecomputedText(text, start, end, param,
+ measuredTexts.toArray(new MeasuredParagraph[measuredTexts.size()]),
+ paragraphEnds.toArray());
+ }
+
+ // Use PrecomputedText.create instead.
+ private PrecomputedText(@NonNull CharSequence text, @IntRange(from = 0) int start,
+ @IntRange(from = 0) int end, @NonNull Params param,
+ @NonNull MeasuredParagraph[] measuredTexts, @NonNull int[] paragraphBreakPoints) {
+ mText = TextUtils.stringOrSpannedString(text);
+ mStart = start;
+ mEnd = end;
+ mParams = param;
+ mMeasuredParagraphs = measuredTexts;
+ mParagraphBreakPoints = paragraphBreakPoints;
+ }
+
+ /**
+ * Return the underlying text.
+ */
+ public @NonNull CharSequence getText() {
+ return mText;
+ }
+
+ /**
+ * Returns the inclusive start offset of measured region.
+ * @hide
+ */
+ public @IntRange(from = 0) int getStart() {
+ return mStart;
+ }
+
+ /**
+ * Returns the exclusive end offset of measured region.
+ * @hide
+ */
+ public @IntRange(from = 0) int getEnd() {
+ return mEnd;
+ }
+
+ /**
+ * Returns the layout parameters used to measure this text.
+ */
+ public @NonNull Params getParams() {
+ return mParams;
+ }
+
+ /**
+ * Returns the length of the paragraph of this text.
+ */
+ public @IntRange(from = 0) int getParagraphCount() {
+ return mParagraphBreakPoints.length;
+ }
+
+ /**
+ * Returns the paragraph start offset of the text.
+ */
+ public @IntRange(from = 0) int getParagraphStart(@IntRange(from = 0) int paraIndex) {
+ Preconditions.checkArgumentInRange(paraIndex, 0, getParagraphCount(), "paraIndex");
+ return paraIndex == 0 ? mStart : mParagraphBreakPoints[paraIndex - 1];
+ }
+
+ /**
+ * Returns the paragraph end offset of the text.
+ */
+ public @IntRange(from = 0) int getParagraphEnd(@IntRange(from = 0) int paraIndex) {
+ Preconditions.checkArgumentInRange(paraIndex, 0, getParagraphCount(), "paraIndex");
+ return mParagraphBreakPoints[paraIndex];
+ }
+
+ /** @hide */
+ public @NonNull MeasuredParagraph getMeasuredParagraph(@IntRange(from = 0) int paraIndex) {
+ return mMeasuredParagraphs[paraIndex];
+ }
+
+ /**
+ * Returns true if the given TextPaint gives the same result of text layout for this text.
+ * @hide
+ */
+ public boolean canUseMeasuredResult(@IntRange(from = 0) int start, @IntRange(from = 0) int end,
+ @NonNull TextDirectionHeuristic textDir, @NonNull TextPaint paint,
+ @Layout.BreakStrategy int strategy, @Layout.HyphenationFrequency int frequency) {
+ final TextPaint mtPaint = mParams.getTextPaint();
+ return mStart == start
+ && mEnd == end
+ && mParams.sameTextMetricsInternal(paint, textDir, strategy, frequency);
+ }
+
+ /** @hide */
+ public int findParaIndex(@IntRange(from = 0) int pos) {
+ // TODO: Maybe good to remove paragraph concept from PrecomputedText and add substring
+ // layout support to StaticLayout.
+ for (int i = 0; i < mParagraphBreakPoints.length; ++i) {
+ if (pos < mParagraphBreakPoints[i]) {
+ return i;
+ }
+ }
+ throw new IndexOutOfBoundsException(
+ "pos must be less than " + mParagraphBreakPoints[mParagraphBreakPoints.length - 1]
+ + ", gave " + pos);
+ }
+
+ /** @hide */
+ public float getWidth(@IntRange(from = 0) int start, @IntRange(from = 0) int end) {
+ final int paraIndex = findParaIndex(start);
+ final int paraStart = getParagraphStart(paraIndex);
+ final int paraEnd = getParagraphEnd(paraIndex);
+ if (start < paraStart || paraEnd < end) {
+ throw new RuntimeException("Cannot measured across the paragraph:"
+ + "para: (" + paraStart + ", " + paraEnd + "), "
+ + "request: (" + start + ", " + end + ")");
+ }
+ return getMeasuredParagraph(paraIndex).getWidth(start - paraStart, end - paraStart);
+ }
+
+ /**
+ * Returns the size of native PrecomputedText memory usage
+ *
+ * Note that this is not guaranteed to be accurate. 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;
+ }
+}
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index e62f421..5869802 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -78,6 +78,23 @@
/**
* Obtain a builder for constructing StaticLayout objects.
*
+ * @param source The precomputed text.
+ * @param start The index of the start of the text
+ * @param end The index + 1 of the end of the text
+ * @param paint The base paint used for layout
+ * @param width The width in pixels
+ * @return a builder object used for constructing the StaticLayout
+ */
+ @NonNull
+ public static Builder obtain(@NonNull PrecomputedText source, @IntRange(from = 0) int start,
+ @IntRange(from = 0) int end, @NonNull TextPaint paint,
+ @IntRange(from = 0) int width) {
+ return obtain(source.getText(), source, start, end, paint, width);
+ }
+
+ /**
+ * Obtain a builder for constructing StaticLayout objects.
+ *
* @param source The text to be laid out, optionally with spans
* @param start The index of the start of the text
* @param end The index + 1 of the end of the text
@@ -89,6 +106,12 @@
public static Builder obtain(@NonNull CharSequence source, @IntRange(from = 0) int start,
@IntRange(from = 0) int end, @NonNull TextPaint paint,
@IntRange(from = 0) int width) {
+ return obtain(source, null, start, end, paint, width);
+ }
+
+ private static Builder obtain(@NonNull CharSequence source, @Nullable PrecomputedText text,
+ @IntRange(from = 0) int start, @IntRange(from = 0) int end,
+ @NonNull TextPaint paint, @IntRange(from = 0) int width) {
Builder b = sPool.acquire();
if (b == null) {
b = new Builder();
@@ -96,6 +119,7 @@
// set default initial values
b.mText = source;
+ b.mPrecomputed = text;
b.mStart = start;
b.mEnd = end;
b.mPaint = paint;
@@ -428,6 +452,7 @@
}
private CharSequence mText;
+ private PrecomputedText mPrecomputed;
private int mStart;
private int mEnd;
private TextPaint mPaint;
@@ -490,7 +515,7 @@
float spacingmult, float spacingadd,
boolean includepad,
TextUtils.TruncateAt ellipsize, int ellipsizedWidth) {
- this(source, bufstart, bufend, paint, outerwidth, align,
+ this(source, null /* precomputed */, bufstart, bufend, paint, outerwidth, align,
TextDirectionHeuristics.FIRSTSTRONG_LTR,
spacingmult, spacingadd, includepad, ellipsize, ellipsizedWidth, Integer.MAX_VALUE);
}
@@ -500,7 +525,16 @@
* @deprecated Use {@link Builder} instead.
*/
@Deprecated
- public StaticLayout(CharSequence source, int bufstart, int bufend,
+ public StaticLayout(CharSequence source, int bufstart, int bufend, TextPaint paint,
+ int outerwidth, Alignment align, TextDirectionHeuristic textDir,
+ float spacingmult, float spacingadd, boolean includepad,
+ TextUtils.TruncateAt ellipsize, int ellipsizedWidth, int maxLines) {
+ this(source, null /* precomputed */, bufstart, bufend, paint, outerwidth, align, textDir,
+ spacingmult, spacingadd, includepad, ellipsize, ellipsizedWidth, maxLines);
+ }
+
+ /** @hide */
+ public StaticLayout(CharSequence source, PrecomputedText precomputed, int bufstart, int bufend,
TextPaint paint, int outerwidth,
Alignment align, TextDirectionHeuristic textDir,
float spacingmult, float spacingadd,
@@ -511,6 +545,7 @@
: (source instanceof Spanned)
? new SpannedEllipsizer(source)
: new Ellipsizer(source),
+ (ellipsize == null) ? precomputed : null,
paint, outerwidth, align, textDir, spacingmult, spacingadd);
Builder b = Builder.obtain(source, bufstart, bufend, paint, outerwidth)
@@ -651,43 +686,20 @@
b.mJustificationMode != Layout.JUSTIFICATION_MODE_NONE,
indents, mLeftPaddings, mRightPaddings);
- MeasuredText measured = null;
- final Spanned spanned;
- final boolean canUseMeasuredText;
- if (source instanceof MeasuredText) {
- measured = (MeasuredText) source;
-
- if (bufStart != measured.getStart() || bufEnd != measured.getEnd()) {
- // The buffer position has changed. Re-measure here.
- canUseMeasuredText = false;
- } else if (b.mBreakStrategy != measured.getBreakStrategy()
- || b.mHyphenationFrequency != measured.getHyphenationFrequency()) {
- // The computed hyphenation pieces may not be able to used. Re-measure it.
- canUseMeasuredText = false;
- } else {
- // We can use measured information.
- canUseMeasuredText = true;
+ PrecomputedText measured = null;
+ final Spanned spanned = (b.mText instanceof Spanned) ? (Spanned) b.mText : null;
+ if (b.mPrecomputed != null) {
+ if (b.mPrecomputed.canUseMeasuredResult(bufStart, bufEnd, textDir, paint,
+ b.mBreakStrategy, b.mHyphenationFrequency)) {
+ measured = b.mPrecomputed;
}
- } else {
- canUseMeasuredText = false;
+ }
+ if (measured == null) {
+ final PrecomputedText.Params param = new PrecomputedText.Params(paint, textDir,
+ b.mBreakStrategy, b.mHyphenationFrequency);
+ measured = PrecomputedText.createWidthOnly(source, param, bufStart, bufEnd);
}
- if (!canUseMeasuredText) {
- measured = new MeasuredText.Builder(source, paint)
- .setRange(bufStart, bufEnd)
- .setTextDirection(textDir)
- .setBreakStrategy(b.mBreakStrategy)
- .setHyphenationFrequency(b.mHyphenationFrequency)
- .build(false /* full layout is not necessary for line breaking */);
- spanned = (source instanceof Spanned) ? (Spanned) source : null;
- } else {
- final CharSequence original = measured.getText();
- spanned = (original instanceof Spanned) ? (Spanned) original : null;
- // Overwrite with the one when measured.
- // TODO: Give an option for developer not to overwrite and measure again here?
- textDir = measured.getTextDir();
- paint = measured.getPaint();
- }
try {
for (int paraIndex = 0; paraIndex < measured.getParagraphCount(); paraIndex++) {
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 55367dc..be5bb4d 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -16,6 +16,7 @@
package android.text;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Canvas;
@@ -60,7 +61,7 @@
private char[] mChars;
private boolean mCharsValid;
private Spanned mSpanned;
- private MeasuredText mMeasured;
+ private PrecomputedText mComputed;
// Additional width of whitespace for justification. This value is per whitespace, thus
// the line width will increase by mAddedWidth x (number of stretchable whitespaces).
@@ -119,7 +120,7 @@
tl.mSpanned = null;
tl.mTabs = null;
tl.mChars = null;
- tl.mMeasured = null;
+ tl.mComputed = null;
tl.mMetricAffectingSpanSpanSet.recycle();
tl.mCharacterStyleSpanSet.recycle();
@@ -149,10 +150,31 @@
* @param tabStops the tabStops. Can be null.
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public void set(TextPaint paint, CharSequence text, int start, int limit, int dir,
- Directions directions, boolean hasTabs, TabStops tabStops) {
+ public void set(TextPaint paint, CharSequence text, int start,
+ int limit, int dir, Directions directions, boolean hasTabs, TabStops tabStops) {
+ set(paint, text, null, start, limit, dir, directions, hasTabs, tabStops);
+ }
+
+ /**
+ * Initializes a TextLine and prepares it for use.
+ *
+ * @param paint the base paint for the line
+ * @param text the text, can be Styled
+ * @param precomputed the precomputed text
+ * @param start the start of the line relative to the text
+ * @param limit the limit of the line relative to the text
+ * @param dir the paragraph direction of this line
+ * @param directions the directions information of this line
+ * @param hasTabs true if the line might contain tabs
+ * @param tabStops the tabStops.
+ */
+ public void set(@NonNull TextPaint paint, @NonNull CharSequence text,
+ @Nullable PrecomputedText precomputed, @IntRange(from = 0) int start,
+ @IntRange(from = 0) int limit, int dir, @NonNull Directions directions, boolean hasTabs,
+ @Nullable TabStops tabStops) {
mPaint = paint;
mText = text;
+ mComputed = precomputed;
mStart = start;
mLen = limit - start;
mDir = dir;
@@ -170,14 +192,6 @@
hasReplacement = mReplacementSpanSpanSet.numberOfSpans > 0;
}
- mMeasured = null;
- if (text instanceof MeasuredText) {
- MeasuredText mt = (MeasuredText) text;
- if (mt.canUseMeasuredResult(paint)) {
- mMeasured = mt;
- }
- }
-
mCharsValid = hasReplacement || hasTabs || directions != Layout.DIRS_ALL_LEFT_TO_RIGHT;
if (mCharsValid) {
@@ -746,12 +760,12 @@
return wp.getRunAdvance(mChars, start, end, contextStart, contextEnd, runIsRtl, offset);
} else {
final int delta = mStart;
- if (mMeasured == null) {
+ if (mComputed == null) {
// TODO: Enable measured getRunAdvance for ReplacementSpan and RTL text.
return wp.getRunAdvance(mText, delta + start, delta + end,
delta + contextStart, delta + contextEnd, runIsRtl, delta + offset);
} else {
- return mMeasured.getWidth(start + delta, end + delta);
+ return mComputed.getWidth(start + delta, end + delta);
}
}
}
diff --git a/core/java/android/transition/TransitionUtils.java b/core/java/android/transition/TransitionUtils.java
index 60b77bc..46c9e0c 100644
--- a/core/java/android/transition/TransitionUtils.java
+++ b/core/java/android/transition/TransitionUtils.java
@@ -20,14 +20,13 @@
import android.animation.AnimatorSet;
import android.animation.TypeEvaluator;
import android.graphics.Bitmap;
+import android.graphics.Canvas;
import android.graphics.Matrix;
+import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
-import android.view.ThreadedRenderer;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
@@ -128,10 +127,8 @@
}
int bitmapWidth = (int) (width * scale);
int bitmapHeight = (int) (height * scale);
- final RenderNode node = RenderNode.create("TransitionUtils", hostView);
- node.setLeftTopRightBottom(0, 0, width, height);
- node.setClipToBounds(false);
- final DisplayListCanvas canvas = node.start(width, height);
+ final Picture picture = new Picture();
+ final Canvas canvas = picture.beginRecording(width, height);
// Do stuff with the canvas
Rect existingBounds = drawable.getBounds();
int left = existingBounds.left;
@@ -141,8 +138,8 @@
drawable.setBounds(0, 0, bitmapWidth, bitmapHeight);
drawable.draw(canvas);
drawable.setBounds(left, top, right, bottom);
- node.end(canvas);
- return ThreadedRenderer.createHardwareBitmap(node, width, height);
+ picture.endRecording();
+ return Bitmap.createBitmap(picture);
}
/**
@@ -183,14 +180,12 @@
matrix.postTranslate(-bounds.left, -bounds.top);
matrix.postScale(scale, scale);
- final RenderNode node = RenderNode.create("TransitionUtils", view);
- node.setLeftTopRightBottom(0, 0, bitmapWidth, bitmapHeight);
- node.setClipToBounds(false);
- final DisplayListCanvas canvas = node.start(bitmapWidth, bitmapHeight);
+ final Picture picture = new Picture();
+ final Canvas canvas = picture.beginRecording(bitmapWidth, bitmapHeight);
canvas.concat(matrix);
view.draw(canvas);
- node.end(canvas);
- bitmap = ThreadedRenderer.createHardwareBitmap(node, bitmapWidth, bitmapHeight);
+ picture.endRecording();
+ bitmap = Bitmap.createBitmap(picture);
}
if (addToOverlay) {
sceneRoot.getOverlay().remove(view);
diff --git a/core/java/android/util/MemoryIntArray.java b/core/java/android/util/MemoryIntArray.java
index 5970892..bf33519 100644
--- a/core/java/android/util/MemoryIntArray.java
+++ b/core/java/android/util/MemoryIntArray.java
@@ -16,18 +16,12 @@
package android.util;
-import static android.os.Process.FIRST_APPLICATION_UID;
-
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
-import android.os.Process;
-
-import com.android.internal.annotations.GuardedBy;
-
-import dalvik.system.CloseGuard;
import libcore.io.IoUtils;
+import dalvik.system.CloseGuard;
import java.io.Closeable;
import java.io.IOException;
@@ -55,18 +49,13 @@
*/
public final class MemoryIntArray implements Parcelable, Closeable {
private static final String TAG = "MemoryIntArray";
- private static final boolean DEBUG = Process.myUid() < FIRST_APPLICATION_UID;
private static final int MAX_SIZE = 1024;
- private final Object mLock = new Object();
private final CloseGuard mCloseGuard = CloseGuard.get();
private final boolean mIsOwner;
private final long mMemoryAddr;
-
- /** Fd for the shared memory object, -1 when closed */
- @GuardedBy("mLock")
private int mFd = -1;
/**
@@ -85,7 +74,6 @@
mFd = nativeCreate(name, size);
mMemoryAddr = nativeOpen(mFd, mIsOwner);
mCloseGuard.open("close");
- if (DEBUG) Log.i(TAG, "created " + getString());
}
private MemoryIntArray(Parcel parcel) throws IOException {
@@ -97,8 +85,6 @@
mFd = pfd.detachFd();
mMemoryAddr = nativeOpen(mFd, mIsOwner);
mCloseGuard.open("close");
-
- if (DEBUG) Log.i(TAG, "created from parcel " + getString());
}
/**
@@ -155,33 +141,13 @@
*/
@Override
public void close() throws IOException {
- synchronized (mLock) {
- if (!isClosed()) {
- if (DEBUG) {
- try {
- throw new Exception();
- } catch (Exception here) {
- Log.i(TAG, "closing " + getString(), here);
- }
- }
- nativeClose(mFd, mMemoryAddr, mIsOwner);
- mFd = -1;
- mCloseGuard.close();
- } else {
- try {
- throw new Exception();
- } catch (Exception here) {
- if (DEBUG) Log.i(TAG, getString() + " already closed", here);
- }
- }
+ if (!isClosed()) {
+ nativeClose(mFd, mMemoryAddr, mIsOwner);
+ mFd = -1;
+ mCloseGuard.close();
}
}
- private String getString() {
- return this.getClass().getSimpleName() + "@" + System.identityHashCode(this)
- + " mMemoryAddr=" + mMemoryAddr + " mFd=" + mFd;
- }
-
/**
* @return Whether this array is closed and shouldn't be used.
*/
@@ -196,9 +162,7 @@
mCloseGuard.warnIfOpen();
}
- if (!isClosed()) {
- IoUtils.closeQuietly(this);
- }
+ IoUtils.closeQuietly(this);
} finally {
super.finalize();
}
@@ -242,8 +206,7 @@
private void enforceNotClosed() {
if (isClosed()) {
- throw new IllegalStateException("cannot interact with a closed instance "
- + getString());
+ throw new IllegalStateException("cannot interact with a closed instance");
}
}
diff --git a/core/java/android/view/RecordingCanvas.java b/core/java/android/view/RecordingCanvas.java
index fbb862b..fc7d828 100644
--- a/core/java/android/view/RecordingCanvas.java
+++ b/core/java/android/view/RecordingCanvas.java
@@ -34,7 +34,7 @@
import android.graphics.RectF;
import android.graphics.TemporaryBuffer;
import android.text.GraphicsOperations;
-import android.text.MeasuredText;
+import android.text.PrecomputedText;
import android.text.SpannableString;
import android.text.SpannedString;
import android.text.TextUtils;
@@ -507,8 +507,8 @@
TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
long measuredTextPtr = 0;
int measuredTextOffset = 0;
- if (text instanceof MeasuredText) {
- MeasuredText mt = (MeasuredText) text;
+ if (text instanceof PrecomputedText) {
+ PrecomputedText mt = (PrecomputedText) text;
int paraIndex = mt.findParaIndex(start);
if (end <= mt.getParagraphEnd(paraIndex)) {
// Only support if the target is in the same paragraph.
@@ -641,7 +641,7 @@
@FastNative
private static native void nDrawTextRun(long nativeCanvas, char[] text, int start, int count,
int contextStart, int contextCount, float x, float y, boolean isRtl, long nativePaint,
- long nativeMeasuredText, int measuredTextOffset);
+ long nativePrecomputedText, int measuredTextOffset);
@FastNative
private static native void nDrawTextOnPath(long nativeCanvas, char[] text, int index, int count,
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index cf26b2b..2af2467 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -7308,6 +7308,10 @@
return mAccessibilityPaneTitle;
}
+ private boolean isAccessibilityPane() {
+ return !TextUtils.isEmpty(mAccessibilityPaneTitle);
+ }
+
/**
* Sends an accessibility event of the given type. If accessibility is
* not enabled this method has no effect. The default implementation calls
@@ -8367,6 +8371,11 @@
}
}
+ // If the app developer explicitly set hints for it, it's important.
+ if (getAutofillHints() != null) {
+ return true;
+ }
+
// Otherwise, assume it's not important...
return false;
}
@@ -11632,7 +11641,7 @@
return mode == IMPORTANT_FOR_ACCESSIBILITY_YES || isActionableForAccessibility()
|| hasListenersForAccessibility() || getAccessibilityNodeProvider() != null
|| getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE
- || (mAccessibilityPaneTitle != null);
+ || isAccessibilityPane();
}
/**
@@ -11729,18 +11738,26 @@
// Changes to views with a pane title count as window state changes, as the pane title
// marks them as significant parts of the UI.
- if (!TextUtils.isEmpty(getAccessibilityPaneTitle())) {
- final AccessibilityEvent event = AccessibilityEvent.obtain();
- event.setEventType(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
- event.setContentChangeTypes(changeType);
- onPopulateAccessibilityEvent(event);
- if (mParent != null) {
- try {
- mParent.requestSendAccessibilityEvent(this, event);
- } catch (AbstractMethodError e) {
- Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName()
- + " does not fully implement ViewParent", e);
+ if ((changeType != AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE)
+ && isAccessibilityPane()) {
+ // If the pane isn't visible, content changed events are sufficient unless we're
+ // reporting that the view just disappeared
+ if ((getVisibility() == VISIBLE)
+ || (changeType == AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_DISAPPEARED)) {
+ final AccessibilityEvent event = AccessibilityEvent.obtain();
+ event.setEventType(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+ event.setContentChangeTypes(changeType);
+ event.setSource(this);
+ onPopulateAccessibilityEvent(event);
+ if (mParent != null) {
+ try {
+ mParent.requestSendAccessibilityEvent(this, event);
+ } catch (AbstractMethodError e) {
+ Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName()
+ + " does not fully implement ViewParent", e);
+ }
}
+ return;
}
}
@@ -14030,6 +14047,11 @@
}
if (accessibilityEnabled) {
+ // If we're an accessibility pane and the visibility changed, we already have sent
+ // a state change, so we really don't need to report other changes.
+ if (isAccessibilityPane()) {
+ changed &= ~VISIBILITY_MASK;
+ }
if ((changed & FOCUSABLE) != 0 || (changed & VISIBILITY_MASK) != 0
|| (changed & CLICKABLE) != 0 || (changed & LONG_CLICKABLE) != 0
|| (changed & CONTEXT_CLICKABLE) != 0) {
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index b09934e..276f50a 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -21,7 +21,7 @@
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
-import android.graphics.Point;
+import android.graphics.Picture;
import android.graphics.Rect;
import android.os.Debug;
import android.os.Handler;
@@ -1782,27 +1782,18 @@
* @hide
*/
public static class HardwareCanvasProvider implements CanvasProvider {
-
- private View mView;
- private Point mSize;
- private RenderNode mNode;
- private DisplayListCanvas mCanvas;
+ private Picture mPicture;
@Override
public Canvas getCanvas(View view, int width, int height) {
- mView = view;
- mSize = new Point(width, height);
- mNode = RenderNode.create("ViewDebug", mView);
- mNode.setLeftTopRightBottom(0, 0, width, height);
- mNode.setClipToBounds(false);
- mCanvas = mNode.start(width, height);
- return mCanvas;
+ mPicture = new Picture();
+ return mPicture.beginRecording(width, height);
}
@Override
public Bitmap createBitmap() {
- mNode.end(mCanvas);
- return ThreadedRenderer.createHardwareBitmap(mNode, mSize.x, mSize.y);
+ mPicture.endRecording();
+ return Bitmap.createBitmap(mPicture);
}
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 5710db3..f6e771a 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -80,8 +80,8 @@
import android.text.InputFilter;
import android.text.InputType;
import android.text.Layout;
-import android.text.MeasuredText;
import android.text.ParcelableSpan;
+import android.text.PrecomputedText;
import android.text.Selection;
import android.text.SpanWatcher;
import android.text.Spannable;
@@ -637,6 +637,7 @@
private CharSequence mText;
private CharSequence mTransformed;
private BufferType mBufferType = BufferType.NORMAL;
+ private PrecomputedText mPrecomputed;
private CharSequence mHint;
private Layout mHintLayout;
@@ -4085,6 +4086,80 @@
}
/**
+ * Gets the parameters for text layout precomputation, for use with {@link PrecomputedText}
+ *
+ * @return A current {@link PrecomputedText.Params}
+ */
+ public @NonNull PrecomputedText.Params getTextMetricsParams() {
+ return new PrecomputedText.Params(new TextPaint(mTextPaint), getTextDirectionHeuristic(),
+ mBreakStrategy, mHyphenationFrequency);
+ }
+
+ /**
+ * Apply the text layout parameter.
+ */
+ public void setTextMetricsParams(@NonNull PrecomputedText.Params params) {
+ mTextPaint.set(params.getTextPaint());
+ mTextDir = params.getTextDirection();
+ mBreakStrategy = params.getBreakStrategy();
+ mHyphenationFrequency = params.getHyphenationFrequency();
+ if (mLayout != null) {
+ nullLayouts();
+ requestLayout();
+ invalidate();
+ }
+ }
+
+ /**
+ * Sets the precomputed text.
+ *
+ * If the parameters for the precomputed text is different from current text view parameters,
+ * apply the parameteres to the text view too.
+ *
+ * @param text A precomputed text.
+ */
+ public void setPrecomputedTextAndParams(@NonNull PrecomputedText text) {
+ Preconditions.checkNotNull(text);
+ final PrecomputedText.Params params = text.getParams();
+ if (!params.sameTextMetrics(getTextMetricsParams())) {
+ setTextMetricsParams(params);
+ }
+ setText(text.getText());
+ if (mTransformed != text.getText()) {
+ // setText modified given text for some reasons, selection, transformation, etc.
+ // Can't use computed result.
+ return;
+ } else {
+ mPrecomputed = text;
+ }
+ }
+
+ /**
+ * Sets the precomputed text.
+ *
+ * If the parameters for the precomputed text is different from current text view parameters,
+ * throws {@link IllegalArgumentException}.
+ *
+ * @param text A precomputed text.
+ */
+ public void setPrecomputedTextOrThrow(@NonNull PrecomputedText text) {
+ Preconditions.checkNotNull(text);
+ final PrecomputedText.Params params = text.getParams();
+ if (!params.sameTextMetrics(getTextMetricsParams())) {
+ throw new IllegalArgumentException(
+ "The precomputed configuration is different from this TextView.");
+ }
+ setText(text.getText());
+ if (mTransformed != text.getText()) {
+ // setText modified given text for some reasons, selection, transformation, etc.
+ // Can't use computed result.
+ // TODO: Do we throw an exception here too?
+ } else {
+ mPrecomputed = text;
+ }
+ }
+
+ /**
* Set justification mode. The default value is {@link Layout#JUSTIFICATION_MODE_NONE}. If the
* last line is too short for justification, the last line will be displayed with the
* alignment set by {@link android.view.View#setTextAlignment}.
@@ -5519,6 +5594,7 @@
private void setText(CharSequence text, BufferType type,
boolean notifyBefore, int oldlen) {
+ mPrecomputed = null;
mTextSetFromXmlOrResourceId = false;
if (text == null) {
text = "";
@@ -5577,7 +5653,7 @@
if (imm != null) imm.restartInput(this);
} else if (type == BufferType.SPANNABLE || mMovement != null) {
text = mSpannableFactory.newSpannable(text);
- } else if (!(text instanceof MeasuredText || text instanceof CharWrapper)) {
+ } else if (!(text instanceof CharWrapper)) {
text = TextUtils.stringOrSpannedString(text);
}
@@ -8244,7 +8320,8 @@
result = builder.build();
} else {
if (boring == UNKNOWN_BORING) {
- boring = BoringLayout.isBoring(mTransformed, mTextPaint, mTextDir, mBoring);
+ boring = BoringLayout.isBoring(mTransformed, mPrecomputed, mTextPaint, mTextDir,
+ mBoring);
if (boring != null) {
mBoring = boring;
}
@@ -8282,9 +8359,15 @@
}
}
if (result == null) {
- StaticLayout.Builder builder = StaticLayout.Builder.obtain(mTransformed,
- 0, mTransformed.length(), mTextPaint, wantWidth)
- .setAlignment(alignment)
+ StaticLayout.Builder builder;
+ if (mPrecomputed != null) {
+ builder = StaticLayout.Builder.obtain(mPrecomputed, 0,
+ mPrecomputed.getText().length(), mTextPaint, wantWidth);
+ } else {
+ builder = StaticLayout.Builder.obtain(mTransformed, 0, mTransformed.length(),
+ mTextPaint, wantWidth);
+ }
+ builder.setAlignment(alignment)
.setTextDirection(mTextDir)
.setLineSpacing(mSpacingAdd, mSpacingMult)
.setIncludePad(mIncludePad)
@@ -8411,7 +8494,8 @@
}
if (des < 0) {
- boring = BoringLayout.isBoring(mTransformed, mTextPaint, mTextDir, mBoring);
+ boring = BoringLayout.isBoring(mTransformed, mPrecomputed, mTextPaint, mTextDir,
+ mBoring);
if (boring != null) {
mBoring = boring;
}
@@ -11696,6 +11780,9 @@
}
/**
+ * Returns the current {@link TextDirectionHeuristic}
+ *
+ * @return A {@link TextDirectionHeuristic}.
* @hide
*/
protected TextDirectionHeuristic getTextDirectionHeuristic() {
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 66475e4..895be08 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -71,10 +71,11 @@
public void uncaughtException(Thread t, Throwable e) {
// Don't re-enter if KillApplicationHandler has already run
if (mCrashing) return;
- if (mApplicationObject == null) {
- // The "FATAL EXCEPTION" string is still used on Android even though
- // apps can set a custom UncaughtExceptionHandler that renders uncaught
- // exceptions non-fatal.
+
+ // mApplicationObject is null for non-zygote java programs (e.g. "am")
+ // There are also apps running with the system UID. We don't want the
+ // first clause in either of these two cases, only for system_server.
+ if (mApplicationObject == null && (Process.SYSTEM_UID == Process.myUid())) {
Clog_e(TAG, "*** FATAL EXCEPTION IN SYSTEM PROCESS: " + t.getName(), e);
} else {
StringBuilder message = new StringBuilder();
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 482d028..2c05d0b 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -1008,6 +1008,23 @@
return paint->getLooper() && paint->getLooper()->asABlurShadow(nullptr);
}
+ static jboolean equalsForTextMeasurement(jlong lPaint, jlong rPaint) {
+ if (lPaint == rPaint) {
+ return true;
+ }
+ Paint* leftPaint = reinterpret_cast<Paint*>(lPaint);
+ Paint* rightPaint = reinterpret_cast<Paint*>(rPaint);
+
+ const Typeface* leftTypeface = Typeface::resolveDefault(leftPaint->getAndroidTypeface());
+ const Typeface* rightTypeface = Typeface::resolveDefault(rightPaint->getAndroidTypeface());
+ minikin::MinikinPaint leftMinikinPaint
+ = MinikinUtils::prepareMinikinPaint(leftPaint, leftTypeface);
+ minikin::MinikinPaint rightMinikinPaint
+ = MinikinUtils::prepareMinikinPaint(rightPaint, rightTypeface);
+
+ return leftMinikinPaint == rightMinikinPaint;
+ }
+
}; // namespace PaintGlue
static const JNINativeMethod methods[] = {
@@ -1107,7 +1124,8 @@
{"nGetStrikeThruPosition","(J)F", (void*) PaintGlue::getStrikeThruPosition},
{"nGetStrikeThruThickness","(J)F", (void*) PaintGlue::getStrikeThruThickness},
{"nSetShadowLayer", "(JFFFI)V", (void*)PaintGlue::setShadowLayer},
- {"nHasShadowLayer", "(J)Z", (void*)PaintGlue::hasShadowLayer}
+ {"nHasShadowLayer", "(J)Z", (void*)PaintGlue::hasShadowLayer},
+ {"nEqualsForTextMeasurement", "(JJ)Z", (void*)PaintGlue::equalsForTextMeasurement},
};
int register_android_graphics_Paint(JNIEnv* env) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 5b87c33..6f3c25f 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1827,19 +1827,20 @@
<permission android:name="android.permission.BIND_TELEPHONY_NETWORK_SERVICE"
android:protectionLevel="signature" />
- <!-- Allows an application to manage embedded subscriptions (those on a eUICC) through
- EuiccManager APIs.
+ <!-- @SystemApi Allows an application to manage embedded subscriptions (those on a eUICC)
+ through EuiccManager APIs.
<p>Protection level: signature|privileged|development
- TODO(b/35851809): Mark this as a SystemApi and remove com. prefix.
- @hide -->
- <permission android:name="com.android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"
+ @hide
+ -->
+ <permission android:name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"
android:protectionLevel="signature|privileged|development" />
- <!-- Must be required by an EuiccService to ensure that only the system can bind to it.
+ <!-- @SystemApi Must be required by an EuiccService to ensure that only the system can bind to
+ it.
<p>Protection level: signature
- TODO(b/35851809): Mark this as a SystemApi and remove com. prefix.
- @hide -->
- <permission android:name="com.android.permission.BIND_EUICC_SERVICE"
+ @hide
+ -->
+ <permission android:name="android.permission.BIND_EUICC_SERVICE"
android:protectionLevel="signature" />
<!-- ================================== -->
@@ -3805,15 +3806,6 @@
<permission android:name="android.permission.INSTANT_APP_FOREGROUND_SERVICE"
android:protectionLevel="signature|development|instant|appop" />
- <!-- Allows a regular application to use {@link android.app.Service#startForeground
- Service.startForeground}.
- <p>Protection level: normal
- -->
- <permission android:name="android.permission.FOREGROUND_SERVICE"
- android:description="@string/permdesc_foregroundService"
- android:label="@string/permlab_foregroundService"
- android:protectionLevel="normal|instant" />
-
<!-- @hide Allows system components to access all app shortcuts. -->
<permission android:name="android.permission.ACCESS_SHORTCUTS"
android:protectionLevel="signature" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2b7b056..ec81df7 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -916,11 +916,6 @@
<string name="permdesc_persistentActivity" product="default">Allows the app to make parts of itself persistent in memory. This can limit memory available to other apps slowing down the phone.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_foregroundService">run foreground service</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_foregroundService">Allows the app to make use of foreground services.</string>
-
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_getPackageSize">measure app storage space</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_getPackageSize">Allows the app to retrieve its code, data, and cache sizes</string>
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 53c22f6..7d5c60a 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -51,7 +51,6 @@
<uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />
<uses-permission android:name="android.permission.DELETE_CACHE_FILES" />
<uses-permission android:name="android.permission.DOWNLOAD_CACHE_NON_PURGEABLE" />
- <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.INJECT_EVENTS" />
diff --git a/core/tests/coretests/src/android/service/euicc/EuiccProfileInfoTest.java b/core/tests/coretests/src/android/service/euicc/EuiccProfileInfoTest.java
index 1e3ddf3..e69d1e7 100644
--- a/core/tests/coretests/src/android/service/euicc/EuiccProfileInfoTest.java
+++ b/core/tests/coretests/src/android/service/euicc/EuiccProfileInfoTest.java
@@ -30,14 +30,15 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Arrays;
+
@SmallTest
@RunWith(AndroidJUnit4.class)
public class EuiccProfileInfoTest {
@Test
public void testWriteToParcel() {
EuiccProfileInfo p =
- new EuiccProfileInfo.Builder()
- .setIccid("21430000000000006587")
+ new EuiccProfileInfo.Builder("21430000000000006587")
.setNickname("profile nickname")
.setServiceProviderName("service provider")
.setProfileName("profile name")
@@ -50,9 +51,7 @@
"45"))
.setPolicyRules(EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE)
.setUiccAccessRule(
- new UiccAccessRule[] {
- new UiccAccessRule(new byte[] {}, "package", 12345L)
- })
+ Arrays.asList(new UiccAccessRule(new byte[] {}, "package", 12345L)))
.build();
Parcel parcel = Parcel.obtain();
@@ -68,8 +67,7 @@
@Test
public void testWriteToParcelNullCarrierId() {
EuiccProfileInfo p =
- new EuiccProfileInfo.Builder()
- .setIccid("21430000000000006587")
+ new EuiccProfileInfo.Builder("21430000000000006587")
.setNickname("profile nickname")
.setServiceProviderName("service provider")
.setProfileName("profile name")
@@ -77,9 +75,8 @@
.setState(EuiccProfileInfo.PROFILE_STATE_ENABLED)
.setPolicyRules(EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE)
.setUiccAccessRule(
- new UiccAccessRule[] {
- new UiccAccessRule(new byte[] {}, "package", 12345L)
- })
+ Arrays.asList(new UiccAccessRule(new byte[] {}, "package", 12345L))
+ )
.build();
Parcel parcel = Parcel.obtain();
@@ -95,8 +92,7 @@
@Test
public void testBuilderAndGetters() {
EuiccProfileInfo p =
- new EuiccProfileInfo.Builder()
- .setIccid("21430000000000006587")
+ new EuiccProfileInfo.Builder("21430000000000006587")
.setNickname("profile nickname")
.setProfileName("profile name")
.setServiceProviderName("service provider")
@@ -108,10 +104,7 @@
.setState(EuiccProfileInfo.PROFILE_STATE_ENABLED)
.setProfileClass(EuiccProfileInfo.PROFILE_CLASS_OPERATIONAL)
.setPolicyRules(EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE)
- .setUiccAccessRule(
- new UiccAccessRule[] {
- new UiccAccessRule(new byte[0], null, 0)
- })
+ .setUiccAccessRule(Arrays.asList(new UiccAccessRule(new byte[0], null, 0)))
.build();
assertEquals("21430000000000006587", p.getIccid());
@@ -130,14 +123,13 @@
assertFalse(p.hasPolicyRule(EuiccProfileInfo.POLICY_RULE_DO_NOT_DISABLE));
assertArrayEquals(
new UiccAccessRule[] {new UiccAccessRule(new byte[0], null, 0)},
- p.getUiccAccessRules());
+ p.getUiccAccessRules().toArray());
}
@Test
public void testBuilder_BasedOnAnotherProfile() {
EuiccProfileInfo p =
- new EuiccProfileInfo.Builder()
- .setIccid("21430000000000006587")
+ new EuiccProfileInfo.Builder("21430000000000006587")
.setNickname("profile nickname")
.setProfileName("profile name")
.setServiceProviderName("service provider")
@@ -150,9 +142,7 @@
.setProfileClass(EuiccProfileInfo.PROFILE_CLASS_OPERATIONAL)
.setPolicyRules(EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE)
.setUiccAccessRule(
- new UiccAccessRule[] {
- new UiccAccessRule(new byte[0], null, 0)
- })
+ Arrays.asList(new UiccAccessRule(new byte[] {}, "package", 12345L)))
.build();
EuiccProfileInfo copied = new EuiccProfileInfo.Builder(p).build();
@@ -164,8 +154,7 @@
@Test
public void testEqualsHashCode() {
EuiccProfileInfo p =
- new EuiccProfileInfo.Builder()
- .setIccid("21430000000000006587")
+ new EuiccProfileInfo.Builder("21430000000000006587")
.setNickname("profile nickname")
.setProfileName("profile name")
.setServiceProviderName("service provider")
@@ -177,10 +166,7 @@
.setState(EuiccProfileInfo.PROFILE_STATE_ENABLED)
.setProfileClass(EuiccProfileInfo.PROFILE_STATE_ENABLED)
.setPolicyRules(EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE)
- .setUiccAccessRule(
- new UiccAccessRule[] {
- new UiccAccessRule(new byte[0], null, 0)
- })
+ .setUiccAccessRule(Arrays.asList(new UiccAccessRule(new byte[0], null, 0)))
.build();
assertTrue(p.equals(p));
@@ -229,13 +215,13 @@
}
@Test(expected = IllegalStateException.class)
- public void testBuilderBuild_NoIccid() {
- new EuiccProfileInfo.Builder().build();
+ public void testBuilderBuild_IllegalIccid() {
+ new EuiccProfileInfo.Builder("abc").build();
}
@Test(expected = IllegalArgumentException.class)
public void testBuilderSetOperatorMccMnc_Illegal() {
- new EuiccProfileInfo.Builder()
+ new EuiccProfileInfo.Builder("21430000000000006587")
.setCarrierIdentifier(new CarrierIdentifier(new byte[] {1, 2, 3, 4}, null, null));
}
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 3495b84..9d1fdbd 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -176,7 +176,7 @@
<permission name="android.permission.UPDATE_LOCK"/>
<permission name="android.permission.WRITE_APN_SETTINGS"/>
<permission name="android.permission.WRITE_SECURE_SETTINGS"/>
- <permission name="com.android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"/>
+ <permission name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"/>
<permission name="com.android.voicemail.permission.READ_VOICEMAIL"/>
<permission name="com.android.voicemail.permission.WRITE_VOICEMAIL"/>
</privapp-permissions>
@@ -381,7 +381,7 @@
<permission name="android.permission.WRITE_DREAM_STATE"/>
<permission name="android.permission.WRITE_MEDIA_STORAGE"/>
<permission name="android.permission.WRITE_SECURE_SETTINGS"/>
- <permission name="com.android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"/>
+ <permission name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"/>
</privapp-permissions>
<privapp-permissions package="com.android.tv">
diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java
index eacb727..07df045 100644
--- a/graphics/java/android/graphics/BaseCanvas.java
+++ b/graphics/java/android/graphics/BaseCanvas.java
@@ -22,7 +22,7 @@
import android.annotation.Size;
import android.graphics.Canvas.VertexMode;
import android.text.GraphicsOperations;
-import android.text.MeasuredText;
+import android.text.PrecomputedText;
import android.text.SpannableString;
import android.text.SpannedString;
import android.text.TextUtils;
@@ -487,8 +487,8 @@
TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
long measuredTextPtr = 0;
int measuredTextOffset = 0;
- if (text instanceof MeasuredText) {
- MeasuredText mt = (MeasuredText) text;
+ if (text instanceof PrecomputedText) {
+ PrecomputedText mt = (PrecomputedText) text;
int paraIndex = mt.findParaIndex(start);
if (end <= mt.getParagraphEnd(paraIndex)) {
// Only suppor the same paragraph.
@@ -647,7 +647,7 @@
private static native void nDrawTextRun(long nativeCanvas, char[] text, int start, int count,
int contextStart, int contextCount, float x, float y, boolean isRtl, long nativePaint,
- long nativeMeasuredText, int measuredTextOffset);
+ long nativePrecomputedText, int measuredTextOffset);
private static native void nDrawTextOnPath(long nativeCanvas, char[] text, int index, int count,
long nativePath, float hOffset, float vOffset, int bidiFlags, long nativePaint);
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index ed147e9..42dac38 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -2835,6 +2835,16 @@
return result;
}
+ /**
+ * Returns true of the passed {@link Paint} will have the same effect on text measurement
+ *
+ * @param other A {@link Paint} object.
+ * @return true if the other {@link Paint} has the same effect on text measurement.
+ */
+ public boolean equalsForTextMeasurement(@NonNull Paint other) {
+ return nEqualsForTextMeasurement(mNativePaint, other.mNativePaint);
+ }
+
// regular JNI
private static native long nGetNativeFinalizer();
private static native long nInit();
@@ -3002,4 +3012,6 @@
private static native float nGetStrikeThruThickness(long paintPtr);
@CriticalNative
private static native void nSetTextSize(long paintPtr, float textSize);
+ @CriticalNative
+ private static native boolean nEqualsForTextMeasurement(long leftPaintPtr, long rightPaintPtr);
}
diff --git a/libs/hwui/hwui/AnimatedImageDrawable.cpp b/libs/hwui/hwui/AnimatedImageDrawable.cpp
index 2bded9b..7e4f755 100644
--- a/libs/hwui/hwui/AnimatedImageDrawable.cpp
+++ b/libs/hwui/hwui/AnimatedImageDrawable.cpp
@@ -41,8 +41,7 @@
return false;
}
- // This will trigger a reset.
- mFinished = true;
+ mStarting = true;
mRunning = true;
return true;
@@ -125,8 +124,11 @@
mDidDraw = true;
- bool drewDirectly = false;
- if (!mSnapshot.mPic) {
+ const bool starting = mStarting;
+ mStarting = false;
+
+ const bool drawDirectly = !mSnapshot.mPic;
+ if (drawDirectly) {
// The image is not animating, and never was. Draw directly from
// mSkAnimatedImage.
SkAutoCanvasRestore acr(canvas, false);
@@ -136,13 +138,14 @@
std::unique_lock lock{mImageLock};
mSkAnimatedImage->draw(canvas);
- drewDirectly = true;
- }
-
- if (mRunning && mFinished) {
+ if (!mRunning) {
+ return;
+ }
+ } else if (starting) {
+ // The image has animated, and now is being reset. Queue up the first
+ // frame, but keep showing the current frame until the first is ready.
auto& thread = uirenderer::AnimatedImageThread::getInstance();
mNextSnapshot = thread.reset(sk_ref_sp(this));
- mFinished = false;
}
bool finalFrame = false;
@@ -154,7 +157,6 @@
if (mSnapshot.mDuration == SkAnimatedImage::kFinished) {
finalFrame = true;
mRunning = false;
- mFinished = true;
} else {
mTimeToShowNextSnapshot += mSnapshot.mDuration;
if (mCurrentTime >= mTimeToShowNextSnapshot) {
@@ -173,7 +175,7 @@
mNextSnapshot = thread.decodeNextFrame(sk_ref_sp(this));
}
- if (!drewDirectly) {
+ if (!drawDirectly) {
// No other thread will modify mCurrentSnap so this should be safe to
// use without locking.
canvas->drawPicture(mSnapshot.mPic, nullptr, lazyPaint.getMaybeNull());
@@ -195,14 +197,29 @@
canvas->saveLayer(mSkAnimatedImage->getBounds(), &paint);
}
- if (mFinished && !mRunning) {
- // Continue drawing the last frame, and return 0 to indicate no need to
- // redraw.
+ if (!mRunning) {
+ // Continue drawing the current frame, and return 0 to indicate no need
+ // to redraw.
std::unique_lock lock{mImageLock};
canvas->drawDrawable(mSkAnimatedImage.get());
return 0.0;
}
+ if (mStarting) {
+ mStarting = false;
+ double duration = 0.0;
+ {
+ std::unique_lock lock{mImageLock};
+ mSkAnimatedImage->reset();
+ duration = mSkAnimatedImage->currentFrameDuration();
+ }
+ {
+ std::unique_lock lock{mSwapLock};
+ mLastWallTime = 0.0;
+ mTimeToShowNextSnapshot = duration;
+ }
+ }
+
bool update = false;
{
const double currentTime = SkTime::GetMSecs();
@@ -211,18 +228,12 @@
// the current time and avoid updating
if (mLastWallTime == 0.0) {
mCurrentTime = currentTime;
- } else if (mRunning) {
- if (mFinished) {
- mCurrentTime = currentTime;
- {
- std::unique_lock lock{mImageLock};
- mSkAnimatedImage->reset();
- }
- mTimeToShowNextSnapshot = currentTime + mSkAnimatedImage->currentFrameDuration();
- } else {
- mCurrentTime += currentTime - mLastWallTime;
- update = mCurrentTime >= mTimeToShowNextSnapshot;
- }
+ // mTimeToShowNextSnapshot is already set to the duration of the
+ // first frame.
+ mTimeToShowNextSnapshot += currentTime;
+ } else if (mRunning && mDidDraw) {
+ mCurrentTime += currentTime - mLastWallTime;
+ update = mCurrentTime >= mTimeToShowNextSnapshot;
}
mLastWallTime = currentTime;
}
@@ -237,13 +248,20 @@
canvas->drawDrawable(mSkAnimatedImage.get());
}
+ mDidDraw = true;
+
std::unique_lock lock{mSwapLock};
if (update) {
if (duration == SkAnimatedImage::kFinished) {
mRunning = false;
- mFinished = true;
- } else {
- mTimeToShowNextSnapshot += duration;
+ return duration;
+ }
+
+ const double timeToShowCurrentSnapshot = mTimeToShowNextSnapshot;
+ mTimeToShowNextSnapshot += duration;
+ if (mCurrentTime >= mTimeToShowNextSnapshot) {
+ // As in onDraw, prevent speedy catch-up behavior.
+ mCurrentTime = timeToShowCurrentSnapshot;
}
}
return mTimeToShowNextSnapshot;
diff --git a/libs/hwui/hwui/AnimatedImageDrawable.h b/libs/hwui/hwui/AnimatedImageDrawable.h
index 2fd6f40..07469d2 100644
--- a/libs/hwui/hwui/AnimatedImageDrawable.h
+++ b/libs/hwui/hwui/AnimatedImageDrawable.h
@@ -102,7 +102,7 @@
private:
sk_sp<SkAnimatedImage> mSkAnimatedImage;
bool mRunning = false;
- bool mFinished = false;
+ bool mStarting = false;
// A snapshot of the current frame to draw.
Snapshot mSnapshot;
diff --git a/media/java/android/media/MediaBrowser2.java b/media/java/android/media/MediaBrowser2.java
index 5cb8313..32d3162 100644
--- a/media/java/android/media/MediaBrowser2.java
+++ b/media/java/android/media/MediaBrowser2.java
@@ -53,8 +53,32 @@
@Nullable Bundle rootExtra) { }
/**
+ * Called when there's change in the parent's children.
+ *
+ * @param parentId parent id that you've specified with {@link #subscribe(String, Bundle)}
+ * @param extras extra bundle that you've specified with {@link #subscribe(String, Bundle)}
+ */
+ public void onChildrenChanged(@NonNull String parentId, @Nullable Bundle extras) { }
+
+ /**
+ * Called when the list of items has been returned by the library service for the previous
+ * {@link MediaBrowser2#getChildren(String, int, int, Bundle)}.
+ *
+ * @param parentId parent id
+ * @param page page number that you've specified with
+ * {@link #getChildren(String, int, int, Bundle)}
+ * @param pageSize page size that you've specified with
+ * {@link #getChildren(String, int, int, Bundle)}
+ * @param extras extra bundle that you've specified with
+ * {@link #getChildren(String, int, int, Bundle)}
+ * @param result result. Can be {@code null}
+ */
+ public void onChildrenLoaded(@NonNull String parentId, int page, int pageSize,
+ @Nullable Bundle extras, @Nullable List<MediaItem2> result) { }
+
+ /**
* Called when the item has been returned by the library service for the previous
- * {@link MediaBrowser2#getItem} call.
+ * {@link MediaBrowser2#getItem(String)} call.
* <p>
* Result can be null if there had been error.
*
@@ -64,40 +88,33 @@
public void onItemLoaded(@NonNull String mediaId, @Nullable MediaItem2 result) { }
/**
- * Called when the list of items has been returned by the library service for the previous
- * {@link MediaBrowser2#getChildren(String, int, int, Bundle)}.
+ * Called when there's change in the search result.
*
- * @param parentId parent id
- * @param page page number that you've specified
- * @param pageSize page size that you've specified
- * @param options optional bundle that you've specified
- * @param result result. Can be {@code null}
+ * @param query search query that you've specified with {@link #search(String, Bundle)}
+ * @param extras extra bundle that you've specified with {@link #search(String, Bundle)}
+ * @param totalItemCount The total item count for the search result
*/
- public void onChildrenLoaded(@NonNull String parentId, int page, int pageSize,
- @Nullable Bundle options, @Nullable List<MediaItem2> result) { }
-
- /**
- * Called when there's change in the parent's children.
- *
- * @param parentId parent id that you've specified with subscribe
- * @param options optional bundle that you've specified with subscribe
- */
- public void onChildrenChanged(@NonNull String parentId, @Nullable Bundle options) { }
+ public void onSearchResultChanged(@NonNull String query, @Nullable Bundle extras,
+ int totalItemCount) { }
/**
* Called when the search result has been returned by the library service for the previous
- * {@link MediaBrowser2#search(String, int, int, Bundle)}.
+ * {@link MediaBrowser2#getSearchResult(String, int, int, Bundle)}.
* <p>
* Result can be null if there had been error.
*
- * @param query query string that you've specified
- * @param page page number that you've specified
- * @param pageSize page size that you've specified
- * @param options optional bundle that you've specified
- * @param result result. Can be {@code null}
+ * @param query search query that you've specified with
+ * {@link #getSearchResult(String, int, int, Bundle)}
+ * @param page page number that you've specified with
+ * {@link #getSearchResult(String, int, int, Bundle)}
+ * @param pageSize page size that you've specified with
+ * {@link #getSearchResult(String, int, int, Bundle)}
+ * @param extras extra bundle that you've specified with
+ * {@link #getSearchResult(String, int, int, Bundle)}
+ * @param result result. Can be {@code null}.
*/
- public void onSearchResult(@NonNull String query, int page, int pageSize,
- @Nullable Bundle options, @Nullable List<MediaItem2> result) { }
+ public void onSearchResultLoaded(@NonNull String query, int page, int pageSize,
+ @Nullable Bundle extras, @Nullable List<MediaItem2> result) { }
}
public MediaBrowser2(@NonNull Context context, @NonNull SessionToken2 token,
@@ -131,10 +148,10 @@
* the actual contents for the parent.
*
* @param parentId parent id
- * @param options optional bundle
+ * @param extras extra bundle
*/
- public void subscribe(String parentId, @Nullable Bundle options) {
- mProvider.subscribe_impl(parentId, options);
+ public void subscribe(String parentId, @Nullable Bundle extras) {
+ mProvider.subscribe_impl(parentId, extras);
}
/**
@@ -142,43 +159,59 @@
* {@link #subscribe(String, Bundle)}.
*
* @param parentId parent id
- * @param options optional bundle
+ * @param extras extra bundle
*/
- public void unsubscribe(String parentId, @Nullable Bundle options) {
- mProvider.unsubscribe_impl(parentId, options);
- }
-
- /**
- * Get the media item with the given media id. Result would be sent back asynchronously with the
- * {@link BrowserCallback#onItemLoaded(String, MediaItem2)}.
- *
- * @param mediaId media id
- */
- public void getItem(String mediaId) {
- mProvider.getItem_impl(mediaId);
+ public void unsubscribe(String parentId, @Nullable Bundle extras) {
+ mProvider.unsubscribe_impl(parentId, extras);
}
/**
* Get list of children under the parent. Result would be sent back asynchronously with the
* {@link BrowserCallback#onChildrenLoaded(String, int, int, Bundle, List)}.
*
- * @param parentId
- * @param page
- * @param pageSize
- * @param options
+ * @param parentId parent id for getting the children.
+ * @param page page number to get the result. Starts from {@code 1}
+ * @param pageSize page size. Should be greater or equal to {@code 1}
+ * @param extras extra bundle
*/
- public void getChildren(String parentId, int page, int pageSize, @Nullable Bundle options) {
- mProvider.getChildren_impl(parentId, page, pageSize, options);
+ public void getChildren(String parentId, int page, int pageSize, @Nullable Bundle extras) {
+ mProvider.getChildren_impl(parentId, page, pageSize, extras);
}
/**
+ * Get the media item with the given media id. Result would be sent back asynchronously with the
+ * {@link BrowserCallback#onItemLoaded(String, MediaItem2)}.
*
- * @param query search query deliminated by string
+ * @param mediaId media id for specifying the item
+ */
+ public void getItem(String mediaId) {
+ mProvider.getItem_impl(mediaId);
+ }
+
+ /**
+ * Send a search request to the library service. When there's a change,
+ * {@link BrowserCallback#onSearchResultChanged(String, Bundle, int)} will be called with the
+ * bundle that you've specified. You should call
+ * {@link #getSearchResult(String, int, int, Bundle)} to get the actual search result.
+ *
+ * @param query search query. Should not be an empty string.
+ * @param extras extra bundle
+ */
+ public void search(@NonNull String query, @Nullable Bundle extras) {
+ mProvider.search_impl(query, extras);
+ }
+
+ /**
+ * Get the search result from lhe library service. Result would be sent back asynchronously with
+ * the {@link BrowserCallback#onSearchResultLoaded(String, int, int, Bundle, List)}.
+ *
+ * @param query search query that you've specified with {@link #search(String, Bundle)}
* @param page page number to get search result. Starts from {@code 1}
* @param pageSize page size. Should be greater or equal to {@code 1}
* @param extras extra bundle
*/
- public void search(String query, int page, int pageSize, Bundle extras) {
- mProvider.search_impl(query, page, pageSize, extras);
+ public void getSearchResult(@NonNull String query, int page, int pageSize,
+ @Nullable Bundle extras) {
+ mProvider.getSearchResult_impl(query, page, pageSize, extras);
}
}
diff --git a/media/java/android/media/MediaItem2.java b/media/java/android/media/MediaItem2.java
index eae4436..667aac1 100644
--- a/media/java/android/media/MediaItem2.java
+++ b/media/java/android/media/MediaItem2.java
@@ -123,27 +123,26 @@
}
/**
- * Set a metadata. Metadata shouldn't be {@code null} and its id should be match
- * with this instance's id.
+ * Set a metadata. If the metadata is not null, its id should be matched with this instance's
+ * media id.
*
* @param metadata metadata to update
*/
- public void setMetadata(@NonNull MediaMetadata2 metadata) {
+ public void setMetadata(@Nullable MediaMetadata2 metadata) {
mProvider.setMetadata_impl(metadata);
}
/**
* Returns the metadata of the media.
*/
- public @NonNull MediaMetadata2 getMetadata() {
+ public @Nullable MediaMetadata2 getMetadata() {
return mProvider.getMetadata_impl();
}
/**
- * Returns the media id in the {@link MediaMetadata2} for this item.
- * @see MediaMetadata2#METADATA_KEY_MEDIA_ID
+ * Returns the media id for this item.
*/
- public @Nullable String getMediaId() {
+ public @NonNull String getMediaId() {
return mProvider.getMediaId_impl();
}
diff --git a/media/java/android/media/MediaLibraryService2.java b/media/java/android/media/MediaLibraryService2.java
index a11768e..7a05d3c 100644
--- a/media/java/android/media/MediaLibraryService2.java
+++ b/media/java/android/media/MediaLibraryService2.java
@@ -82,22 +82,22 @@
*
* @param controller controller to notify
* @param parentId
- * @param options
+ * @param extras
*/
public void notifyChildrenChanged(@NonNull ControllerInfo controller,
- @NonNull String parentId, @NonNull Bundle options) {
- mProvider.notifyChildrenChanged_impl(controller, parentId, options);
+ @NonNull String parentId, @NonNull Bundle extras) {
+ mProvider.notifyChildrenChanged_impl(controller, parentId, extras);
}
/**
* Notify subscribed controller about change in a parent's children.
*
* @param parentId parent id
- * @param options optional bundle
+ * @param extras extra bundle
*/
// This is for the backward compatibility.
- public void notifyChildrenChanged(@NonNull String parentId, @Nullable Bundle options) {
- mProvider.notifyChildrenChanged_impl(parentId, options);
+ public void notifyChildrenChanged(@NonNull String parentId, @Nullable Bundle extras) {
+ mProvider.notifyChildrenChanged_impl(parentId, extras);
}
}
@@ -134,27 +134,12 @@
}
/**
- * Called to get the search result. Return search result here for the browser.
+ * Called to get an item. Return result here for the browser.
* <p>
- * Return an empty list for no search result, and return {@code null} for the error.
- *
- * @param query The search query sent from the media browser. It contains keywords separated
- * by space.
- * @param extras The bundle of service-specific arguments sent from the media browser.
- * @return search result. {@code null} for error.
- */
- public @Nullable List<MediaItem2> onSearch(@NonNull ControllerInfo controllerInfo,
- @NonNull String query, @Nullable Bundle extras) {
- return null;
- }
-
- /**
- * Called to get the search result . Return result here for the browser.
- * <p>
- * Return an empty list for no search result, and return {@code null} for the error.
+ * Return {@code null} for no result or error.
*
* @param itemId item id to get media item.
- * @return media item2. {@code null} for error.
+ * @return a media item. {@code null} for no result or error.
*/
public @Nullable MediaItem2 onLoadItem(@NonNull ControllerInfo controllerInfo,
@NonNull String itemId) {
@@ -162,18 +147,18 @@
}
/**
- * Called to get the search result. Return search result here for the browser.
+ * Called to get children of given parent id. Return the children here for the browser.
* <p>
- * Return an empty list for no search result, and return {@code null} for the error.
+ * Return an empty list for no children, and return {@code null} for the error.
*
* @param parentId parent id to get children
* @param page number of page
* @param pageSize size of the page
- * @param options
+ * @param extras extra bundle
* @return list of children. Can be {@code null}.
*/
public @Nullable List<MediaItem2> onLoadChildren(@NonNull ControllerInfo controller,
- @NonNull String parentId, int page, int pageSize, @Nullable Bundle options) {
+ @NonNull String parentId, int page, int pageSize, @Nullable Bundle extras) {
return null;
}
@@ -182,10 +167,10 @@
*
* @param controller controller
* @param parentId parent id
- * @param options optional bundle
+ * @param extras extra bundle
*/
- public void onSubscribed(@NonNull ControllerInfo controller,
- String parentId, @Nullable Bundle options) {
+ public void onSubscribed(@NonNull ControllerInfo controller, String parentId,
+ @Nullable Bundle extras) {
}
/**
@@ -193,10 +178,41 @@
*
* @param controller controller
* @param parentId parent id
- * @param options optional bundle
+ * @param extras extra bundle
*/
- public void onUnsubscribed(@NonNull ControllerInfo controller,
- String parentId, @Nullable Bundle options) {
+ public void onUnsubscribed(@NonNull ControllerInfo controller, String parentId,
+ @Nullable Bundle extras) {
+ }
+
+ /**
+ * Called when a controller requests search.
+ *
+ * @param query The search query sent from the media browser. It contains keywords separated
+ * by space.
+ * @param extras The bundle of service-specific arguments sent from the media browser.
+ */
+ public void onSearch(@NonNull ControllerInfo controllerInfo, @NonNull String query,
+ @Nullable Bundle extras) {
+
+ }
+
+ /**
+ * Called to get the search result. Return search result here for the browser which has
+ * requested search previously.
+ * <p>
+ * Return an empty list for no search result, and return {@code null} for the error.
+ *
+ * @param controllerInfo Information of the controller requesting the search result.
+ * @param query The search query which was previously sent through
+ * {@link #onSearch(ControllerInfo, String, Bundle)} call.
+ * @param page page number. Starts from {@code 1}.
+ * @param pageSize page size. Should be greater or equal to {@code 1}.
+ * @param extras The bundle of service-specific arguments sent from the media browser.
+ * @return search result. {@code null} for error.
+ */
+ public @Nullable List<MediaItem2> onLoadSearchResult(@NonNull ControllerInfo controllerInfo,
+ @NonNull String query, int page, int pageSize, @Nullable Bundle extras) {
+ return null;
}
}
diff --git a/media/java/android/media/MediaPlayer2Impl.java b/media/java/android/media/MediaPlayer2Impl.java
index 49bbc2b..b805eb44 100644
--- a/media/java/android/media/MediaPlayer2Impl.java
+++ b/media/java/android/media/MediaPlayer2Impl.java
@@ -17,7 +17,6 @@
package android.media;
import android.annotation.CallbackExecutor;
-import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityThread;
@@ -26,7 +25,6 @@
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.net.Uri;
-import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
@@ -48,17 +46,8 @@
import android.view.SurfaceHolder;
import android.widget.VideoView;
import android.graphics.SurfaceTexture;
-import android.media.AudioManager;
-import android.media.MediaDrm;
-import android.media.MediaFormat;
-import android.media.MediaPlayer2;
-import android.media.MediaTimeProvider;
-import android.media.PlaybackParams;
-import android.media.SubtitleController;
import android.media.SubtitleController.Anchor;
-import android.media.SubtitleData;
import android.media.SubtitleTrack.RenderingWidget;
-import android.media.SyncParams;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
@@ -74,16 +63,12 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.lang.AutoCloseable;
import java.lang.Runnable;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.HttpCookie;
import java.net.HttpURLConnection;
-import java.net.InetSocketAddress;
import java.net.URL;
import java.nio.ByteOrder;
import java.util.ArrayList;
@@ -2190,6 +2175,13 @@
private native final void native_setup(Object mediaplayer2_this);
private native final void native_finalize();
+ private static native final void native_stream_event_onTearDown(
+ long nativeCallbackPtr, long userDataPtr);
+ private static native final void native_stream_event_onStreamPresentationEnd(
+ long nativeCallbackPtr, long userDataPtr);
+ private static native final void native_stream_event_onStreamDataRequest(
+ long jAudioTrackPtr, long nativeCallbackPtr, long userDataPtr);
+
/**
* Class for MediaPlayer2 to return each audio/video/subtitle track's metadata.
*
@@ -4228,6 +4220,65 @@
}
+ // Called from the native side
+ @SuppressWarnings("unused")
+ private static boolean setAudioOutputDeviceById(AudioTrack track, int deviceId) {
+ if (track == null) {
+ return false;
+ }
+
+ if (deviceId == 0) {
+ // Use default routing.
+ track.setPreferredDevice(null);
+ return true;
+ }
+
+ // TODO: Unhide AudioManager.getDevicesStatic.
+ AudioDeviceInfo[] outputDevices =
+ AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_OUTPUTS);
+
+ boolean success = false;
+ for (AudioDeviceInfo device : outputDevices) {
+ if (device.getId() == deviceId) {
+ track.setPreferredDevice(device);
+ success = true;
+ break;
+ }
+ }
+ return success;
+ }
+
+ // Instantiated from the native side
+ @SuppressWarnings("unused")
+ private static class StreamEventCallback extends AudioTrack.StreamEventCallback {
+ public long mJAudioTrackPtr;
+ public long mNativeCallbackPtr;
+ public long mUserDataPtr;
+
+ public StreamEventCallback(long jAudioTrackPtr, long nativeCallbackPtr, long userDataPtr) {
+ super();
+ mJAudioTrackPtr = jAudioTrackPtr;
+ mNativeCallbackPtr = nativeCallbackPtr;
+ mUserDataPtr = userDataPtr;
+ }
+
+ @Override
+ public void onTearDown(AudioTrack track) {
+ native_stream_event_onTearDown(mNativeCallbackPtr, mUserDataPtr);
+ }
+
+ @Override
+ public void onStreamPresentationEnd(AudioTrack track) {
+ native_stream_event_onStreamPresentationEnd(mNativeCallbackPtr, mUserDataPtr);
+ }
+
+ @Override
+ public void onStreamDataRequest(AudioTrack track) {
+ native_stream_event_onStreamDataRequest(
+ mJAudioTrackPtr, mNativeCallbackPtr, mUserDataPtr);
+ }
+ }
+
private class ProvisioningThread extends Thread {
public static final int TIMEOUT_MS = 60000;
diff --git a/media/java/android/media/update/MediaBrowser2Provider.java b/media/java/android/media/update/MediaBrowser2Provider.java
index 17256a8..f2e7313 100644
--- a/media/java/android/media/update/MediaBrowser2Provider.java
+++ b/media/java/android/media/update/MediaBrowser2Provider.java
@@ -16,7 +16,6 @@
package android.media.update;
-import android.annotation.SystemApi;
import android.os.Bundle;
/**
@@ -29,6 +28,7 @@
void unsubscribe_impl(String parentId, Bundle options);
void getItem_impl(String mediaId);
- void getChildren_impl(String parentId, int page, int pageSize, Bundle options);
- void search_impl(String query, int page, int pageSize, Bundle extras);
+ void getChildren_impl(String parentId, int page, int pageSize, Bundle extras);
+ void search_impl(String query, Bundle options);
+ void getSearchResult_impl(String query, int page, int pageSize, Bundle extras);
}
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index d7f51d4..3518392 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -20,7 +20,7 @@
#include "android_media_MediaDrm.h"
#include "android_media_MediaMetricsJNI.h"
-
+#include "android_os_Parcel.h"
#include "android_runtime/AndroidRuntime.h"
#include "android_runtime/Log.h"
#include "android_os_Parcel.h"
@@ -29,12 +29,16 @@
#include <binder/IServiceManager.h>
#include <binder/Parcel.h>
+#include <binder/PersistableBundle.h>
#include <cutils/properties.h>
#include <media/IDrm.h>
#include <media/IMediaDrmService.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaErrors.h>
+using ::android::os::PersistableBundle;
+
+
namespace android {
#define FIND_CLASS(var, className) \
@@ -57,6 +61,10 @@
var = env->GetStaticMethodID(clazz, fieldName, fieldDescriptor); \
LOG_FATAL_IF(! (var), "Unable to find static method " fieldName);
+#define GET_STATIC_OBJECT_FIELD(var, clazz, fieldName) \
+ var = env->GetStaticObjectField(clazz, fieldName); \
+ LOG_FATAL_IF(! (var), "Unable to find static object field " fieldName);
+
struct RequestFields {
jfieldID data;
@@ -170,10 +178,58 @@
jclass hashmapClassId;
jclass arraylistClassId;
jclass stringClassId;
+ jobject bundleCreator;
+ jmethodID createFromParcelId;
+ jclass parcelCreatorClassId;
};
static fields_t gFields;
+namespace {
+
+// Helper function to convert a native PersistableBundle to a Java
+// PersistableBundle.
+jobject nativeToJavaPersistableBundle(JNIEnv *env, jobject thiz,
+ PersistableBundle* nativeBundle) {
+ if (env == NULL || thiz == NULL || nativeBundle == NULL) {
+ ALOGE("Unexpected NULL parmeter");
+ return NULL;
+ }
+
+ // Create a Java parcel with the native parcel data.
+ // Then create a new PersistableBundle with that parcel as a parameter.
+ jobject jParcel = android::createJavaParcelObject(env);
+ if (jParcel == NULL) {
+ ALOGE("Failed to create a Java Parcel.");
+ return NULL;
+ }
+
+ android::Parcel* nativeParcel = android::parcelForJavaObject(env, jParcel);
+ if (nativeParcel == NULL) {
+ ALOGE("Failed to get the native Parcel.");
+ return NULL;
+ }
+
+ android::status_t result = nativeBundle->writeToParcel(nativeParcel);
+ nativeParcel->setDataPosition(0);
+ if (result != android::OK) {
+ ALOGE("Failed to write nativeBundle to Parcel: %d.", result);
+ return NULL;
+ }
+
+ jobject newBundle = env->CallObjectMethod(gFields.bundleCreator,
+ gFields.createFromParcelId,
+ jParcel);
+ if (newBundle == NULL) {
+ ALOGE("Failed to create a new PersistableBundle "
+ "from the createFromParcel call.");
+ }
+
+ return newBundle;
+}
+
+} // namespace anonymous
+
// ----------------------------------------------------------------------------
// ref-counted object for callbacks
class JNIDrmListener: public DrmListener
@@ -713,6 +769,19 @@
GET_FIELD_ID(gFields.certificate.certificateData, clazz, "mCertificateData", "[B");
gFields.certificateClassId = static_cast<jclass>(env->NewGlobalRef(clazz));
+ // Metrics-related fields and classes.
+ FIND_CLASS(clazz, "android/os/PersistableBundle");
+ jfieldID bundleCreatorId;
+ GET_STATIC_FIELD_ID(bundleCreatorId, clazz, "CREATOR",
+ "Landroid/os/Parcelable$Creator;");
+ jobject bundleCreator;
+ GET_STATIC_OBJECT_FIELD(bundleCreator, clazz, bundleCreatorId);
+ gFields.bundleCreator = static_cast<jobject>(env->NewGlobalRef(bundleCreator));
+ FIND_CLASS(clazz, "android/os/Parcelable$Creator");
+ GET_METHOD_ID(gFields.createFromParcelId, clazz, "createFromParcel",
+ "(Landroid/os/Parcel;)Ljava/lang/Object;");
+ gFields.parcelCreatorClassId = static_cast<jclass>(env->NewGlobalRef(clazz));
+
FIND_CLASS(clazz, "java/util/ArrayList");
GET_METHOD_ID(gFields.arraylist.init, clazz, "<init>", "()V");
GET_METHOD_ID(gFields.arraylist.add, clazz, "add", "(Ljava/lang/Object;)Z");
@@ -1656,19 +1725,14 @@
}
// Retrieve current metrics snapshot from drm.
- MediaAnalyticsItem item ;
- status_t err = drm->getMetrics(&item);
+ PersistableBundle metrics;
+ status_t err = drm->getMetrics(&metrics);
if (err != OK) {
ALOGE("getMetrics failed: %d", (int)err);
return (jobject) NULL;
}
- jobject mybundle = MediaMetricsJNI::writeMetricsToBundle(env, &item, NULL);
- if (mybundle == NULL) {
- ALOGE("getMetrics metric conversion failed");
- }
-
- return mybundle;
+ return nativeToJavaPersistableBundle(env, thiz, &metrics);
}
static jbyteArray android_media_MediaDrm_signRSANative(
diff --git a/media/jni/android_media_MediaPlayer2.cpp b/media/jni/android_media_MediaPlayer2.cpp
index e73b2f8..51bc330 100644
--- a/media/jni/android_media_MediaPlayer2.cpp
+++ b/media/jni/android_media_MediaPlayer2.cpp
@@ -28,6 +28,7 @@
#include <media/NdkWrapper.h>
#include <media/stagefright/Utils.h>
#include <media/stagefright/foundation/ByteUtils.h> // for FOURCC definition
+#include <mediaplayer2/JAudioTrack.h>
#include <mediaplayer2/mediaplayer2.h>
#include <stdio.h>
#include <assert.h>
@@ -1387,6 +1388,65 @@
// AudioRouting end
// ----------------------------------------------------------------------------
+/////////////////////////////////////////////////////////////////////////////////////
+// AudioTrack.StreamEventCallback begin
+static void android_media_MediaPlayer2_native_on_tear_down(JNIEnv *env __unused,
+ jobject thiz __unused, jlong callbackPtr, jlong userDataPtr)
+{
+ JAudioTrack::callback_t callback = (JAudioTrack::callback_t) callbackPtr;
+ if (callback != NULL) {
+ callback(JAudioTrack::EVENT_NEW_IAUDIOTRACK, (void *) userDataPtr, NULL);
+ }
+}
+
+static void android_media_MediaPlayer2_native_on_stream_presentation_end(JNIEnv *env __unused,
+ jobject thiz __unused, jlong callbackPtr, jlong userDataPtr)
+{
+ JAudioTrack::callback_t callback = (JAudioTrack::callback_t) callbackPtr;
+ if (callback != NULL) {
+ callback(JAudioTrack::EVENT_STREAM_END, (void *) userDataPtr, NULL);
+ }
+}
+
+static void android_media_MediaPlayer2_native_on_stream_data_request(JNIEnv *env __unused,
+ jobject thiz __unused, jlong jAudioTrackPtr, jlong callbackPtr, jlong userDataPtr)
+{
+ JAudioTrack::callback_t callback = (JAudioTrack::callback_t) callbackPtr;
+ JAudioTrack* track = (JAudioTrack *) jAudioTrackPtr;
+ if (callback != NULL && track != NULL) {
+ JAudioTrack::Buffer* buffer = new JAudioTrack::Buffer();
+
+ size_t bufferSizeInFrames = track->frameCount();
+ audio_format_t format = track->format();
+
+ size_t bufferSizeInBytes;
+ if (audio_has_proportional_frames(format)) {
+ bufferSizeInBytes =
+ bufferSizeInFrames * audio_bytes_per_sample(format) * track->channelCount();
+ } else {
+ // See Javadoc of AudioTrack::getBufferSizeInFrames().
+ bufferSizeInBytes = bufferSizeInFrames;
+ }
+
+ uint8_t* byteBuffer = new uint8_t[bufferSizeInBytes];
+ buffer->mSize = bufferSizeInBytes;
+ buffer->mData = (void *) byteBuffer;
+
+ callback(JAudioTrack::EVENT_MORE_DATA, (void *) userDataPtr, buffer);
+
+ if (buffer->mSize > 0 && buffer->mData == byteBuffer) {
+ track->write(buffer->mData, buffer->mSize, true /* Blocking */);
+ }
+
+ delete[] byteBuffer;
+ delete buffer;
+ }
+}
+
+
+// AudioTrack.StreamEventCallback end
+// ----------------------------------------------------------------------------
+
static const JNINativeMethod gMethods[] = {
{
"nativeSetDataSource",
@@ -1443,6 +1503,11 @@
{"native_setOutputDevice", "(I)Z", (void *)android_media_MediaPlayer2_setOutputDevice},
{"native_getRoutedDeviceId", "()I", (void *)android_media_MediaPlayer2_getRoutedDeviceId},
{"native_enableDeviceCallback", "(Z)V", (void *)android_media_MediaPlayer2_enableDeviceCallback},
+
+ // StreamEventCallback for JAudioTrack
+ {"native_stream_event_onTearDown", "(JJ)V", (void *)android_media_MediaPlayer2_native_on_tear_down},
+ {"native_stream_event_onStreamPresentationEnd", "(JJ)V", (void *)android_media_MediaPlayer2_native_on_stream_presentation_end},
+ {"native_stream_event_onStreamDataRequest", "(JJJ)V", (void *)android_media_MediaPlayer2_native_on_stream_data_request},
};
// This function only registers the native methods
diff --git a/packages/MtpDocumentsProvider/AndroidManifest.xml b/packages/MtpDocumentsProvider/AndroidManifest.xml
index c0a59b3..8d79f62 100644
--- a/packages/MtpDocumentsProvider/AndroidManifest.xml
+++ b/packages/MtpDocumentsProvider/AndroidManifest.xml
@@ -3,7 +3,6 @@
package="com.android.mtp"
android:sharedUserId="android.media">
<uses-feature android:name="android.hardware.usb.host" />
- <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.MANAGE_USB" />
<application android:label="@string/app_label">
<provider
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index fa6006e..dda6799 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -53,16 +53,25 @@
<string name="bluetooth_disconnected" msgid="6557104142667339895">"Déconnecté"</string>
<string name="bluetooth_disconnecting" msgid="8913264760027764974">"Déconnexion…"</string>
<string name="bluetooth_connecting" msgid="8555009514614320497">"Connexion en cours…"</string>
- <string name="bluetooth_connected" msgid="6038755206916626419">"Connecté"</string>
+ <!-- no translation found for bluetooth_connected (5427152882755735944) -->
+ <skip />
<string name="bluetooth_pairing" msgid="1426882272690346242">"Association…"</string>
- <string name="bluetooth_connected_no_headset" msgid="2866994875046035609">"Connecté (sans audio pour appels tél.)"</string>
- <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Connecté (sans audio contenu mutimédia)"</string>
- <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Connecté (sans accès aux messages)"</string>
- <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Connecté (sans audio tel./multimédia)"</string>
- <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Connecté. Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Connecté (sans téléphone). Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Connecté (sans média). Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Connecté (sans téléphone ni média). Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <!-- no translation found for bluetooth_connected_no_headset (616068069034994802) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_no_a2dp (3736431800395923868) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_no_map (3200033913678466453) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_no_headset_no_a2dp (2047403011284187056) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_battery_level (5162924691231307748) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_no_headset_battery_level (1610296229139400266) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (3908466636369853652) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1163440823807659316) -->
+ <skip />
<string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Paramètres audio du support"</string>
<string name="bluetooth_profile_headset" msgid="7815495680863246034">"Appels téléphoniques"</string>
<string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfert de fichier"</string>
@@ -327,9 +336,12 @@
<item msgid="8280754435979370728">"Couleurs naturelles, comme l\'œil les voit"</item>
<item msgid="5363960654009010371">"Couleurs optimisées pour le contenu numérique"</item>
</string-array>
- <string name="inactive_apps_title" msgid="1317817863508274533">"Applications inactives"</string>
+ <!-- no translation found for inactive_apps_title (9042996804461901648) -->
+ <skip />
<string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Application inactive. Touchez ici pour l\'activer."</string>
<string name="inactive_app_active_summary" msgid="4174921824958516106">"Application active. Touchez ici pour la désactiver."</string>
+ <!-- no translation found for standby_bucket_summary (6567835350910684727) -->
+ <skip />
<string name="runningservices_settings_title" msgid="8097287939865165213">"Services en cours d\'exécution"</string>
<string name="runningservices_settings_summary" msgid="854608995821032748">"Afficher et contrôler les services en cours d\'exécution"</string>
<string name="select_webview_provider_title" msgid="4628592979751918907">"Mise en œuvre WebView"</string>
@@ -351,16 +363,34 @@
<string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correction des couleurs"</string>
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Cette fonctionnalité est expérimentale et peut affecter les performances."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="power_remaining_duration_only" msgid="845431008899029842">"Il reste environ <xliff:g id="TIME">^1</xliff:g>"</string>
- <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Il reste environ <xliff:g id="TIME">^1</xliff:g> en fonction de votre usage"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> jusqu\'à la charge complète"</string>
- <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant : <xliff:g id="TIME">^1</xliff:g>"</string>
- <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Il reste <xliff:g id="TIME">^1</xliff:g> en fonction de votre usage"</string>
- <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> : il reste environ <xliff:g id="TIME">^2</xliff:g>"</string>
- <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> : il reste environ <xliff:g id="TIME">^2</xliff:g> en fonction de votre usage"</string>
- <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – Temps restant : <xliff:g id="TIME">^2</xliff:g>"</string>
+ <string name="power_remaining_duration_only" msgid="845431008899029842">"Il reste environ <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Il reste environ <xliff:g id="TIME">%1$s</xliff:g> en fonction de votre usage"</string>
+ <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> jusqu\'à la charge complète"</string>
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant : <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <!-- no translation found for power_remaining_less_than_duration_only (5996752448813295329) -->
+ <skip />
+ <!-- no translation found for power_remaining_less_than_duration (7967078125657859046) -->
+ <skip />
+ <!-- no translation found for power_remaining_more_than_subtext (6846716609975752316) -->
+ <skip />
+ <!-- no translation found for power_remaining_only_more_than_subtext (8884488700395194194) -->
+ <skip />
+ <!-- no translation found for power_remaining_duration_only_shutdown_imminent (8168317165722752881) -->
+ <skip />
+ <!-- no translation found for power_remaining_duration_only_shutdown_imminent (5957064378548718872) -->
+ <skip />
+ <!-- no translation found for power_remaining_duration_only_shutdown_imminent (9055596817716471373) -->
+ <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> : il reste environ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> : il reste environ <xliff:g id="TIME">%2$s</xliff:g> en fonction de votre usage"</string>
+ <!-- no translation found for power_remaining_duration_shutdown_imminent (7679005631124015335) -->
+ <skip />
+ <!-- no translation found for power_remaining_duration_shutdown_imminent (261050880878965621) -->
+ <skip />
+ <!-- no translation found for power_remaining_duration_shutdown_imminent (2020049829798578618) -->
+ <skip />
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> : <xliff:g id="TIME">^2</xliff:g> jusqu\'à la charge complète"</string>
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> : <xliff:g id="TIME">%2$s</xliff:g> jusqu\'à la charge complète"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Inconnu"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charge en cours…"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"en cours de charge"</string>
@@ -414,4 +444,12 @@
<string name="zen_mode_settings_summary_off" msgid="6119891445378113334">"Jamais"</string>
<string name="zen_interruption_level_priority" msgid="2078370238113347720">"Priorités seulement"</string>
<string name="zen_mode_and_condition" msgid="4927230238450354412">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_alarm_warning_indef (3007988140196673193) -->
+ <skip />
+ <!-- no translation found for zen_alarm_warning (6236690803924413088) -->
+ <skip />
+ <!-- no translation found for alarm_template (4996153414057676512) -->
+ <skip />
+ <!-- no translation found for alarm_template_far (3779172822607461675) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 48c7bec..a1cdb8c 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -53,16 +53,25 @@
<string name="bluetooth_disconnected" msgid="6557104142667339895">"Исклучено"</string>
<string name="bluetooth_disconnecting" msgid="8913264760027764974">"Се исклучува..."</string>
<string name="bluetooth_connecting" msgid="8555009514614320497">"Се поврзува..."</string>
- <string name="bluetooth_connected" msgid="6038755206916626419">"Поврзани"</string>
+ <!-- no translation found for bluetooth_connected (5427152882755735944) -->
+ <skip />
<string name="bluetooth_pairing" msgid="1426882272690346242">"Поврзување..."</string>
- <string name="bluetooth_connected_no_headset" msgid="2866994875046035609">"Поврзани (без телефон)"</string>
- <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Поврзани (без медиуми)"</string>
- <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Поврзано (без порака за пристап)"</string>
- <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Поврзан (без телефон или медиуми)"</string>
- <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Поврзан, ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Поврзан (освен телефонот), ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Поврзан (освен аудио-визуелните содржини), ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Поврзан (освен телефонот и аудио-визуелните содржини), ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <!-- no translation found for bluetooth_connected_no_headset (616068069034994802) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_no_a2dp (3736431800395923868) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_no_map (3200033913678466453) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_no_headset_no_a2dp (2047403011284187056) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_battery_level (5162924691231307748) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_no_headset_battery_level (1610296229139400266) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (3908466636369853652) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1163440823807659316) -->
+ <skip />
<string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Аудио на медиуми"</string>
<string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефонски повици"</string>
<string name="bluetooth_profile_opp" msgid="9168139293654233697">"Пренос на датотека"</string>
@@ -327,9 +336,12 @@
<item msgid="8280754435979370728">"Природни бои како што со гледаат со голо око"</item>
<item msgid="5363960654009010371">"Оптимизирани бои за дигитална содржина"</item>
</string-array>
- <string name="inactive_apps_title" msgid="1317817863508274533">"Неактивни апликации"</string>
+ <!-- no translation found for inactive_apps_title (9042996804461901648) -->
+ <skip />
<string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Неактивно. Допрете за да смените."</string>
<string name="inactive_app_active_summary" msgid="4174921824958516106">"Активно. Допрете за да смените."</string>
+ <!-- no translation found for standby_bucket_summary (6567835350910684727) -->
+ <skip />
<string name="runningservices_settings_title" msgid="8097287939865165213">"Активни услуги"</string>
<string name="runningservices_settings_summary" msgid="854608995821032748">"Погледнете и контролирајте услуги што се моментално активни"</string>
<string name="select_webview_provider_title" msgid="4628592979751918907">"Воведување WebView"</string>
@@ -351,16 +363,34 @@
<string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекција на боја"</string>
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Функцијата е експериментална и може да влијае на изведбата."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Прескокнато според <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="power_remaining_duration_only" msgid="845431008899029842">"Преостануваат околу <xliff:g id="TIME">^1</xliff:g>"</string>
- <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Уште околу <xliff:g id="TIME">^1</xliff:g> според користењето"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Преостануваат <xliff:g id="TIME">^1</xliff:g> дури се наполни целосно"</string>
- <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"уште <xliff:g id="TIME">^1</xliff:g>"</string>
- <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Уште <xliff:g id="TIME">^1</xliff:g> според користењето"</string>
- <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - уште околу <xliff:g id="TIME">^2</xliff:g>"</string>
- <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - уште околу <xliff:g id="TIME">^2</xliff:g> според користењето"</string>
- <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - уште <xliff:g id="TIME">^2</xliff:g>"</string>
+ <string name="power_remaining_duration_only" msgid="845431008899029842">"Преостануваат околу <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Уште околу <xliff:g id="TIME">%1$s</xliff:g> според користењето"</string>
+ <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Преостануваат <xliff:g id="TIME">%1$s</xliff:g> дури се наполни целосно"</string>
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"уште <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <!-- no translation found for power_remaining_less_than_duration_only (5996752448813295329) -->
+ <skip />
+ <!-- no translation found for power_remaining_less_than_duration (7967078125657859046) -->
+ <skip />
+ <!-- no translation found for power_remaining_more_than_subtext (6846716609975752316) -->
+ <skip />
+ <!-- no translation found for power_remaining_only_more_than_subtext (8884488700395194194) -->
+ <skip />
+ <!-- no translation found for power_remaining_duration_only_shutdown_imminent (8168317165722752881) -->
+ <skip />
+ <!-- no translation found for power_remaining_duration_only_shutdown_imminent (5957064378548718872) -->
+ <skip />
+ <!-- no translation found for power_remaining_duration_only_shutdown_imminent (9055596817716471373) -->
+ <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - уште околу <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - уште околу <xliff:g id="TIME">%2$s</xliff:g> според користењето"</string>
+ <!-- no translation found for power_remaining_duration_shutdown_imminent (7679005631124015335) -->
+ <skip />
+ <!-- no translation found for power_remaining_duration_shutdown_imminent (261050880878965621) -->
+ <skip />
+ <!-- no translation found for power_remaining_duration_shutdown_imminent (2020049829798578618) -->
+ <skip />
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> дури се наполни целосно"</string>
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> дури се наполни целосно"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Непознато"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Се полни"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"се полни"</string>
@@ -414,4 +444,12 @@
<string name="zen_mode_settings_summary_off" msgid="6119891445378113334">"Никогаш"</string>
<string name="zen_interruption_level_priority" msgid="2078370238113347720">"Само приоритетно"</string>
<string name="zen_mode_and_condition" msgid="4927230238450354412">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_alarm_warning_indef (3007988140196673193) -->
+ <skip />
+ <!-- no translation found for zen_alarm_warning (6236690803924413088) -->
+ <skip />
+ <!-- no translation found for alarm_template (4996153414057676512) -->
+ <skip />
+ <!-- no translation found for alarm_template_far (3779172822607461675) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 0a65c13..ecb73f0 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -53,16 +53,25 @@
<string name="bluetooth_disconnected" msgid="6557104142667339895">"Uzildi"</string>
<string name="bluetooth_disconnecting" msgid="8913264760027764974">"Uzilyapti…"</string>
<string name="bluetooth_connecting" msgid="8555009514614320497">"Ulanmoqda…"</string>
- <string name="bluetooth_connected" msgid="6038755206916626419">"Ulandi"</string>
+ <!-- no translation found for bluetooth_connected (5427152882755735944) -->
+ <skip />
<string name="bluetooth_pairing" msgid="1426882272690346242">"Biriktirilmoqda"</string>
- <string name="bluetooth_connected_no_headset" msgid="2866994875046035609">"Ulandi (telefondan tashqari)"</string>
- <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Ulanildi (mediadan tashqari)"</string>
- <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Ulangan (xabarlarga kirib bo‘lmaydi)"</string>
- <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Ulangan (telefon yoki media qurilma emas)"</string>
- <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Ulangan, batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Ulangan (HSP/HFP dan tashqari), batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Ulangan (A2DP dan tashqari), batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Ulangan (HSP/HFP/A2DP dan tashqari), batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <!-- no translation found for bluetooth_connected_no_headset (616068069034994802) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_no_a2dp (3736431800395923868) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_no_map (3200033913678466453) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_no_headset_no_a2dp (2047403011284187056) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_battery_level (5162924691231307748) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_no_headset_battery_level (1610296229139400266) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (3908466636369853652) -->
+ <skip />
+ <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1163440823807659316) -->
+ <skip />
<string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
<string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefon chaqiruvlari"</string>
<string name="bluetooth_profile_opp" msgid="9168139293654233697">"Fayl uzatish"</string>
@@ -327,9 +336,12 @@
<item msgid="8280754435979370728">"Ko‘zga ko‘rinadigan tabiiy ranglar"</item>
<item msgid="5363960654009010371">"Raqamli kontentga moslashtirilgan ranglar"</item>
</string-array>
- <string name="inactive_apps_title" msgid="1317817863508274533">"Nofaol ilovalar"</string>
+ <!-- no translation found for inactive_apps_title (9042996804461901648) -->
+ <skip />
<string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Nofaol. O‘zgartirish uchun bu yerga bosing."</string>
<string name="inactive_app_active_summary" msgid="4174921824958516106">"Faol. O‘zgartirish uchun bu yerga bosing."</string>
+ <!-- no translation found for standby_bucket_summary (6567835350910684727) -->
+ <skip />
<string name="runningservices_settings_title" msgid="8097287939865165213">"Ishlab turgan ilovalar"</string>
<string name="runningservices_settings_summary" msgid="854608995821032748">"Ishlab turgan ilovalarni ko‘rish va boshqarish"</string>
<string name="select_webview_provider_title" msgid="4628592979751918907">"WebView ta’minotchisi"</string>
@@ -351,16 +363,34 @@
<string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Rangni tuzatish"</string>
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu funksiya tajribaviy bo‘lib, u qurilma unumdorligiga ta’sir qilishi mumkin."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> bilan almashtirildi"</string>
- <string name="power_remaining_duration_only" msgid="845431008899029842">"Taxminan <xliff:g id="TIME">^1</xliff:g> qoldi"</string>
- <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Joriy holatda taxminan <xliff:g id="TIME">^1</xliff:g> qoldi"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"To‘lishiga <xliff:g id="TIME">^1</xliff:g> qoldi"</string>
- <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> qoldi"</string>
- <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Joriy holatda <xliff:g id="TIME">^1</xliff:g> qoldi"</string>
- <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> – taxminan <xliff:g id="TIME">^2</xliff:g> qoldi"</string>
- <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> (joriy holatda taxminan <xliff:g id="TIME">^2</xliff:g> qoldi)"</string>
- <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> qoldi"</string>
+ <string name="power_remaining_duration_only" msgid="845431008899029842">"Taxminan <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
+ <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Joriy holatda taxminan <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
+ <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"To‘lishiga <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
+ <!-- no translation found for power_remaining_less_than_duration_only (5996752448813295329) -->
+ <skip />
+ <!-- no translation found for power_remaining_less_than_duration (7967078125657859046) -->
+ <skip />
+ <!-- no translation found for power_remaining_more_than_subtext (6846716609975752316) -->
+ <skip />
+ <!-- no translation found for power_remaining_only_more_than_subtext (8884488700395194194) -->
+ <skip />
+ <!-- no translation found for power_remaining_duration_only_shutdown_imminent (8168317165722752881) -->
+ <skip />
+ <!-- no translation found for power_remaining_duration_only_shutdown_imminent (5957064378548718872) -->
+ <skip />
+ <!-- no translation found for power_remaining_duration_only_shutdown_imminent (9055596817716471373) -->
+ <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – taxminan <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
+ <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> (joriy holatda taxminan <xliff:g id="TIME">%2$s</xliff:g> qoldi)"</string>
+ <!-- no translation found for power_remaining_duration_shutdown_imminent (7679005631124015335) -->
+ <skip />
+ <!-- no translation found for power_remaining_duration_shutdown_imminent (261050880878965621) -->
+ <skip />
+ <!-- no translation found for power_remaining_duration_shutdown_imminent (2020049829798578618) -->
+ <skip />
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> – <xliff:g id="TIME">^2</xliff:g> ichida to‘ladi"</string>
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> ichida to‘ladi"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Noma’lum"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Quvvat olmoqda"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"quvvat olmoqda"</string>
@@ -414,4 +444,12 @@
<string name="zen_mode_settings_summary_off" msgid="6119891445378113334">"Hech qachon"</string>
<string name="zen_interruption_level_priority" msgid="2078370238113347720">"Faqat muhimlari"</string>
<string name="zen_mode_and_condition" msgid="4927230238450354412">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_alarm_warning_indef (3007988140196673193) -->
+ <skip />
+ <!-- no translation found for zen_alarm_warning (6236690803924413088) -->
+ <skip />
+ <!-- no translation found for alarm_template (4996153414057676512) -->
+ <skip />
+ <!-- no translation found for alarm_template_far (3779172822607461675) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml
index ddb49b6..7b09ef7 100644
--- a/packages/SettingsLib/res/values/dimens.xml
+++ b/packages/SettingsLib/res/values/dimens.xml
@@ -83,4 +83,12 @@
<dimen name="zen_mode_condition_detail_item_interline_spacing">4dp</dimen>
<!-- Zen mode panel: bottom padding, a bit less than qs_panel_padding -->
<dimen name="zen_mode_condition_detail_bottom_padding">4dp</dimen>
+
+ <!-- SignalDrawable -->
+ <dimen name="signal_icon_size">17dp</dimen>
+ <!-- How far to inset the rounded edges -->
+ <dimen name="stat_sys_mobile_signal_circle_inset">0.9dp</dimen>
+
+
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java b/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
rename to packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java
index 15ef742..846e30d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java
@@ -12,7 +12,7 @@
* permissions and limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.settingslib.graph;
import android.animation.ArgbEvaluator;
import android.annotation.IntRange;
@@ -36,7 +36,6 @@
import com.android.settingslib.R;
import com.android.settingslib.Utils;
-import com.android.systemui.qs.SlashDrawable;
public class SignalDrawable extends Drawable {
@@ -458,6 +457,7 @@
}
private final class SlashArtist {
+ private static final float CORNER_RADIUS = 1f;
// These values are derived in un-rotated (vertical) orientation
private static final float SLASH_WIDTH = 1.8384776f;
private static final float SLASH_HEIGHT = 22f;
@@ -478,7 +478,7 @@
void draw(int height, int width, @NonNull Canvas canvas, Paint paint) {
Matrix m = new Matrix();
- final float radius = scale(SlashDrawable.CORNER_RADIUS, width);
+ final float radius = scale(CORNER_RADIUS, width);
updateRect(
scale(LEFT, width),
scale(TOP, height),
diff --git a/packages/SettingsLib/tests/robotests/Android.mk b/packages/SettingsLib/tests/robotests/Android.mk
index 7cf7163..f5c42b6 100644
--- a/packages/SettingsLib/tests/robotests/Android.mk
+++ b/packages/SettingsLib/tests/robotests/Android.mk
@@ -12,12 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
############################################################
# SettingsLib Shell app just for Robolectric test target. #
############################################################
LOCAL_PATH := $(call my-dir)
-
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := SettingsLibShell
@@ -25,8 +23,7 @@
LOCAL_PRIVILEGED_MODULE := true
-LOCAL_RESOURCE_DIR := \
- $(LOCAL_PATH)/res
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_USE_AAPT2 := true
@@ -35,43 +32,44 @@
include $(BUILD_PACKAGE)
#############################################
-# SettingsLib Robolectric test target. #
+# SettingsLib Robolectric test target. #
#############################################
include $(CLEAR_VARS)
+LOCAL_MODULE := SettingsLibRoboTests
+
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-# Include the testing libraries (JUnit4 + Robolectric libs).
-LOCAL_STATIC_JAVA_LIBRARIES := \
- mockito-robolectric-prebuilt \
- platform-robolectric-android-all-stubs \
- truth-prebuilt
+LOCAL_JAVA_RESOURCE_DIRS := config
LOCAL_JAVA_LIBRARIES := \
- junit \
- platform-robolectric-3.6.1-prebuilt
+ robolectric_android-all-stub \
+ Robolectric_all-target \
+ mockito-robolectric-prebuilt \
+ truth-prebuilt
LOCAL_INSTRUMENTATION_FOR := SettingsLibShell
-LOCAL_MODULE := SettingsLibRoboTests
LOCAL_MODULE_TAGS := optional
include $(BUILD_STATIC_JAVA_LIBRARY)
#############################################################
-# SettingsLib runner target to run the previous target. #
+# SettingsLib runner target to run the previous target. #
#############################################################
include $(CLEAR_VARS)
LOCAL_MODULE := RunSettingsLibRoboTests
-LOCAL_SDK_VERSION := current
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- SettingsLibRoboTests
+LOCAL_JAVA_LIBRARIES := \
+ SettingsLibRoboTests \
+ robolectric_android-all-stub \
+ Robolectric_all-target \
+ mockito-robolectric-prebuilt \
+ truth-prebuilt
LOCAL_TEST_PACKAGE := SettingsLibShell
LOCAL_ROBOTEST_TIMEOUT := 36000
-include prebuilts/misc/common/robolectric/3.6.1/run_robotests.mk
+include external/robolectric-shadows/run_robotests.mk
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/config/robolectric.properties b/packages/SettingsLib/tests/robotests/config/robolectric.properties
new file mode 100644
index 0000000..34a2a1a
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/config/robolectric.properties
@@ -0,0 +1,2 @@
+manifest=frameworks/base/packages/SettingsLib/tests/robotests/AndroidManifest.xml
+sdk=NEWEST_SDK
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/CustomEditTextPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/CustomEditTextPreferenceTest.java
index 7e37493..9d7f59a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/CustomEditTextPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/CustomEditTextPreferenceTest.java
@@ -31,11 +31,9 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class CustomEditTextPreferenceTest {
@Mock
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/DeviceInfoUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/DeviceInfoUtilsTest.java
index 82604f7..19a916c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/DeviceInfoUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/DeviceInfoUtilsTest.java
@@ -25,10 +25,8 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class DeviceInfoUtilsTest {
private Context mContext;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java
index fdc42bf..e153c3e 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java
@@ -16,6 +16,13 @@
package com.android.settingslib;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
@@ -27,6 +34,7 @@
import android.content.res.TypedArray;
import android.provider.Settings;
import android.view.MenuItem;
+
import com.android.internal.R;
import org.junit.Before;
@@ -37,20 +45,11 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
/**
* Tests for {@link HelpUtils}.
*/
@RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class HelpUtilsTest {
private static final String TEST_HELP_URL = "intent:#Intent;action=com.android.test;end";
private static final String PACKAGE_NAME_KEY = "package-name-key";
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
index 64de635..5f60868 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
@@ -20,11 +20,8 @@
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT;
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_REMOTE_INPUT;
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
-
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-
import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
@@ -43,12 +40,10 @@
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
import java.util.Arrays;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class RestrictedLockUtilsTest {
@Mock
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedPreferenceHelperTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedPreferenceHelperTest.java
index 79d99f7..a8821ba 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedPreferenceHelperTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedPreferenceHelperTest.java
@@ -17,6 +17,12 @@
package com.android.settingslib;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceViewHolder;
@@ -28,19 +34,10 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
-
-import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class RestrictedPreferenceHelperTest {
-
@Mock
private Context mContext;
@Mock
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingsLibRobolectricTestRunner.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingsLibRobolectricTestRunner.java
index df850be..8778ae9 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingsLibRobolectricTestRunner.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingsLibRobolectricTestRunner.java
@@ -15,6 +15,8 @@
*/
package com.android.settingslib;
+import android.annotation.NonNull;
+
import org.junit.runners.model.InitializationError;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
@@ -22,6 +24,8 @@
import org.robolectric.res.Fs;
import org.robolectric.res.ResourcePath;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.List;
public class SettingsLibRobolectricTestRunner extends RobolectricTestRunner {
@@ -30,33 +34,40 @@
super(testClass);
}
+ /**
+ * We are going to create our own custom manifest so we can add multiple resource paths to it.
+ */
@Override
protected AndroidManifest getAppManifest(Config config) {
- // Using the manifest file's relative path, we can figure out the application directory.
- final String appRoot = "frameworks/base/packages/SettingsLib";
- final String manifestPath = appRoot + "/AndroidManifest.xml";
- final String resDir = appRoot + "/tests/robotests/res";
- final String assetsDir = appRoot + config.assetDir();
+ try {
+ // Using the manifest file's relative path, we can figure out the application directory.
+ final URL appRoot =
+ new URL("file:frameworks/base/packages/SettingsLib/tests/robotests");
+ final URL manifestPath = new URL(appRoot, "AndroidManifest.xml");
+ final URL resDir = new URL(appRoot, "res");
+ final URL assetsDir = new URL(appRoot, "assets");
- return new AndroidManifest(Fs.fileFromPath(manifestPath), Fs.fileFromPath(resDir),
- Fs.fileFromPath(assetsDir), "com.android.settingslib") {
- @Override
- public List<ResourcePath> getIncludedResourcePaths() {
- List<ResourcePath> paths = super.getIncludedResourcePaths();
- paths.add(new ResourcePath(
- null,
- Fs.fileFromPath("./frameworks/base/packages/SettingsLib/res"),
- null));
- paths.add(new ResourcePath(
- null,
- Fs.fileFromPath("./frameworks/base/core/res/res"),
- null));
- paths.add(new ResourcePath(
- null,
- Fs.fileFromPath("./frameworks/support/v7/appcompat/res"),
- null));
- return paths;
- }
- };
+ return new AndroidManifest(Fs.fromURL(manifestPath), Fs.fromURL(resDir),
+ Fs.fromURL(assetsDir), "com.android.settingslib") {
+ @Override
+ public List<ResourcePath> getIncludedResourcePaths() {
+ final List<ResourcePath> paths = super.getIncludedResourcePaths();
+ paths.add(resourcePath("file:frameworks/base/packages/SettingsLib/res"));
+ paths.add(resourcePath("file:frameworks/base/core/res/res"));
+ paths.add(resourcePath("file:frameworks/support/v7/appcompat/res"));
+ return paths;
+ }
+ };
+ } catch (MalformedURLException e) {
+ throw new RuntimeException("SettingsLibRobolectricTestRunner failure", e);
+ }
+ }
+
+ private static ResourcePath resourcePath(@NonNull String spec) {
+ try {
+ return new ResourcePath(null, Fs.fromURL(new URL(spec)), null);
+ } catch (MalformedURLException e) {
+ throw new RuntimeException("SettingsLibRobolectricTestRunner failure", e);
+ }
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
deleted file mode 100644
index 1f9070c..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settingslib;
-
-import android.os.Build;
-
-public class TestConfig {
- public static final int SDK_VERSION = Build.VERSION_CODES.O;
- public static final String MANIFEST_PATH =
- "frameworks/base/packages/SettingsLib/tests/robotests/AndroidManifest.xml";
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TetherUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TetherUtilTest.java
index 8bd31d4..0109f48 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TetherUtilTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TetherUtilTest.java
@@ -16,6 +16,8 @@
package com.android.settingslib;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
import android.content.Context;
@@ -24,13 +26,8 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.when;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class TetherUtilTest {
@Mock
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TwoTargetPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TwoTargetPreferenceTest.java
index b5ee5ad..c5e93f0 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TwoTargetPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TwoTargetPreferenceTest.java
@@ -31,10 +31,8 @@
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class TwoTargetPreferenceTest {
private PreferenceViewHolder mViewHolder;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
index 5459fb7..12d3106 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
@@ -34,9 +34,9 @@
import android.provider.Settings;
import android.provider.Settings.Secure;
import android.text.TextUtils;
+
import com.android.settingslib.wrapper.LocationManagerWrapper;
-import java.util.HashMap;
-import java.util.Map;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -50,11 +50,11 @@
import org.robolectric.annotation.Implements;
import org.robolectric.shadows.ShadowSettings;
+import java.util.HashMap;
+import java.util.Map;
+
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(
- manifest = TestConfig.MANIFEST_PATH,
- sdk = TestConfig.SDK_VERSION,
- shadows = {
+@Config(shadows = {
UtilsTest.ShadowSecure.class,
UtilsTest.ShadowLocationManagerWrapper.class})
public class UtilsTest {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java
index fa31a7d..060b716 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java
@@ -17,7 +17,6 @@
package com.android.settingslib.applications;
import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -27,24 +26,17 @@
import android.provider.Settings;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
-import com.android.settingslib.testutils.shadow.ShadowPackageManagerWrapper;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
- shadows = {ShadowPackageManagerWrapper.class})
public class ServiceListingTest {
private static final String TEST_SETTING = "testSetting";
private static final String TEST_INTENT = "com.example.intent";
- private static final String TEST_PERMISSION = "testPermission";
private ServiceListing mServiceListing;
@@ -59,11 +51,6 @@
.build();
}
- @After
- public void tearDown() {
- ShadowPackageManagerWrapper.reset();
- }
-
@Test
public void testCallback() {
ServiceListing.Callback callback = mock(ServiceListing.Callback.class);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
index 590bc90..334ea16 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
@@ -15,6 +15,13 @@
*/
package com.android.settingslib.bluetooth;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothCodecConfig;
import android.bluetooth.BluetoothCodecStatus;
@@ -24,30 +31,16 @@
import android.content.res.Resources;
import com.android.settingslib.R;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.wrapper.BluetoothA2dpWrapper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
@RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class A2dpProfileTest {
@Mock Context mContext;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index 1481161..92c68e6 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -16,7 +16,6 @@
package com.android.settingslib.bluetooth;
import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doAnswer;
@@ -30,9 +29,6 @@
import android.bluetooth.BluetoothProfile;
import android.content.Context;
-import com.android.settingslib.R;
-import com.android.settingslib.TestConfig;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -43,8 +39,7 @@
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, resourceDir =
- "../../res")
+@Config(resourceDir = "../../res")
public class CachedBluetoothDeviceTest {
private final static String DEVICE_NAME = "TestName";
private final static String DEVICE_ALIAS = "TestAlias";
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/UtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/UtilsTest.java
index 5eb543b..baba267 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/UtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/UtilsTest.java
@@ -22,18 +22,13 @@
import com.android.settingslib.R;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.graph.BluetoothDeviceLayerDrawable;
-import com.android.settingslib.testutils.shadow.SettingsLibShadowResources;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
- shadows = SettingsLibShadowResources.class)
public class UtilsTest {
@Test
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/AbstractPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/AbstractPreferenceControllerTest.java
index 26970e1..8767923 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/AbstractPreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/AbstractPreferenceControllerTest.java
@@ -22,8 +22,6 @@
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
-import com.android.settingslib.TestConfig;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -31,10 +29,8 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class AbstractPreferenceControllerTest {
@Mock
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java
index 8bea51d..5c19e61 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java
@@ -28,7 +28,6 @@
import android.util.Pair;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
import org.junit.Before;
@@ -39,14 +38,12 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class MetricsFeatureProviderTest {
private static int CATEGORY = 10;
private static boolean SUBTYPE_BOOLEAN = true;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SharedPreferenceLoggerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SharedPreferenceLoggerTest.java
index d558a64..ebafc59 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SharedPreferenceLoggerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SharedPreferenceLoggerTest.java
@@ -30,9 +30,7 @@
import android.content.SharedPreferences;
import android.util.Pair;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-
import com.google.common.truth.Platform;
import org.junit.Before;
@@ -42,10 +40,8 @@
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SharedPreferenceLoggerTest {
private static final String TEST_TAG = "tag";
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixinTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixinTest.java
index 1ab6afe..8b31450 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixinTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixinTest.java
@@ -16,7 +16,6 @@
package com.android.settingslib.core.instrumentation;
import static com.android.settingslib.core.instrumentation.Instrumentable.METRICS_CATEGORY_UNKNOWN;
-
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
@@ -30,12 +29,11 @@
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
-
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
+
import com.android.internal.logging.nano.MetricsProto;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import org.junit.Before;
import org.junit.Test;
@@ -44,11 +42,9 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.android.controller.ActivityController;
-import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class VisibilityLoggerMixinTest {
@Mock
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java
index ae24c07..2b2bf5b 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java
@@ -25,7 +25,6 @@
import android.view.MenuItem;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.core.lifecycle.events.OnAttach;
import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu;
import com.android.settingslib.core.lifecycle.events.OnDestroy;
@@ -42,10 +41,8 @@
import org.robolectric.Robolectric;
import org.robolectric.android.controller.ActivityController;
import org.robolectric.android.controller.FragmentController;
-import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class LifecycleTest {
private LifecycleOwner mLifecycleOwner;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/DevelopmentSettingsEnablerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/DevelopmentSettingsEnablerTest.java
index 708353e..a15f5fc 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/DevelopmentSettingsEnablerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/DevelopmentSettingsEnablerTest.java
@@ -22,7 +22,6 @@
import android.provider.Settings;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.testutils.shadow.ShadowUserManager;
import org.junit.After;
@@ -33,9 +32,7 @@
import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, shadows = {
- ShadowUserManager.class
-})
+@Config(shadows = ShadowUserManager.class)
public class DevelopmentSettingsEnablerTest {
private Context mContext;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/EnableAdbPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/EnableAdbPreferenceControllerTest.java
index aac736a..475e7d8 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/EnableAdbPreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/EnableAdbPreferenceControllerTest.java
@@ -31,18 +31,15 @@
import android.support.v7.preference.PreferenceScreen;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class EnableAdbPreferenceControllerTest {
@Mock(answer = RETURNS_DEEP_STUBS)
private PreferenceScreen mScreen;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/LogdSizePreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/LogdSizePreferenceControllerTest.java
index 26d3570..72c8d1ad36 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/LogdSizePreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/LogdSizePreferenceControllerTest.java
@@ -45,20 +45,15 @@
import com.android.settingslib.R;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
- shadows = SystemPropertiesTestImpl.class)
public class LogdSizePreferenceControllerTest {
@Mock
@@ -95,11 +90,6 @@
mController.displayPreference(mPreferenceScreen);
}
- @After
- public void tearDown() {
- SystemPropertiesTestImpl.clear();
- }
-
@Test
public void testUpdateLogdSizeValues_lowRamEntries() {
SystemProperties.set(LOW_RAM_CONFIG_PROPERTY_KEY, "true");
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/LogpersistPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/LogpersistPreferenceControllerTest.java
index 050877d..4b9bfc3 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/LogpersistPreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/LogpersistPreferenceControllerTest.java
@@ -28,7 +28,6 @@
import android.support.v7.preference.PreferenceScreen;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
@@ -37,11 +36,8 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
- shadows = SystemPropertiesTestImpl.class)
public class LogpersistPreferenceControllerTest {
private LifecycleOwner mLifecycleOwner;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/SystemPropPokerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/SystemPropPokerTest.java
index fa7961b..40db478 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/SystemPropPokerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/SystemPropPokerTest.java
@@ -20,7 +20,6 @@
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -29,7 +28,6 @@
import android.os.Parcel;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import org.junit.Before;
import org.junit.Test;
@@ -37,10 +35,8 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
-import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SystemPropPokerTest {
@Spy
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/SystemPropertiesTestImpl.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/SystemPropertiesTestImpl.java
deleted file mode 100644
index 6977e09..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/SystemPropertiesTestImpl.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settingslib.development;
-
-import android.text.TextUtils;
-import android.util.ArrayMap;
-
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.shadows.ShadowSystemProperties;
-
-import java.util.Map;
-
-@Implements(className = "android.os.SystemProperties")
-public class SystemPropertiesTestImpl extends ShadowSystemProperties {
-
- private static Map<String, String> sProperties = new ArrayMap<>();
-
- @Implementation
- public static String get(String key) {
- String value = sProperties.get(key);
- if (!TextUtils.isEmpty(value)) {
- return value;
- } else {
- return ShadowSystemProperties.get(key);
- }
- }
-
- @Implementation
- public static String get(String key, String def) {
- String value = sProperties.get(key);
- if (!TextUtils.isEmpty(value)) {
- return value;
- } else {
- return ShadowSystemProperties.get(key, def);
- }
- }
-
- @Implementation
- public static void set(String key, String val) {
- sProperties.put(key, val);
- }
-
- public static synchronized void clear() {
- sProperties.clear();
- }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/BluetoothAddressPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/BluetoothAddressPreferenceControllerTest.java
index 1de7a7a..0385f4b 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/BluetoothAddressPreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/BluetoothAddressPreferenceControllerTest.java
@@ -26,7 +26,6 @@
import android.support.v7.preference.PreferenceScreen;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
@@ -39,7 +38,6 @@
import org.robolectric.annotation.Implements;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class BluetoothAddressPreferenceControllerTest {
@Mock
private Context mContext;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/ConnectivityPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/ConnectivityPreferenceControllerTest.java
index 362dbd9..7c127e5 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/ConnectivityPreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/ConnectivityPreferenceControllerTest.java
@@ -17,7 +17,6 @@
package com.android.settingslib.deviceinfo;
import static com.google.common.truth.Truth.assertWithMessage;
-
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doReturn;
@@ -31,7 +30,6 @@
import android.os.Handler;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
@@ -40,10 +38,8 @@
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class ConnectivityPreferenceControllerTest {
@Mock
private Context mContext;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/ImsStatusPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/ImsStatusPreferenceControllerTest.java
index 112ee64..d600c20 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/ImsStatusPreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/ImsStatusPreferenceControllerTest.java
@@ -17,7 +17,6 @@
package com.android.settingslib.deviceinfo;
import static com.google.common.truth.Truth.assertWithMessage;
-
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -30,7 +29,6 @@
import android.telephony.SubscriptionManager;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
@@ -43,7 +41,6 @@
import org.robolectric.annotation.Implements;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class ImsStatusPreferenceControllerTest {
@Mock
private Context mContext;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java
index d0ecae3..99e582c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java
@@ -27,7 +27,6 @@
import android.support.v7.preference.PreferenceScreen;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
@@ -35,13 +34,11 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
import java.util.Arrays;
import java.util.List;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class IpAddressPreferenceControllerTest {
@Mock
private Context mContext;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/SerialNumberPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/SerialNumberPreferenceControllerTest.java
index 34bbf4f..a4fa7aa 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/SerialNumberPreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/SerialNumberPreferenceControllerTest.java
@@ -24,7 +24,6 @@
import android.support.v7.preference.PreferenceScreen;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import org.junit.Before;
import org.junit.Test;
@@ -32,10 +31,8 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SerialNumberPreferenceControllerTest {
@Mock
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/SimStatusImeiInfoPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/SimStatusImeiInfoPreferenceControllerTest.java
index 28409fa..eaae405 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/SimStatusImeiInfoPreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/SimStatusImeiInfoPreferenceControllerTest.java
@@ -17,7 +17,6 @@
package com.android.settingslib.deviceinfo;
import static com.google.common.truth.Truth.assertThat;
-
import static org.robolectric.shadow.api.Shadow.extract;
import android.net.ConnectivityManager;
@@ -25,7 +24,6 @@
import android.util.SparseBooleanArray;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import org.junit.Before;
import org.junit.Test;
@@ -36,8 +34,7 @@
import org.robolectric.annotation.Implements;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
- shadows = {SimStatusImeiInfoPreferenceControllerTest.ShadowUserManager.class,
+@Config(shadows = {SimStatusImeiInfoPreferenceControllerTest.ShadowUserManager.class,
SimStatusImeiInfoPreferenceControllerTest.ShadowConnectivityManager.class})
public class SimStatusImeiInfoPreferenceControllerTest {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/UptimePreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/UptimePreferenceControllerTest.java
index f68533b..39e05fa 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/UptimePreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/UptimePreferenceControllerTest.java
@@ -28,7 +28,6 @@
import android.text.format.DateUtils;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
@@ -36,11 +35,9 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowLooper;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class UptimePreferenceControllerTest {
@Mock
private Context mContext;
@@ -98,5 +95,4 @@
super(context, lifecycle);
}
}
-
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java
index 265a60b..d546f11 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java
@@ -17,7 +17,6 @@
package com.android.settingslib.deviceinfo;
import static com.google.common.truth.Truth.assertWithMessage;
-
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -32,7 +31,6 @@
import com.android.settingslib.R;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
@@ -40,14 +38,12 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
import java.util.Arrays;
import java.util.List;
@SuppressLint("HardwareIds")
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class WifiMacAddressPreferenceControllerTest {
@Mock
private Context mContext;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
index 6be44cc..b90f37a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
@@ -16,21 +16,17 @@
package com.android.settingslib.drawer;
-import android.util.ArraySet;
+import static com.google.common.truth.Truth.assertThat;
-import com.android.settingslib.TestConfig;
+import android.util.ArraySet;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
import java.util.Set;
-import static com.google.common.truth.Truth.assertThat;
-
@RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class CategoryKeyTest {
@Test
@@ -64,5 +60,4 @@
assertThat(allKeys.size()).isEqualTo(15);
}
-
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryManagerTest.java
index f099c90..4efcb7e 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryManagerTest.java
@@ -16,27 +16,24 @@
package com.android.settingslib.drawer;
+import static com.google.common.truth.Truth.assertThat;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.util.Pair;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
import java.util.HashMap;
import java.util.Map;
-import static com.google.common.truth.Truth.assertThat;
-
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class CategoryManagerTest {
private Context mContext;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
index a395a4a..fc1b2238 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
@@ -17,7 +17,6 @@
package com.android.settingslib.drawer;
import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
@@ -54,7 +53,6 @@
import android.widget.RemoteViews;
import com.android.settingslib.R;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.suggestions.SuggestionParser;
import org.junit.Before;
@@ -74,9 +72,7 @@
import java.util.Map;
@RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH,
- sdk = TestConfig.SDK_VERSION,
- shadows = {TileUtilsTest.TileUtilsShadowRemoteViews.class})
+@Config(shadows = TileUtilsTest.TileUtilsShadowRemoteViews.class)
public class TileUtilsTest {
private Context mContext;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java
index fc0019d..c6a1428 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java
@@ -17,7 +17,6 @@
package com.android.settingslib.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doNothing;
@@ -27,17 +26,14 @@
import android.os.IDeviceIdleController;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class PowerWhitelistBackendTest {
private static final String PACKAGE_ONE = "com.example.packageone";
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
index e022232..49dde0e 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
@@ -26,8 +26,6 @@
import android.graphics.Paint;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
-import com.android.settingslib.testutils.shadow.SettingsLibShadowResources;
import org.junit.Before;
import org.junit.Test;
@@ -35,12 +33,9 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
- shadows = SettingsLibShadowResources.class)
public class BatteryMeterDrawableBaseTest {
private static final int CRITICAL_LEVEL = 5;
private static final int PADDING = 5;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BluetoothDeviceLayerDrawableTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BluetoothDeviceLayerDrawableTest.java
index 94f80d3..37d4d1d 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BluetoothDeviceLayerDrawableTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BluetoothDeviceLayerDrawableTest.java
@@ -19,23 +19,17 @@
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
-import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.VectorDrawable;
import com.android.settingslib.R;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
-import com.android.settingslib.testutils.shadow.SettingsLibShadowResources;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
- shadows = SettingsLibShadowResources.class)
public class BluetoothDeviceLayerDrawableTest {
private static final int RES_ID = R.drawable.ic_bt_cellphone;
private static final int BATTERY_LEVEL = 15;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java
index c7e9262..96b2a14 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java
@@ -18,12 +18,10 @@
import static com.google.common.truth.Truth.assertThat;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.annotation.Config;
import org.xmlpull.v1.XmlPullParserException;
import java.io.ByteArrayInputStream;
@@ -35,7 +33,6 @@
import java.util.Map;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class LicenseHtmlGeneratorFromXmlTest {
private static final String VALILD_XML_STRING =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlLoaderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlLoaderTest.java
index 1a6f30c..5095f50 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlLoaderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlLoaderTest.java
@@ -17,7 +17,6 @@
package com.android.settingslib.license;
import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
@@ -26,7 +25,6 @@
import android.content.Context;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
import org.junit.Before;
@@ -34,13 +32,11 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
import java.io.File;
import java.util.ArrayList;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class LicenseHtmlLoaderTest {
@Mock
private Context mContext;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java
index 226166b..5e0fcef 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java
@@ -1,8 +1,8 @@
package com.android.settingslib.location;
+import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.isA;
import static org.mockito.Mockito.when;
-import static com.google.common.truth.Truth.assertThat;
import android.app.AppOpsManager;
import android.app.AppOpsManager.OpEntry;
@@ -15,23 +15,21 @@
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
+
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(
- manifest = TestConfig.MANIFEST_PATH,
- sdk = TestConfig.SDK_VERSION)
public class RecentLocationAppsTest {
private static final int TEST_UID = 1234;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/EnableZenModeDialogTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/EnableZenModeDialogTest.java
index 777cd98..9b5da4a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/EnableZenModeDialogTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/EnableZenModeDialogTest.java
@@ -18,21 +18,18 @@
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
-
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
-import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.net.Uri;
import android.service.notification.Condition;
import android.view.LayoutInflater;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
import org.junit.Before;
@@ -41,10 +38,8 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class EnableZenModeDialogTest {
private EnableZenModeDialog mController;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionControllerMixinTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionControllerMixinTest.java
index ed1c405..cfa16b8 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionControllerMixinTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionControllerMixinTest.java
@@ -18,9 +18,7 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_START;
import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
-
import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -30,7 +28,6 @@
import android.content.ComponentName;
import android.content.Context;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -44,10 +41,7 @@
import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
- shadows = {
- ShadowSuggestionController.class
- })
+@Config(shadows = ShadowSuggestionController.class)
public class SuggestionControllerMixinTest {
@Mock
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java
index db599a7..d05bcfd 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java
@@ -17,11 +17,9 @@
package com.android.settingslib.suggestions;
import static com.google.common.truth.Truth.assertThat;
-
import static org.robolectric.RuntimeEnvironment.application;
import static org.robolectric.shadow.api.Shadow.extract;
-import android.app.ApplicationPackageManager;
import android.content.ComponentName;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -30,28 +28,22 @@
import android.preference.PreferenceManager;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.drawer.TileUtilsTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.annotation.Config;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.shadows.ShadowApplicationPackageManager;
+import org.robolectric.shadows.ShadowPackageManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
- shadows = SuggestionParserTest.TestPackageManager.class)
public class SuggestionParserTest {
- private TestPackageManager mPackageManager;
+ private ShadowPackageManager mPackageManager;
private SuggestionParser mSuggestionParser;
private SuggestionCategory mMultipleCategory;
private SuggestionCategory mExclusiveCategory;
@@ -205,13 +197,4 @@
mSuggestionParser.readSuggestions(
mMultipleCategory, mSuggestionsAfterDismiss, isSmartSuggestionEnabled);
}
-
- @Implements(ApplicationPackageManager.class)
- public static class TestPackageManager extends ShadowApplicationPackageManager {
-
- @Implementation
- public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
- return super.queryIntentActivities(intent, flags);
- }
- }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/SettingsLibShadowResources.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/SettingsLibShadowResources.java
deleted file mode 100644
index b53cc37..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/SettingsLibShadowResources.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settingslib.testutils.shadow;
-
-import static org.robolectric.shadow.api.Shadow.directlyOn;
-
-import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
-import android.support.annotation.ArrayRes;
-
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.annotation.RealObject;
-import org.robolectric.shadows.ShadowResources;
-
-/**
- * Shadow Resources to handle resource references that Robolectric shadows cannot
- * handle because they are too new or private.
- */
-@Implements(Resources.class)
-public class SettingsLibShadowResources extends ShadowResources {
-
- @RealObject
- public Resources realResources;
-
- @Implementation
- public int[] getIntArray(@ArrayRes int id) throws NotFoundException {
- // The Robolectric has resource mismatch for these values, so we need to stub it here
- if (id == com.android.settingslib.R.array.batterymeter_bolt_points
- || id == com.android.settingslib.R.array.batterymeter_plus_points) {
- return new int[2];
- }
- return directlyOn(realResources, Resources.class).getIntArray(id);
- }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowPackageManagerWrapper.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowPackageManagerWrapper.java
deleted file mode 100644
index 1fdca27..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowPackageManagerWrapper.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settingslib.testutils.shadow;
-
-import android.content.Intent;
-import android.content.pm.ResolveInfo;
-import android.util.ArrayMap;
-
-import com.android.settingslib.wrapper.PackageManagerWrapper;
-
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Shadow for {@link PackageManagerWrapper} to allow stubbing hidden methods.
- */
-@Implements(PackageManagerWrapper.class)
-public class ShadowPackageManagerWrapper {
- private static final Map<Intent, List<ResolveInfo>> intentServices = new ArrayMap<>();
-
- @Implementation
- public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int i, int user) {
- List<ResolveInfo> list = intentServices.get(intent);
- return list != null ? list : Collections.emptyList();
- }
-
- public static void addResolveInfoForIntent(Intent intent, ResolveInfo info) {
- List<ResolveInfo> infoList = intentServices.computeIfAbsent(intent, k -> new ArrayList<>());
- infoList.add(info);
- }
-
- public static void reset() {
- intentServices.clear();
- }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowUserManager.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowUserManager.java
index c8b3269..a3e1bc8 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowUserManager.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowUserManager.java
@@ -25,7 +25,7 @@
import org.robolectric.annotation.Resetter;
import org.robolectric.shadow.api.Shadow;
-@Implements(UserManager.class)
+@Implements(value = UserManager.class, inheritImplementationMethods = true)
public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager {
private boolean mAdminUser;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java
index f93210f..9285148f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java
@@ -20,20 +20,19 @@
import static org.mockito.Mockito.spy;
import android.content.Context;
+
import com.android.settingslib.R;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
-import com.android.settingslib.utils.PowerUtil;
-import java.time.Duration;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
+
+import java.time.Duration;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class PowerUtilTest {
public static final String TEST_BATTERY_LEVEL_10 = "10%";
public static final String FIFTEEN_MIN_FORMATTED = "15m";
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/StringUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/StringUtilTest.java
index d5e3cdb..47dd022 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/StringUtilTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/StringUtilTest.java
@@ -23,16 +23,15 @@
import android.text.SpannableStringBuilder;
import android.text.format.DateUtils;
import android.text.style.TtsSpan;
+
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class StringUtilTest {
private Context mContext;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/ThreadUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/ThreadUtilsTest.java
index 5f6a5c8..83a9d5b 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/ThreadUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/ThreadUtilsTest.java
@@ -19,16 +19,12 @@
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
-import com.android.settingslib.TestConfig;
-
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowLooper;
@RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class ThreadUtilsTest {
@Test
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AnimatedImageViewTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AnimatedImageViewTest.java
index 2c9c868..36abd20 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AnimatedImageViewTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AnimatedImageViewTest.java
@@ -16,21 +16,19 @@
package com.android.settingslib.widget;
+import static com.google.common.truth.Truth.assertThat;
+
import android.app.Activity;
import android.graphics.drawable.AnimatedRotateDrawable;
import android.view.View;
-import com.android.settingslib.TestConfig;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import static com.google.common.truth.Truth.assertThat;
@RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class AnimatedImageViewTest {
private AnimatedImageView mAnimatedImageView;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceMixinTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceMixinTest.java
index 88c57b5..8071c6db 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceMixinTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceMixinTest.java
@@ -29,7 +29,6 @@
import android.support.v7.preference.PreferenceScreen;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
@@ -37,11 +36,9 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class FooterPreferenceMixinTest {
@Mock
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java
index 5d01027..ff11b80 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java
@@ -16,6 +16,8 @@
package com.android.settingslib.widget;
+import static com.google.common.truth.Truth.assertThat;
+
import android.content.Context;
import android.support.v7.preference.PreferenceViewHolder;
import android.text.method.LinkMovementMethod;
@@ -24,18 +26,13 @@
import com.android.settingslib.R;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
-import static com.google.common.truth.Truth.assertThat;
-
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class FooterPreferenceTest {
private Context mContext;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/AccessPointPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/AccessPointPreferenceTest.java
index 3fee16b..ee2c2ff 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/AccessPointPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/AccessPointPreferenceTest.java
@@ -25,7 +25,6 @@
import android.graphics.drawable.ColorDrawable;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import org.junit.Before;
import org.junit.Test;
@@ -33,10 +32,8 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class AccessPointPreferenceTest {
private Context mContext = RuntimeEnvironment.application;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/TimestampedScoredNetworkTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/TimestampedScoredNetworkTest.java
index b2d9d67b..f0e8c66 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/TimestampedScoredNetworkTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/TimestampedScoredNetworkTest.java
@@ -23,16 +23,14 @@
import android.os.Parcel;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
-import java.util.Date;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
+
+import java.util.Date;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class TimestampedScoredNetworkTest {
private TimestampedScoredNetwork impl;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java
index 9310b73..ea8ecba 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java
@@ -16,7 +16,6 @@
package com.android.settingslib.wifi;
import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.when;
@@ -35,7 +34,6 @@
import com.android.settingslib.R;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.TestConfig;
import org.junit.Before;
import org.junit.Test;
@@ -43,12 +41,10 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
import java.util.ArrayList;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class WifiUtilsTest {
private static final String TEST_SSID = "\"test_ssid\"";
private static final String TEST_BSSID = "00:00:00:00:00:00";
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 4d49899..5c8d745 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -44,7 +44,6 @@
<uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
<uses-permission android:name="android.permission.MANAGE_USB" />
<uses-permission android:name="android.permission.USE_RESERVED_DISK" />
- <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!-- System tool permissions granted to the shell. -->
<uses-permission android:name="android.permission.REAL_GET_TASKS" />
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index cbb3e8f..35c4d59 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -110,7 +110,7 @@
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<!-- Keyguard -->
- <uses-permission android:name="com.android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" />
+ <uses-permission android:name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" />
<uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
@@ -381,6 +381,12 @@
android:finishOnCloseSystemDialogs="true"
android:excludeFromRecents="true">
</activity>
+ <activity-alias
+ android:name=".UsbDebuggingActivityAlias"
+ android:permission="android.permission.DUMP"
+ android:targetActivity=".usb.UsbDebuggingActivity"
+ android:exported="true">
+ </activity-alias>
<activity android:name=".usb.UsbDebuggingSecondaryUserActivity"
android:theme="@style/Theme.SystemUI.Dialog.Alert"
android:finishOnCloseSystemDialogs="true"
diff --git a/packages/SystemUI/res-keyguard/values-da/strings.xml b/packages/SystemUI/res-keyguard/values-da/strings.xml
index 156da2e..d9075aa 100644
--- a/packages/SystemUI/res-keyguard/values-da/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-da/strings.xml
@@ -53,6 +53,8 @@
<string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Næste alarm er indstillet til <xliff:g id="ALARM">%1$s</xliff:g>"</string>
<string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Slet"</string>
<string name="disable_carrier_button_text" msgid="6914341927421916114">"Deaktiver eSIM"</string>
+ <string name="error_disable_esim_title" msgid="4852978431156228006">"eSIM kan ikke deaktiveres"</string>
+ <string name="error_disable_esim_msg" msgid="676694908770135639">"eSIM kan ikke deaktiveres på grund af en fejl."</string>
<string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
<string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Har du glemt mønsteret?"</string>
<string name="kg_wrong_pattern" msgid="7620081431514773802">"Forkert mønster"</string>
@@ -65,7 +67,7 @@
<string name="kg_pattern_instructions" msgid="5547646893001491340">"Tegn dit mønster"</string>
<string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Angiv pinkoden til SIM-kortet."</string>
<string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Angiv pinkoden til SIM-kortet fra \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
- <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Deaktiver eSIM for at bruge enheden uden mobiltjeneste."</string>
+ <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Deaktiver eSIM for at bruge enheden uden mobiltjeneste."</string>
<string name="kg_pin_instructions" msgid="4069609316644030034">"Indtast pinkode"</string>
<string name="kg_password_instructions" msgid="136952397352976538">"Angiv adgangskode"</string>
<string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-kortet er nu deaktiveret. Indtast PUK-koden for at fortsætte. Kontakt mobilselskabet for at få flere oplysninger."</string>
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index 3d79ae2..a5aa06e 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -53,6 +53,8 @@
<string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Hurrengo alarmak ordu honetan joko du: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
<string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Ezabatu"</string>
<string name="disable_carrier_button_text" msgid="6914341927421916114">"Desgaitu eSIM txartela"</string>
+ <string name="error_disable_esim_title" msgid="4852978431156228006">"Ezin da desgaitu eSIM txartela"</string>
+ <string name="error_disable_esim_msg" msgid="676694908770135639">"Errore bat gertatu da eta ezin da desgaitu eSIM txartela."</string>
<string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Sartu"</string>
<string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Eredua ahaztu zaizu"</string>
<string name="kg_wrong_pattern" msgid="7620081431514773802">"Eredu hori ez da zuzena"</string>
@@ -65,7 +67,7 @@
<string name="kg_pattern_instructions" msgid="5547646893001491340">"Marraztu eredua"</string>
<string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Idatzi SIM txartelaren PIN kodea."</string>
<string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Idatzi \"<xliff:g id="CARRIER">%1$s</xliff:g>\" operadorearen SIM txartelaren PIN kodea."</string>
- <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Desgaitu eSIM txartela gailua zerbitzu mugikorrik gabe erabiltzeko."</string>
+ <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Desgaitu eSIM txartela gailua zerbitzu mugikorrik gabe erabiltzeko."</string>
<string name="kg_pin_instructions" msgid="4069609316644030034">"Idatzi PIN kodea"</string>
<string name="kg_password_instructions" msgid="136952397352976538">"Idatzi pasahitza"</string>
<string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Desgaitu egin da SIM txartela. Aurrera egiteko, idatzi PUK kodea. Xehetasunak lortzeko, jarri operadorearekin harremanetan."</string>
diff --git a/packages/SystemUI/res-keyguard/values-hy/strings.xml b/packages/SystemUI/res-keyguard/values-hy/strings.xml
index 2936935..fec903e 100644
--- a/packages/SystemUI/res-keyguard/values-hy/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hy/strings.xml
@@ -53,6 +53,8 @@
<string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Հաջորդ զարթուցիչը դրված է <xliff:g id="ALARM">%1$s</xliff:g>-ի վրա"</string>
<string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Ջնջել"</string>
<string name="disable_carrier_button_text" msgid="6914341927421916114">"Անջատել էլեկտրոնային SIM քարտը"</string>
+ <string name="error_disable_esim_title" msgid="4852978431156228006">"Չհաջողվեց անջատել eSIM-ը"</string>
+ <string name="error_disable_esim_msg" msgid="676694908770135639">"Սխալի պատճառով չհաջողվեց անջատել eSIM-ը։"</string>
<string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Մուտքի ստեղն"</string>
<string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Մոռացել եմ նախշը"</string>
<string name="kg_wrong_pattern" msgid="7620081431514773802">"Նախշը սխալ է"</string>
@@ -65,7 +67,7 @@
<string name="kg_pattern_instructions" msgid="5547646893001491340">"Մուտքագրեք նախշը"</string>
<string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Մուտքագրեք SIM քարտի PIN կոդը։"</string>
<string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Մուտքագրեք SIM քարտի PIN կոդը «<xliff:g id="CARRIER">%1$s</xliff:g>»-ի համար:"</string>
- <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Անջատել էլեկտրոնային SIM քարտը՝ սարքն առանց բջջային ծառայությունների օգտագործելու համար:"</string>
+ <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Անջատեք eSIM-ը՝ սարքն առանց բջջային կապի օգտագործելու համար։"</string>
<string name="kg_pin_instructions" msgid="4069609316644030034">"Մուտքագրեք PIN-ը"</string>
<string name="kg_password_instructions" msgid="136952397352976538">"Մուտքագրեք գաղտնաբառը"</string>
<string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM քարտն այժմ անջատված է: Շարունակելու համար մուտքագրեք PUK կոդը: Մանրամասն տեղեկություններ ստանալու համար դիմեք օպերատորին:"</string>
diff --git a/packages/SystemUI/res-keyguard/values-uz/strings.xml b/packages/SystemUI/res-keyguard/values-uz/strings.xml
index 3272cb2..07198c7c 100644
--- a/packages/SystemUI/res-keyguard/values-uz/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uz/strings.xml
@@ -53,10 +53,8 @@
<string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Signal <xliff:g id="ALARM">%1$s</xliff:g> da chalinadi."</string>
<string name="keyboardview_keycode_delete" msgid="6883116827512721630">"O‘chirib tashlash"</string>
<string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIMni faolsizlantirish"</string>
- <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
- <skip />
- <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
- <skip />
+ <string name="error_disable_esim_title" msgid="4852978431156228006">"eSIM faolsizlantirilmadi"</string>
+ <string name="error_disable_esim_msg" msgid="676694908770135639">"Xatolik tufayli eSIM faolsizlantirilmadi."</string>
<string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter tugmasi"</string>
<string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Grafik kalit esimdan chiqdi"</string>
<string name="kg_wrong_pattern" msgid="7620081431514773802">"Grafik kalit xato"</string>
@@ -69,8 +67,7 @@
<string name="kg_pattern_instructions" msgid="5547646893001491340">"Grafik kalit chizing"</string>
<string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM karta PIN kodini kiriting."</string>
<string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"“<xliff:g id="CARRIER">%1$s</xliff:g>” SIM kartasi PIN kodini kiriting."</string>
- <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
- <skip />
+ <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Qurilmadan mobil xizmatlarsiz foydalanish uchun eSIMni faolsizlantiring."</string>
<string name="kg_pin_instructions" msgid="4069609316644030034">"PIN kodni kiriting"</string>
<string name="kg_password_instructions" msgid="136952397352976538">"Parol kiriting"</string>
<string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM karta hozir o‘chirilgan. Davom etish uchun PUK kodni kiriting. Batafsil axborot olish uchun tarmoq operatori bilan bog‘laning."</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 39895acb..9ebd492 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -103,12 +103,9 @@
<string name="camera_label" msgid="7261107956054836961">"åbn kamera"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Vælg nyt opgavelayout"</string>
<string name="cancel" msgid="6442560571259935130">"Annuller"</string>
- <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
- <skip />
- <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
- <skip />
- <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
- <skip />
+ <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon for fingeraftryk"</string>
+ <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Appens ikon"</string>
+ <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Område med hjælpemeddelelse"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Knap for kompatibilitetszoom."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom mindre til større skærm."</string>
<string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth tilsluttet."</string>
@@ -311,6 +308,7 @@
<string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi slået fra"</string>
<string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi er slået til"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Der er ingen tilgængelige Wi-Fi-netværk"</string>
+ <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarm"</string>
<string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
<string name="quick_settings_casting" msgid="6601710681033353316">"Caster"</string>
<string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Enhed uden navn"</string>
@@ -327,9 +325,11 @@
<string name="quick_settings_connecting" msgid="47623027419264404">"Opretter forbindelse…"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Netdeling"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
- <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
- <skip />
- <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+ <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Aktiverer…"</string>
+ <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+ <item quantity="one">%d enhed</item>
+ <item quantity="other">%d enheder</item>
+ </plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Underretninger"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lommelygte"</string>
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobildata"</string>
@@ -339,10 +339,8 @@
<string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> brugt"</string>
<string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Grænse: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Advarsel ved <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
- <skip />
- <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
- <skip />
+ <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Arbejdsprofil"</string>
+ <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Underretninger og apps er slået fra"</string>
<string name="quick_settings_night_display_label" msgid="3577098011487644395">"Nattelys"</string>
<string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Tænd ved solnedgang"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Indtil solopgang"</string>
@@ -360,8 +358,6 @@
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> er deaktiveret i sikker tilstand."</string>
<string name="recents_stack_action_button_label" msgid="6593727103310426253">"Ryd alle"</string>
<string name="recents_drag_hint_message" msgid="2649739267073203985">"Træk hertil for at bruge delt skærm"</string>
- <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
- <skip />
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Opdel vandret"</string>
<string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Opdel lodret"</string>
<string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Opdel brugerdefineret"</string>
@@ -502,11 +498,18 @@
<string name="volume_zen_end_now" msgid="6930243045593601084">"Deaktiver nu"</string>
<string name="accessibility_volume_expand" msgid="5946812790999244205">"Udvid"</string>
<string name="accessibility_volume_collapse" msgid="3609549593031810875">"Skjul"</string>
+ <string name="accessibility_output_chooser" msgid="8185317493017988680">"Skift enhed til lydudgang"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Skærmen er fastgjort"</string>
<string name="screen_pinning_description" msgid="8909878447196419623">"Dette fastholder skærmen i visningen, indtil du frigør den. Tryk på Tilbage og Overblik, og hold fingeren nede for at frigøre skærmen."</string>
+ <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Dette fastholder skærmen i visningen, indtil du frigør den. Hold Tilbage og Startskærm nede for at frigøre skærmen."</string>
<string name="screen_pinning_description_accessible" msgid="426190689254018656">"Dette fastholder skærmen i visningen, indtil du frigør den. Tryk på Tilbage, og hold fingeren nede for at frigøre skærmen."</string>
+ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Dette fastholder skærmen i visningen, indtil du frigør den. Hold Startskærm nede for at frigøre skærmen."</string>
+ <string name="screen_pinning_toast" msgid="2266705122951934150">"Hold knapperne Tilbage og Oversigt nede for at frigøre skærmen"</string>
+ <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Hold knapperne Tilbage og Startskærm nede for at frigøre skærmen"</string>
<string name="screen_pinning_positive" msgid="3783985798366751226">"OK, det er forstået"</string>
<string name="screen_pinning_negative" msgid="3741602308343880268">"Nej tak"</string>
+ <string name="screen_pinning_start" msgid="1022122128489278317">"Skærmen blev fastgjort"</string>
+ <string name="screen_pinning_exit" msgid="5187339744262325372">"Skærmen blev frigjort"</string>
<string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Vil du skjule <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
<string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Den vises igen, næste gang du aktiverer den i indstillingerne."</string>
<string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Skjul"</string>
@@ -586,8 +589,7 @@
<string name="power_notification_controls_description" msgid="4372459941671353358">"Med kontrolelementer til underretninger om strøm kan du konfigurere et vigtighedsniveau fra 0 til 5 for en apps underretninger. \n\n"<b>"Niveau 5"</b>\n"- Vis øverst på listen over underretninger \n- Tillad afbrydelse af fuld skærm \n- Se altid smugkig \n\n"<b>"Niveau 4"</b>\n"- Ingen afbrydelse af fuld skærm \n- Se altid smugkig \n\n"<b>"Niveau 3"</b>\n"- Ingen afbrydelse af fuld skærm \n- Se aldrig smugkig \n\n"<b>"Niveau 2"</b>\n"- Ingen afbrydelse af fuld skærm \n Se aldrig smugkig \n- Ingen lyd og vibration \n\n"<b>"Niveau 1"</b>\n"- Ingen afbrydelse af fuld skærm \n- Se aldrig smugkig \n- Ingen lyd eller vibration \n- Skjul fra låseskærm og statusbjælke \n- Vis nederst på listen over underretninger \n\n"<b>"Niveau 0"</b>\n"- Bloker alle underretninger fra appen."</string>
<string name="notification_header_default_channel" msgid="7506845022070889909">"Underretninger"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Du får ikke længere vist disse underretninger"</string>
- <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
- <skip />
+ <string name="inline_blocking_helper" msgid="3055064577771478591">"Du afviser som regel disse underretninger. \nVil du blive ved med at se dem?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Vil du fortsætte med at se disse underretninger?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Stop underretninger"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Fortsæt med at vise underretninger"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 1c46eba..9b52656 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -103,12 +103,9 @@
<string name="camera_label" msgid="7261107956054836961">"ireki kamera"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Hautatu zereginen diseinua"</string>
<string name="cancel" msgid="6442560571259935130">"Utzi"</string>
- <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
- <skip />
- <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
- <skip />
- <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
- <skip />
+ <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Hatz-markaren ikonoa"</string>
+ <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Aplikazioaren ikonoa"</string>
+ <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Laguntza-mezuaren eremua"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Zoom-bateragarritasunaren botoia."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Handiagotu pantaila txikia."</string>
<string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetootha konektatuta."</string>
@@ -313,6 +310,7 @@
<string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi konexioa desaktibatuta"</string>
<string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Aktibatuta dago Wi-Fi konexioa"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Ez dago Wi-Fi sarerik erabilgarri"</string>
+ <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarma"</string>
<string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
<string name="quick_settings_casting" msgid="6601710681033353316">"Igortzen"</string>
<string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Izenik gabeko gailua"</string>
@@ -329,9 +327,11 @@
<string name="quick_settings_connecting" msgid="47623027419264404">"Konektatzen…"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Konexioa partekatzea"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Sare publikoa"</string>
- <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
- <skip />
- <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+ <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Aktibatzen…"</string>
+ <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+ <item quantity="other">%d gailu</item>
+ <item quantity="one">%d gailu</item>
+ </plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Jakinarazpenak"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Linterna"</string>
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Datu mugikorrak"</string>
@@ -341,10 +341,8 @@
<string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> erabilita"</string>
<string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Muga: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Abisua: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
- <skip />
- <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
- <skip />
+ <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Laneko profila"</string>
+ <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Jakinarazpenak eta aplikazioak desaktibatuta daude"</string>
<string name="quick_settings_night_display_label" msgid="3577098011487644395">"Gaueko argia"</string>
<string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Ilunabarrean"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Ilunabarrera arte"</string>
@@ -362,8 +360,6 @@
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> desgaituta dago modu seguruan."</string>
<string name="recents_stack_action_button_label" msgid="6593727103310426253">"Garbitu guztiak"</string>
<string name="recents_drag_hint_message" msgid="2649739267073203985">"Arrastatu hau pantaila zatitzeko"</string>
- <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
- <skip />
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Zatitze horizontala"</string>
<string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Zatitze bertikala"</string>
<string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Zatitze pertsonalizatua"</string>
@@ -504,11 +500,18 @@
<string name="volume_zen_end_now" msgid="6930243045593601084">"Desaktibatu"</string>
<string name="accessibility_volume_expand" msgid="5946812790999244205">"Zabaldu"</string>
<string name="accessibility_volume_collapse" msgid="3609549593031810875">"Tolestu"</string>
+ <string name="accessibility_output_chooser" msgid="8185317493017988680">"Aldatu irteerako gailua"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Pantaila ainguratuta dago"</string>
<string name="screen_pinning_description" msgid="8909878447196419623">"Horrela, ikusgai egongo da aingura kendu arte. Aingura kentzeko, eduki sakatuta \"Atzera\" eta \"Ikuspegi orokorra\" botoiak."</string>
+ <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Horrela, ikusgai egongo da aingura kendu arte. Aingura kentzeko, eduki sakatuta Atzera eta Hasiera botoiak."</string>
<string name="screen_pinning_description_accessible" msgid="426190689254018656">"Horrela, ikusgai egongo da aingura kendu arte. Aingura kentzeko, eduki sakatuta \"Ikuspegi orokorra\" botoia."</string>
+ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Horrela, ikusgai egongo da aingura kendu arte. Aingura kentzeko, eduki sakatuta Hasiera botoia."</string>
+ <string name="screen_pinning_toast" msgid="2266705122951934150">"Pantailari aingura kentzeko, eduki sakatuta Atzera eta Ikuspegi orokorra botoiak"</string>
+ <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Pantailari aingura kentzeko, eduki sakatuta Atzera eta Hasiera botoiak"</string>
<string name="screen_pinning_positive" msgid="3783985798366751226">"Ados"</string>
<string name="screen_pinning_negative" msgid="3741602308343880268">"Ez, eskerrik asko"</string>
+ <string name="screen_pinning_start" msgid="1022122128489278317">"Ainguratu da pantaila"</string>
+ <string name="screen_pinning_exit" msgid="5187339744262325372">"Kendu zaio aingura pantailari"</string>
<string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> ezkutatu nahi duzu?"</string>
<string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Ezarpenetan aktibatzen duzun hurrengoan agertuko da berriro."</string>
<string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ezkutatu"</string>
@@ -588,8 +591,7 @@
<string name="power_notification_controls_description" msgid="4372459941671353358">"Bateria-mailaren arabera jakinarazpenak kontrolatzeko aukerekin, 0 eta 5 bitarteko garrantzi-mailetan sailka ditzakezu aplikazioen jakinarazpenak. \n\n"<b>"5. maila"</b>" \n- Erakutsi jakinarazpenen zerrendaren goialdean. \n- Baimendu etetea pantaila osoko moduan zaudenean. \n- Agerrarazi beti jakinarazpenak. \n\n"<b>"4. maila"</b>" \n- Galarazi etetea pantaila osoko moduan zaudenean. \n- Agerrarazi beti jakinarazpenak. \n\n"<b>"3. maila"</b>" \n- Galarazi etetea pantaila osoko moduan zaudenean. \n- Ez agerrarazi jakinarazpenik inoiz. \n\n"<b>"2. maila"</b>" \n- Galarazi etetea pantaila osoko moduan zaudenean. \n- Ez agerrarazi jakinarazpenik inoiz. \n- Ez egin soinurik edo dardararik inoiz. \n\n"<b>"1. maila"</b>" \n- Galarazi etetea pantaila osoko moduan zaudenean. \n- Ez agerrarazi jakinarazpenik inoiz. \n- Ez egin soinurik edo dardararik inoiz. \n- Ezkutatu pantaila blokeatutik eta egoera-barratik. \n- Erakutsi jakinarazpenen zerrendaren behealdean. \n\n"<b>"0. maila"</b>" \n- Blokeatu aplikazioaren jakinarazpen guztiak."</string>
<string name="notification_header_default_channel" msgid="7506845022070889909">"Jakinarazpenak"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Aurrerantzean ez duzu ikusiko horrelako jakinarazpenik"</string>
- <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
- <skip />
+ <string name="inline_blocking_helper" msgid="3055064577771478591">"Baztertu egin ohi dituzu jakinarazpen hauek. \nHaiek erakusten jarraitzea nahi duzu?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Jakinarazpenak erakusten jarraitzea nahi duzu?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Blokeatu jakinarazpenak"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Jarraitu erakusten"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 56ca97c..fe8f6d5 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -310,8 +310,7 @@
<string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi désactivé"</string>
<string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi activé"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Aucun réseau Wi-Fi à proximité"</string>
- <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
- <skip />
+ <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarme"</string>
<string name="quick_settings_cast_title" msgid="7709016546426454729">"Diffuser"</string>
<string name="quick_settings_casting" msgid="6601710681033353316">"Diffusion"</string>
<string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Appareil sans nom"</string>
@@ -361,7 +360,6 @@
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> est désactivée en mode sans échec."</string>
<string name="recents_stack_action_button_label" msgid="6593727103310426253">"Effacer tout"</string>
<string name="recents_drag_hint_message" msgid="2649739267073203985">"Glissez l\'élément ici pour utiliser l\'écran partagé"</string>
- <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Balayez vers le haut pour changer d\'application"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Séparation horizontale"</string>
<string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Séparation verticale"</string>
<string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Séparation personnalisée"</string>
@@ -505,21 +503,15 @@
<string name="accessibility_output_chooser" msgid="8185317493017988680">"Changer d\'appareil de sortie"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"L\'écran est épinglé"</string>
<string name="screen_pinning_description" msgid="8909878447196419623">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez le doigt sur « Retour » et « Aperçu »."</string>
- <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
- <skip />
+ <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez le doigt sur les touches Retour et Accueil."</string>
<string name="screen_pinning_description_accessible" msgid="426190689254018656">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez le doigt sur « Aperçu »."</string>
- <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
- <skip />
- <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
- <skip />
- <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
- <skip />
+ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez le doigt sur la touche Accueil."</string>
+ <string name="screen_pinning_toast" msgid="2266705122951934150">"Pour annuler l\'épinglage de cet écran, maintenez le doigt sur les touches Retour et Aperçu."</string>
+ <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Pour annuler l\'épinglage de cet écran, maintenez le doigt sur les touches Retour et Accueil."</string>
<string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
<string name="screen_pinning_negative" msgid="3741602308343880268">"Non, merci"</string>
- <!-- no translation found for screen_pinning_start (1022122128489278317) -->
- <skip />
- <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
- <skip />
+ <string name="screen_pinning_start" msgid="1022122128489278317">"Écran épinglé"</string>
+ <string name="screen_pinning_exit" msgid="5187339744262325372">"Épinglage d\'écran annulé"</string>
<string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Masquer <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
<string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Cet élément réapparaîtra la prochaine fois que vous l\'activerez dans les paramètres."</string>
<string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Masquer"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 33d8821..5dc1dfa 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -103,12 +103,9 @@
<string name="camera_label" msgid="7261107956054836961">"բացել ֆոտոխցիկը"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Ընտրել առաջադրանքի նոր դասավորություն"</string>
<string name="cancel" msgid="6442560571259935130">"Չեղարկել"</string>
- <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
- <skip />
- <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
- <skip />
- <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
- <skip />
+ <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Մատնահետքի պատկերակ"</string>
+ <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Հավելվածի պատկերակ"</string>
+ <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Օգնության հաղորդագրության դաշտ"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Համատեղելիության խոշորացման կոճակը:"</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Դիտափոխել փոքրից ավելի մեծ էկրան:"</string>
<string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth-ը միացված է:"</string>
@@ -311,6 +308,7 @@
<string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi-ը անջատված է"</string>
<string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi-ը միացված է"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Հասանելի Wi-Fi ցանցեր չկան"</string>
+ <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Զարթուցիչ"</string>
<string name="quick_settings_cast_title" msgid="7709016546426454729">"Հեռարձակում"</string>
<string name="quick_settings_casting" msgid="6601710681033353316">"Հեռարձակում"</string>
<string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Անանուն սարք"</string>
@@ -327,9 +325,11 @@
<string name="quick_settings_connecting" msgid="47623027419264404">"Միանում է..."</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Մոդեմի ռեժիմ"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Թեժ կետ"</string>
- <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
- <skip />
- <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+ <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Միանում է..."</string>
+ <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+ <item quantity="one">%d սարք</item>
+ <item quantity="other">%d սարք</item>
+ </plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Ծանուցումներ"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Լապտեր"</string>
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Բջջային ինտերնետ"</string>
@@ -339,10 +339,8 @@
<string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Օգտագործված է՝ <xliff:g id="DATA_USED">%s</xliff:g>"</string>
<string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Սահմանաչափ՝ <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> զգուշացում"</string>
- <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
- <skip />
- <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
- <skip />
+ <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Աշխատանքային պրոֆիլ"</string>
+ <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Ծանուցումներն ու հավելվածներն անջատված են"</string>
<string name="quick_settings_night_display_label" msgid="3577098011487644395">"Գիշերային լույս"</string>
<string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Կմիացվի մայրամուտին"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Մինչև լուսաբաց"</string>
@@ -360,8 +358,6 @@
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> հավելվածը անվտանգ ռեժիմում անջատված է:"</string>
<string name="recents_stack_action_button_label" msgid="6593727103310426253">"Մաքրել բոլորը"</string>
<string name="recents_drag_hint_message" msgid="2649739267073203985">"Քաշեք այստեղ՝ էկրանի տրոհումն օգտագործելու համար"</string>
- <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
- <skip />
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Հորիզոնական տրոհում"</string>
<string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Ուղղահայաց տրոհում"</string>
<string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Հատուկ տրոհում"</string>
@@ -502,11 +498,18 @@
<string name="volume_zen_end_now" msgid="6930243045593601084">"Անջատել հիմա"</string>
<string name="accessibility_volume_expand" msgid="5946812790999244205">"Ընդարձակել"</string>
<string name="accessibility_volume_collapse" msgid="3609549593031810875">"Կոծկել"</string>
+ <string name="accessibility_output_chooser" msgid="8185317493017988680">"Փոխել արտածման սարքը"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Էկրանն ամրացված է"</string>
<string name="screen_pinning_description" msgid="8909878447196419623">"Էկրանը կմնա տեսադաշտում, մինչև այն ապամրացնեք: Ապամրացնելու համար հպեք և պահեք Հետ և Համատեսք կոճակները:"</string>
+ <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Էկրանը կցուցադրվի այնքան ժամանակ, մինչև որ չապամրացնեք այն: Ապամրացնելու համար հպեք և պահեք Հետ և գլխավոր էկրանի կոճակները:"</string>
<string name="screen_pinning_description_accessible" msgid="426190689254018656">"Էկրանը կմնա տեսադաշտում, մինչև այն ապամրացնեք: Ապամրացնելու համար հպեք և պահեք Համատեսք կոճակը:"</string>
+ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Էկրանը կցուցադրվի այնքան ժամանակ, մինչև որ չապամրացնեք այն: Ապամրացնելու համար հպեք և պահեք գլխավոր էկրանի կոճակը:"</string>
+ <string name="screen_pinning_toast" msgid="2266705122951934150">"Էկրանն ապամրացնելու համար հպեք և պահեք Հետ և Համատեսք կոճակները"</string>
+ <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Էկրանն ապամրացնելու համար հպեք և պահեք Հետ և գլխավոր էկրանի կոճակները"</string>
<string name="screen_pinning_positive" msgid="3783985798366751226">"Եղավ"</string>
<string name="screen_pinning_negative" msgid="3741602308343880268">"Ոչ"</string>
+ <string name="screen_pinning_start" msgid="1022122128489278317">"Էկրանն ամրացված է"</string>
+ <string name="screen_pinning_exit" msgid="5187339744262325372">"Էկրանն ապամրացված է"</string>
<string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Թաքցնե՞լ <xliff:g id="TILE_LABEL">%1$s</xliff:g>-ը:"</string>
<string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Այն դարձյալ կհայտնվի, երբ նորից միացնեք կարգավորումներում:"</string>
<string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Թաքցնել"</string>
@@ -586,8 +589,7 @@
<string name="power_notification_controls_description" msgid="4372459941671353358">"Ծանուցումների ընդլայնված կառավարման օգնությամբ կարող եք յուրաքանչյուր հավելվածի ծանուցումների համար նշանակել կարևորության աստիճան՝ 0-5 սահմաններում: \n\n"<b>"5-րդ աստիճան"</b>" \n- Ցուցադրել ծանուցումների ցանկի վերևում \n- Թույլատրել լիաէկրան ընդհատումները \n- Միշտ ցուցադրել կարճ ծանուցումները \n\n"<b>"4-րդ աստիճան"</b>" \n- Արգելել լիաէկրան ընդհատումները \n- Միշտ ցուցադրել կարճ ծանուցումները \n\n"<b>"3-րդ աստիճան"</b>" \n- Արգելել լիաէկրան ընդհատումները \n- Արգելել կարճ ծանուցումների ցուցադրումը \n\n"<b>"2-րդ աստիճան"</b>" \n- Արգելել լիաէկրան ընդհատումները \n- Արգելել կարճ ծանուցումների ցուցադրումը \n- Անջատել ձայնը և թրթռումը \n\n"<b>"1-ին աստիճան"</b>" \n- Արգելել լիաէկրան ընդհատումները \n- Արգելել կարճ ծանուցումների ցուցադրումը \n- Անջատել ձայնը և թրթռումը \n- Չցուցադրել կողպէկրանում և կարգավիճակի գոտում \n- Ցուցադրել ծանուցումների ցանկի ներքևում \n\n"<b>"0-րդ աստիճան"</b>\n"- Արգելափակել հավելվածի բոլոր ծանուցումները"</string>
<string name="notification_header_default_channel" msgid="7506845022070889909">"Ծանուցումներ"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Դուք այլևս չեք ստանա այս ծանուցումները"</string>
- <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
- <skip />
+ <string name="inline_blocking_helper" msgid="3055064577771478591">"Դուք սովորաբար փակում եք այս ծանուցումները: \nՇարունակե՞լ ցուցադրել դրանք:"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Ցուցադրե՞լ այս ծանուցումները։"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Չցուցադրել ծանուցումներ"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Ցուցադրել"</string>
@@ -766,7 +768,7 @@
<string name="pip_skip_to_prev" msgid="1955311326688637914">"Վերադառնալ նախորդին"</string>
<string name="thermal_shutdown_title" msgid="4458304833443861111">"Հեռախոսն անջատվել է տաքանալու պատճառով"</string>
<string name="thermal_shutdown_message" msgid="9006456746902370523">"Հեռախոսն այժմ նորմալ աշխատում է"</string>
- <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"Ձեր հեռախոսը չափազանց տաք էր, այդ պատճառով այն անջատվել է՝ սառելու համար: Հեռախոսն այժմ նորմալ աշխատում է:\n\nՀեռախոսը կարող է տաքանալ, եթե՝\n • Օգտագործում եք ռեսուրսատար հավելվածներ (օրինակ՝ խաղեր, տեսանյութեր կամ նավարկման հավելվածներ)\n • Ներբեռնում կամ վերբեռնում եք ծանր ֆայլեր\n • Օգտագործում եք ձեր հեռախոսը բարձր ջերմային պայմաններում"</string>
+ <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"Ձեր հեռախոսը չափազանց տաք էր, այդ պատճառով այն անջատվել է՝ հովանալու համար: Հեռախոսն այժմ նորմալ աշխատում է:\n\nՀեռախոսը կարող է տաքանալ, եթե՝\n • Օգտագործում եք ռեսուրսատար հավելվածներ (օրինակ՝ խաղեր, տեսանյութեր կամ նավարկման հավելվածներ)\n • Ներբեռնում կամ վերբեռնում եք ծանր ֆայլեր\n • Օգտագործում եք ձեր հեռախոսը բարձր ջերմային պայմաններում"</string>
<string name="high_temp_title" msgid="4589508026407318374">"Հեռախոսը տաքանում է"</string>
<string name="high_temp_notif_message" msgid="5642466103153429279">"Հովանալու ընթացքում հեռախոսի որոշ գործառույթներ սահմանափակ են"</string>
<string name="high_temp_dialog_message" msgid="6840700639374113553">"Ձեր հեռախոսն ավտոմատ կերպով կփորձի hովանալ: Կարող եք շարունակել օգտագործել հեռախոսը, սակայն հնարավոր է, որ այն ավելի դանդաղ աշխատի:\n\nՀովանալուց հետո հեռախոսը կաշխատի կանոնավոր կերպով:"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 37d8118..0279d16 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -310,8 +310,7 @@
<string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi o‘chiq"</string>
<string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi yoqilgan"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Hech qanday Wi-Fi tarmog‘i mavjud emas"</string>
- <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
- <skip />
+ <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Signal"</string>
<string name="quick_settings_cast_title" msgid="7709016546426454729">"Translatsiya"</string>
<string name="quick_settings_casting" msgid="6601710681033353316">"Translatsiya qilinmoqda"</string>
<string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Nomsiz qurilma"</string>
@@ -361,7 +360,6 @@
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Xavfsiz rejimda <xliff:g id="APP">%s</xliff:g> ilovasi o‘chirib qo‘yildi."</string>
<string name="recents_stack_action_button_label" msgid="6593727103310426253">"Hammasini tozalash"</string>
<string name="recents_drag_hint_message" msgid="2649739267073203985">"Ekranni bo‘lish xususiyatidan foydalanish uchun bu yerga torting"</string>
- <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Ilovalarni almashtirish uchun ekranni tepaga suring"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Gorizontal yo‘nalishda bo‘lish"</string>
<string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Vertikal yo‘nalishda bo‘lish"</string>
<string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Boshqa usulda bo‘lish"</string>
@@ -502,25 +500,18 @@
<string name="volume_zen_end_now" msgid="6930243045593601084">"O‘chiring"</string>
<string name="accessibility_volume_expand" msgid="5946812790999244205">"Yoyish"</string>
<string name="accessibility_volume_collapse" msgid="3609549593031810875">"Yig‘ish"</string>
- <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
- <skip />
+ <string name="accessibility_output_chooser" msgid="8185317493017988680">"Audiochiqish qurilmasini almashtirish"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Ekran qadaldi"</string>
<string name="screen_pinning_description" msgid="8909878447196419623">"Ekran yechilmaguncha u o‘zgarmas holatda qoladi. Uni yechish uchun “Orqaga” va “Umumiy ma’lumot” tugmalarini bosib turing."</string>
- <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
- <skip />
+ <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Ekran yechilmaguncha u o‘zgarmas holatda qoladi. Uni yechish uchun Orqaga va Boshi tugmalarini bosib turing."</string>
<string name="screen_pinning_description_accessible" msgid="426190689254018656">"Ekran yechilmaguncha u o‘zgarmas holatda qoladi. Uni yechish uchun “Umumiy ma’lumot” tugmasini bosib turing."</string>
- <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
- <skip />
- <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
- <skip />
- <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
- <skip />
+ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ekran yechilmaguncha u o‘zgarmas holatda qoladi. Uni yechish uchun Orqaga va Boshi tugmlarini bosib turing."</string>
+ <string name="screen_pinning_toast" msgid="2266705122951934150">"Bu ekrandan chiqish uchun Orqaga va Menyu tugmalarini bosib turing"</string>
+ <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Bu ekrandan chiqish uchun Orqaga va Boshi tugmalarini bosib turing"</string>
<string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
<string name="screen_pinning_negative" msgid="3741602308343880268">"Yo‘q, kerakmas"</string>
- <!-- no translation found for screen_pinning_start (1022122128489278317) -->
- <skip />
- <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
- <skip />
+ <string name="screen_pinning_start" msgid="1022122128489278317">"Ekran mahkamlandi"</string>
+ <string name="screen_pinning_exit" msgid="5187339744262325372">"Ekran olib tashlandi"</string>
<string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> berkitilsinmi?"</string>
<string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Keyingi safar sozlamalardan yoqilgan paydo bo‘ladi."</string>
<string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Berkitish"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index c351b94..3f6c85f 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -855,8 +855,6 @@
<dimen name="default_gear_space">18dp</dimen>
<dimen name="cell_overlay_padding">18dp</dimen>
- <dimen name="signal_icon_size">17dp</dimen>
-
<dimen name="hwui_edge_margin">16dp</dimen>
<dimen name="global_actions_panel_width">120dp</dimen>
@@ -885,11 +883,6 @@
<dimen name="nav_quick_scrub_track_edge_padding">42dp</dimen>
<dimen name="nav_quick_scrub_track_thickness">2dp</dimen>
- <!-- Intended corner radius when drawing the mobile signal -->
- <dimen name="stat_sys_mobile_signal_corner_radius">0.75dp</dimen>
- <!-- How far to inset the rounded edges -->
- <dimen name="stat_sys_mobile_signal_circle_inset">0.9dp</dimen>
-
<!-- Home button padding for sizing -->
<dimen name="home_padding">15dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index fc5ea458..dc082a9 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1340,8 +1340,7 @@
<string name="volume_stream_content_description_vibrate_a11y">%1$s. Tap to set to vibrate.</string>
<string name="volume_stream_content_description_mute_a11y">%1$s. Tap to mute.</string>
- <string name="volume_dialog_accessibility_shown_message">%s volume controls shown. Swipe up to dismiss.</string>
- <string name="volume_dialog_accessibility_dismissed_message">Volume controls hidden</string>
+ <string name="volume_dialog_title">%s volume controls</string>
<string name="output_title">Media output</string>
<string name="output_calls_title">Phone call output</string>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java
index d5e6e6e..6fa7db3 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java
@@ -21,8 +21,12 @@
import android.content.pm.ActivityInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.os.RemoteException;
+import java.util.ArrayList;
+import java.util.List;
+
public class PackageManagerWrapper {
private static final String TAG = "PackageManagerWrapper";
@@ -47,4 +51,42 @@
return null;
}
}
+
+ /**
+ * @return true if the packageName belongs to the current preferred home app on the device.
+ *
+ * If will also return false if there are multiple home apps and the user has not picked any
+ * preferred home, in which case the user would see a disambiguation screen on going to home.
+ */
+ public boolean isDefaultHomeActivity(String packageName) {
+ List<ResolveInfo> allHomeCandidates = new ArrayList<>();
+ ComponentName home;
+ try {
+ home = mIPackageManager.getHomeActivities(allHomeCandidates);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ return false;
+ }
+
+ if (home != null && packageName.equals(home.getPackageName())) {
+ return true;
+ }
+
+ // Find the launcher with the highest priority and return that component if there are no
+ // other home activity with the same priority.
+ int lastPriority = Integer.MIN_VALUE;
+ ComponentName lastComponent = null;
+ final int size = allHomeCandidates.size();
+ for (int i = 0; i < size; i++) {
+ final ResolveInfo ri = allHomeCandidates.get(i);
+ if (ri.priority > lastPriority) {
+ lastComponent = ri.activityInfo.getComponentName();
+ lastPriority = ri.priority;
+ } else if (ri.priority == lastPriority) {
+ // Two components found with same priority.
+ lastComponent = null;
+ }
+ }
+ return lastComponent != null && packageName.equals(lastComponent.getPackageName());
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java b/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java
index 5f260938..e7eefe8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java
@@ -19,12 +19,12 @@
import android.service.quicksettings.Tile;
import android.widget.ImageView;
+import com.android.settingslib.graph.SignalDrawable;
import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.QSTile.Icon;
import com.android.systemui.plugins.qs.QSTile.State;
import com.android.systemui.qs.tileimpl.QSTileImpl;
-import com.android.systemui.statusbar.phone.SignalDrawable;
import java.util.Objects;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index 5a3081c..3847040 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -171,8 +171,6 @@
queryTiles();
mNotifQsContainer.setCustomizerAnimating(true);
mNotifQsContainer.setCustomizerShowing(true);
- announceForAccessibility(mContext.getString(
- R.string.accessibility_desc_quick_settings_edit));
Dependency.get(KeyguardMonitor.class).addCallback(mKeyguardCallback);
updateNavColors();
}
@@ -213,8 +211,6 @@
mClipper.animateCircularClip(mX, mY, false, mCollapseAnimationListener);
mNotifQsContainer.setCustomizerAnimating(true);
mNotifQsContainer.setCustomizerShowing(false);
- announceForAccessibility(mContext.getString(
- R.string.accessibility_desc_quick_settings));
Dependency.get(KeyguardMonitor.class).removeCallback(mKeyguardCallback);
updateNavColors();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 2607ebb..7fe9e35 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -131,21 +131,10 @@
if (enabled) {
if (connected) {
- state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_connected);
+ state.icon = new BluetoothConnectedTileIcon();
state.contentDescription = mContext.getString(
R.string.accessibility_bluetooth_name, state.label);
- final CachedBluetoothDevice lastDevice = mController.getLastDevice();
- if (lastDevice != null) {
- final int batteryLevel = lastDevice.getBatteryLevel();
- if (batteryLevel != BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
- state.icon = new BluetoothBatteryTileIcon(
- batteryLevel,
- mContext.getResources().getFraction(
- R.fraction.bt_battery_scale_fraction, 1, 1));
- }
- }
-
state.label = mController.getLastDeviceName();
} else if (state.isTransient) {
state.icon = ResourceIcon.get(R.drawable.ic_bluetooth_transient_animation);
@@ -281,6 +270,25 @@
}
}
+
+ /**
+ * Bluetooth icon wrapper (when connected with no battery indicator) for Quick Settings. This is
+ * used instead of {@link com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIcon} in order to
+ * use a context that reflects dark/light theme attributes.
+ */
+ private class BluetoothConnectedTileIcon extends Icon {
+
+ BluetoothConnectedTileIcon() {
+ // Do nothing. Default constructor to limit visibility.
+ }
+
+ @Override
+ public Drawable getDrawable(Context context) {
+ // This method returns Pair<Drawable, String> - the first value is the drawable.
+ return context.getDrawable(R.drawable.ic_qs_bluetooth_connected);
+ }
+ }
+
protected class BluetoothDetailAdapter implements DetailAdapter, QSDetailItems.Callback {
// We probably won't ever have space in the UI for more than 20 devices, so don't
// get info for them.
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index bf4a225..2acb1bb 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -38,10 +38,12 @@
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
+import android.graphics.Picture;
import android.graphics.PixelFormat;
import android.graphics.PointF;
import android.graphics.Rect;
@@ -57,13 +59,10 @@
import android.util.DisplayMetrics;
import android.util.Slog;
import android.view.Display;
-import android.view.DisplayListCanvas;
import android.view.LayoutInflater;
import android.view.MotionEvent;
-import android.view.RenderNode;
import android.view.Surface;
import android.view.SurfaceControl;
-import android.view.ThreadedRenderer;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
@@ -233,14 +232,12 @@
*/
private Bitmap generateAdjustedHwBitmap(Bitmap bitmap, int width, int height, Matrix matrix,
Paint paint, int color) {
- RenderNode node = RenderNode.create("ScreenshotCanvas", null);
- node.setLeftTopRightBottom(0, 0, width, height);
- node.setClipToBounds(false);
- DisplayListCanvas canvas = node.start(width, height);
+ Picture picture = new Picture();
+ Canvas canvas = picture.beginRecording(width, height);
canvas.drawColor(color);
canvas.drawBitmap(bitmap, matrix, paint);
- node.end(canvas);
- return ThreadedRenderer.createHardwareBitmap(node, width, height);
+ picture.endRecording();
+ return Bitmap.createBitmap(picture);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 735f4fd..afe906c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -50,7 +50,6 @@
import com.android.systemui.Interpolators;
import com.android.systemui.R;
-import java.lang.IllegalArgumentException;
import java.util.List;
import java.util.Set;
@@ -274,7 +273,7 @@
}
private void saveImportance() {
- if (mNonblockable || !hasImportanceChanged()) {
+ if (mNonblockable) {
return;
}
MetricsLogger.action(mContext, MetricsEvent.ACTION_SAVE_IMPORTANCE,
@@ -409,7 +408,7 @@
final int centerY = v.getHeight() / 2;
final int x = targetLoc[0] - parentLoc[0] + centerX;
final int y = targetLoc[1] - parentLoc[1] + centerY;
- mGutsContainer.closeControls(x, y, false /* save */, false /* force */);
+ mGutsContainer.closeControls(x, y, true /* save */, false /* force */);
}
@Override
@@ -429,7 +428,9 @@
@Override
public boolean handleCloseControls(boolean save, boolean force) {
- if (save && hasImportanceChanged()) {
+ // Save regardless of the importance so we can lock the importance field if the user wants
+ // to keep getting notifications
+ if (save) {
if (mCheckSaveListener != null) {
mCheckSaveListener.checkSave(this::saveImportance, mSbn);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index a7fb61a..cb6e5a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -38,9 +38,9 @@
import android.widget.ImageView;
import android.widget.LinearLayout;
+import com.android.settingslib.graph.SignalDrawable;
import com.android.systemui.Dependency;
import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.SignalDrawable;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.policy.DarkIconDispatcher;
import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
index 677fa81..0304086 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
@@ -16,10 +16,10 @@
import android.util.TypedValue;
import android.view.View;
import android.widget.ImageView;
+import com.android.settingslib.graph.SignalDrawable;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.statusbar.ScalingDrawableWrapper;
-import com.android.systemui.statusbar.phone.SignalDrawable;
import com.android.systemui.statusbar.policy.BluetoothController;
import static com.android.systemui.statusbar.phone.StatusBar.DEBUG;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 52d005c..0e8fcba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -45,7 +45,7 @@
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowInsets;
-import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import com.android.internal.logging.MetricsLogger;
@@ -111,6 +111,7 @@
}
};
private final PowerManager mPowerManager;
+ private final AccessibilityManager mAccessibilityManager;
private KeyguardAffordanceHelper mAffordanceHelper;
private KeyguardUserSwitcher mKeyguardUserSwitcher;
@@ -249,6 +250,8 @@
setWillNotDraw(!DEBUG);
mFalsingManager = FalsingManager.getInstance(context);
mPowerManager = context.getSystemService(PowerManager.class);
+ mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
+ setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
}
public void setStatusBar(StatusBar bar) {
@@ -661,16 +664,6 @@
}
@Override
- public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
- if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
- event.getText().add(getKeyguardOrLockScreenString());
- mLastAnnouncementWasQuickSettings = false;
- return true;
- }
- return super.dispatchPopulateAccessibilityEventInternal(event);
- }
-
- @Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (mBlockTouches || mQsFullyExpanded && mQs.onInterceptTouchEvent(event)) {
return false;
@@ -1300,10 +1293,6 @@
setQsExpanded(true);
} else if (height <= mQsMinExpansionHeight && mQsExpanded) {
setQsExpanded(false);
- if (mLastAnnouncementWasQuickSettings && !mTracking && !isCollapsing()) {
- announceForAccessibility(getKeyguardOrLockScreenString());
- mLastAnnouncementWasQuickSettings = false;
- }
}
mQsExpansionHeight = height;
updateQsExpansion();
@@ -1329,13 +1318,10 @@
updateClock(mClockPositionResult.clockAlpha, mClockPositionResult.clockScale);
}
- // Upon initialisation when we are not layouted yet we don't want to announce that we are
- // fully expanded, hence the != 0.0f check.
- if (height != 0.0f && mQsFullyExpanded && !mLastAnnouncementWasQuickSettings) {
- announceForAccessibility(getContext().getString(
- R.string.accessibility_desc_quick_settings));
- mLastAnnouncementWasQuickSettings = true;
+ if (mAccessibilityManager.isEnabled()) {
+ setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
}
+
if (mQsFullyExpanded && mFalsingManager.shouldEnforceBouncer()) {
mStatusBar.executeRunnableDismissingKeyguard(null, null /* cancelAction */,
false /* dismissShade */, true /* afterKeyguardGone */, false /* deferred */);
@@ -1350,9 +1336,13 @@
mQs.setQsExpansion(getQsExpansionFraction(), getHeaderTranslation());
}
- private String getKeyguardOrLockScreenString() {
+ private String determineAccessibilityPaneTitle() {
if (mQs != null && mQs.isCustomizing()) {
return getContext().getString(R.string.accessibility_desc_quick_settings_edit);
+ } else if (mQsExpansionHeight != 0.0f && mQsFullyExpanded) {
+ // Upon initialisation when we are not layouted yet we don't want to announce that we
+ // are fully expanded, hence the != 0.0f check.
+ return getContext().getString(R.string.accessibility_desc_quick_settings);
} else if (mStatusBarState == StatusBarState.KEYGUARD) {
return getContext().getString(R.string.accessibility_desc_lock_screen);
} else {
@@ -1880,6 +1870,9 @@
requestScrollerTopPaddingUpdate(false /* animate */);
requestPanelHeightUpdate();
}
+ if (mAccessibilityManager.isEnabled()) {
+ setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 8516278..f0854ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -35,8 +35,8 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.cdma.EriInfo;
+import com.android.settingslib.graph.SignalDrawable;
import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.SignalDrawable;
import com.android.systemui.statusbar.policy.NetworkController.IconState;
import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 8881ee9..1e8e98c 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -178,7 +178,6 @@
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
- mWindow.setTitle(VolumeDialogImpl.class.getSimpleName());
mWindow.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
mWindow.setWindowAnimations(com.android.internal.R.style.Animation_Toast);
final WindowManager.LayoutParams lp = mWindow.getAttributes();
@@ -410,6 +409,7 @@
final boolean hasVibrator = mController.hasVibrator();
if (mState.ringerModeInternal == AudioManager.RINGER_MODE_NORMAL) {
if (hasVibrator) {
+ mController.vibrate();
mController.setRingerMode(AudioManager.RINGER_MODE_VIBRATE, false);
} else {
mController.setRingerMode(AudioManager.RINGER_MODE_SILENT, false);
@@ -491,15 +491,6 @@
}, 50))
.start();
- if (mAccessibilityMgr.isEnabled()) {
- AccessibilityEvent event =
- AccessibilityEvent.obtain(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
- event.setPackageName(mContext.getPackageName());
- event.setClassName(CustomDialog.class.getSuperclass().getName());
- event.getText().add(mContext.getString(
- R.string.volume_dialog_accessibility_dismissed_message));
- mAccessibilityMgr.sendAccessibilityEvent(event);
- }
Events.writeEvent(mContext, Events.EVENT_DISMISS_DIALOG, reason);
mController.notifyVisible(false);
synchronized (mSafetyWarningLock) {
@@ -670,6 +661,8 @@
updateVolumeRowH(row);
}
updateRingerH();
+ mWindow.setTitle(mContext.getString(R.string.volume_dialog_title,
+ getStreamLabelH(getActiveRow().ss)));
}
private void updateVolumeRowH(VolumeRow row) {
@@ -1065,22 +1058,6 @@
}
return false;
}
-
- @Override
- public boolean dispatchPopulateAccessibilityEvent(@NonNull AccessibilityEvent event) {
- event.setClassName(getClass().getSuperclass().getName());
- event.setPackageName(mContext.getPackageName());
-
- if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
- if (mShowing) {
- event.getText().add(mContext.getString(
- R.string.volume_dialog_accessibility_shown_message,
- getStreamLabelH(getActiveRow().ss)));
- return true;
- }
- }
- return false;
- }
}
private final class VolumeSeekBarChangeListener implements OnSeekBarChangeListener {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index 8e8b3e0..b8d9b19 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -16,7 +16,9 @@
package com.android.systemui.statusbar;
+import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import static android.print.PrintManager.PRINT_SPOOLER_PACKAGE_NAME;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
@@ -95,6 +97,7 @@
final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
mNotificationInfo = (NotificationInfo) layoutInflater.inflate(R.layout.notification_info,
null);
+ mNotificationInfo.setGutsParent(mock(NotificationGuts.class));
// PackageManager must return a packageInfo and applicationInfo.
final PackageInfo packageInfo = new PackageInfo();
@@ -323,24 +326,27 @@
@Test
public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnchanged()
throws Exception {
+ int originalImportance = mNotificationChannel.getImportance();
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, null);
mNotificationInfo.handleCloseControls(true, false);
- verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
+ verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
anyString(), eq(TEST_UID), any());
+ assertEquals(originalImportance, mNotificationChannel.getImportance());
}
@Test
public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnspecified()
throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_UNSPECIFIED);
+ mNotificationChannel.setImportance(IMPORTANCE_UNSPECIFIED);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, null);
mNotificationInfo.handleCloseControls(true, false);
- verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
+ verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
anyString(), eq(TEST_UID), any());
+ assertEquals(IMPORTANCE_UNSPECIFIED, mNotificationChannel.getImportance());
}
@Test
@@ -370,16 +376,30 @@
verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
anyString(), eq(TEST_UID), updated.capture());
assertTrue((updated.getValue().getUserLockedFields()
- & NotificationChannel.USER_LOCKED_IMPORTANCE) != 0);
+ & USER_LOCKED_IMPORTANCE) != 0);
}
@Test
- public void testBlockUndoDoesNotCallUpdateNotificationChannel() throws Exception {
+ public void testKeepUpdatesNotificationChannel() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null,
- Collections.singleton(TEST_PACKAGE_NAME));
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, null);
+ mNotificationInfo.handleCloseControls(true, false);
+
+ ArgumentCaptor<NotificationChannel> updated =
+ ArgumentCaptor.forClass(NotificationChannel.class);
+ verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
+ anyString(), eq(TEST_UID), updated.capture());
+ assertTrue(0 != (mNotificationChannel.getUserLockedFields() & USER_LOCKED_IMPORTANCE));
+ assertEquals(IMPORTANCE_LOW, mNotificationChannel.getImportance());
+ }
+
+ @Test
+ public void testBlockUndoDoesNotBlockNotificationChannel() throws Exception {
+ mNotificationChannel.setImportance(IMPORTANCE_LOW);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, null);
mNotificationInfo.findViewById(R.id.block).performClick();
waitForUndoButton();
@@ -389,8 +409,9 @@
ArgumentCaptor<NotificationChannel> updated =
ArgumentCaptor.forClass(NotificationChannel.class);
- verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
+ verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
anyString(), eq(TEST_UID), updated.capture());
+ assertTrue(0 != (mNotificationChannel.getUserLockedFields() & USER_LOCKED_IMPORTANCE));
assertEquals(IMPORTANCE_LOW, mNotificationChannel.getImportance());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index f685b1f..8aab837 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -43,9 +43,9 @@
import android.util.Log;
import com.android.internal.telephony.cdma.EriInfo;
+import com.android.settingslib.graph.SignalDrawable;
import com.android.settingslib.net.DataUsageController;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.phone.SignalDrawable;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
import com.android.systemui.statusbar.policy.NetworkController.IconState;
import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 3ad107c..550f4a7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -30,9 +30,9 @@
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyIntents;
+import com.android.settingslib.graph.SignalDrawable;
import com.android.settingslib.net.DataUsageController;
import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.SignalDrawable;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 10fad62..a422b7c 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -2584,7 +2584,7 @@
if (mAlarmBatches.size() > 0) {
final Batch firstWakeup = findFirstWakeupBatchLocked();
final Batch firstBatch = mAlarmBatches.get(0);
- if (firstWakeup != null && mNextWakeup != firstWakeup.start) {
+ if (firstWakeup != null) {
mNextWakeup = firstWakeup.start;
mLastWakeupSet = SystemClock.elapsedRealtime();
setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup.start);
@@ -2598,7 +2598,7 @@
nextNonWakeup = mNextNonWakeupDeliveryTime;
}
}
- if (nextNonWakeup != 0 && mNextNonWakeup != nextNonWakeup) {
+ if (nextNonWakeup != 0) {
mNextNonWakeup = nextNonWakeup;
setLocked(ELAPSED_REALTIME, nextNonWakeup);
}
@@ -3229,6 +3229,8 @@
expectedMaxWhenElapsed, nowELAPSED, pw);
pw.print(" whenElapsed="); TimeUtils.formatDuration(whenElapsed,
nowELAPSED, pw);
+ pw.print(" maxWhenElapsed="); TimeUtils.formatDuration(maxWhenElapsed,
+ nowELAPSED, pw);
pw.print(" when=");
if (isRtc) {
pw.print(sdf.format(new Date(when)));
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 230f69d..14404f5 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1043,14 +1043,20 @@
throw new SecurityException("Instant app " + r.appInfo.packageName
+ " does not have permission to create foreground services");
default:
- mAm.enforcePermission(
- android.Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
- r.app.pid, r.appInfo.uid, "startForeground");
+ try {
+ if (AppGlobals.getPackageManager().checkPermission(
+ android.Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
+ r.appInfo.packageName, UserHandle.getUserId(r.appInfo.uid))
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Instant app " + r.appInfo.packageName
+ + " does not have permission to create foreground"
+ + "services");
+ }
+ } catch (RemoteException e) {
+ throw new SecurityException("Failed to check instant app permission." ,
+ e);
+ }
}
- } else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.P) {
- mAm.enforcePermission(
- android.Manifest.permission.FOREGROUND_SERVICE,
- r.app.pid, r.appInfo.uid, "startForeground");
}
if (r.fgRequired) {
if (DEBUG_SERVICE || DEBUG_BACKGROUND_CHECK) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
index 0a7d3fd..87e8121 100644
--- a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
+++ b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
@@ -65,7 +65,7 @@
static final boolean DEBUG_NETWORK = DEBUG_ALL || false;
static final boolean DEBUG_OOM_ADJ = DEBUG_ALL || false;
static final boolean DEBUG_OOM_ADJ_REASON = DEBUG_ALL || false;
- static final boolean DEBUG_PAUSE = DEBUG_ALL || false;
+ static final boolean DEBUG_PAUSE = DEBUG_ALL || true;
static final boolean DEBUG_POWER = DEBUG_ALL || false;
static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
static final boolean DEBUG_PROCESS_OBSERVERS = DEBUG_ALL || false;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index cd8b6d7..c958b67 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8889,20 +8889,6 @@
/**
* This can be called with or without the global lock held.
*/
- void enforcePermission(String permission, int pid, int uid, String func) {
- if (checkPermission(permission, pid, uid) == PackageManager.PERMISSION_GRANTED) {
- return;
- }
-
- String msg = "Permission Denial: " + func + " from pid=" + pid + ", uid=" + uid
- + " requires " + permission;
- Slog.w(TAG, msg);
- throw new SecurityException(msg);
- }
-
- /**
- * This can be called with or without the global lock held.
- */
void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
enforceCallingPermission(permission, func);
@@ -25697,9 +25683,11 @@
}
synchronized (ActivityManagerService.this) {
- return mActivityStartController.startActivitiesInPackage(packageUid, packageName,
+ return mActivityStartController.startActivitiesInPackage(
+ packageUid, packageName,
intents, resolvedTypes, null /* resultTo */,
- SafeActivityOptions.fromBundle(bOptions), userId);
+ SafeActivityOptions.fromBundle(bOptions), userId,
+ false /* validateIncomingUser */);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStartController.java b/services/core/java/com/android/server/am/ActivityStartController.java
index 5551914..da11f686 100644
--- a/services/core/java/com/android/server/am/ActivityStartController.java
+++ b/services/core/java/com/android/server/am/ActivityStartController.java
@@ -245,11 +245,25 @@
.execute();
}
+ /**
+ * Start intents as a package.
+ *
+ * @param uid Make a call as if this UID did.
+ * @param callingPackage Make a call as if this package did.
+ * @param intents Intents to start.
+ * @param userId Start the intents on this user.
+ * @param validateIncomingUser Set true to skip checking {@code userId} with the calling UID.
+ */
final int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
- String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId) {
+ String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
+ boolean validateIncomingUser) {
final String reason = "startActivityInPackage";
- userId = mService.mUserController.handleIncomingUser(Binder.getCallingPid(),
- Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, reason, null);
+ if (validateIncomingUser) {
+ userId = mService.mUserController.handleIncomingUser(Binder.getCallingPid(),
+ Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, reason, null);
+ } else {
+ mService.mUserController.ensureNotSpecialUser(userId);
+ }
// TODO: Switch to user app stacks here.
return startActivities(null, uid, callingPackage, intents, resolvedTypes, resultTo, options,
userId, reason);
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index 8e9d85d..264609f 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -335,7 +335,8 @@
allResolvedTypes[allResolvedTypes.length-1] = resolvedType;
res = owner.getActivityStartController().startActivitiesInPackage(
uid, key.packageName, allIntents, allResolvedTypes,
- resultTo, mergedOptions, userId);
+ resultTo, mergedOptions, userId,
+ true /* validateIncomingUser */);
} else {
res = owner.getActivityStartController().startActivityInPackage(uid,
callingPid, callingUid, key.packageName, finalIntent,
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index d54e264..bfc787e 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -1489,9 +1489,8 @@
}
}
}
- if (!allowAll && targetUserId < 0) {
- throw new IllegalArgumentException(
- "Call does not support special user #" + targetUserId);
+ if (!allowAll) {
+ ensureNotSpecialUser(targetUserId);
}
// Check shell permission
if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_SYSTEM) {
@@ -1508,6 +1507,13 @@
? getCurrentUserId(): userId;
}
+ void ensureNotSpecialUser(int userId) {
+ if (userId >= 0) {
+ return;
+ }
+ throw new IllegalArgumentException("Call does not support special user #" + userId);
+ }
+
void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
Preconditions.checkNotNull(name, "Observer name cannot be null");
if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 23de592..fa39ce4 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -500,6 +500,7 @@
}
public void onSwitchUser(@UserIdInt int newUserId) {
+ handleSettingsChange();
mBrightnessTracker.onSwitchUser(newUserId);
}
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 47a4fb2..be48f69 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -2337,9 +2337,9 @@
if (callingUid != Process.SYSTEM_UID) {
throw new SecurityException("Job has invalid flags");
}
- if (job.hasLateConstraint() || job.hasEarlyConstraint()) {
- Slog.wtf(TAG, "Jobs with time-constraints mustn't have"
- +" FLAG_EXEMPT_FROM_APP_STANDBY. Job=" + job);
+ if (job.isPeriodic()) {
+ Slog.wtf(TAG, "Periodic jobs mustn't have"
+ + " FLAG_EXEMPT_FROM_APP_STANDBY. Job=" + job);
}
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 1ad8c74..8d2f0dd 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -15,6 +15,7 @@
*/
package com.android.server.notification;
+import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
import static android.app.NotificationManager.IMPORTANCE_MIN;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
@@ -22,6 +23,8 @@
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.service.notification.NotificationListenerService.Ranking
.USER_SENTIMENT_NEUTRAL;
+import static android.service.notification.NotificationListenerService.Ranking
+ .USER_SENTIMENT_POSITIVE;
import android.app.Notification;
import android.app.NotificationChannel;
@@ -163,6 +166,7 @@
mLight = calculateLights();
mAdjustments = new ArrayList<>();
mStats = new NotificationStats();
+ calculateUserSentiment();
}
private boolean isPreChannelsNotification() {
@@ -320,7 +324,7 @@
if (mPreChannelsNotification
&& (importance == IMPORTANCE_UNSPECIFIED
|| (getChannel().getUserLockedFields()
- & NotificationChannel.USER_LOCKED_IMPORTANCE) == 0)) {
+ & USER_LOCKED_IMPORTANCE) == 0)) {
if (!stats.isNoisy && requestedImportance > IMPORTANCE_LOW) {
requestedImportance = IMPORTANCE_LOW;
}
@@ -585,8 +589,12 @@
setOverrideGroupKey(groupOverrideKey);
}
if (signals.containsKey(Adjustment.KEY_USER_SENTIMENT)) {
- setUserSentiment(adjustment.getSignals().getInt(
- Adjustment.KEY_USER_SENTIMENT, USER_SENTIMENT_NEUTRAL));
+ // Only allow user sentiment update from assistant if user hasn't already
+ // expressed a preference for this channel
+ if ((getChannel().getUserLockedFields() & USER_LOCKED_IMPORTANCE) == 0) {
+ setUserSentiment(adjustment.getSignals().getInt(
+ Adjustment.KEY_USER_SENTIMENT, USER_SENTIMENT_NEUTRAL));
+ }
}
}
}
@@ -845,10 +853,6 @@
}
}
- public boolean isImportanceFromUser() {
- return mImportance == mUserImportance;
- }
-
public NotificationChannel getChannel() {
return mChannel;
}
@@ -857,6 +861,7 @@
if (channel != null) {
mChannel = channel;
calculateImportance();
+ calculateUserSentiment();
}
}
@@ -900,6 +905,12 @@
mSnoozeCriteria = snoozeCriteria;
}
+ private void calculateUserSentiment() {
+ if ((getChannel().getUserLockedFields() & USER_LOCKED_IMPORTANCE) != 0) {
+ mUserSentiment = USER_SENTIMENT_POSITIVE;
+ }
+ }
+
private void setUserSentiment(int userSentiment) {
mUserSentiment = userSentiment;
}
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index b0e3820..dc936d2 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -640,9 +640,11 @@
if (updatedChannel.getLockscreenVisibility() == Notification.VISIBILITY_PUBLIC) {
updatedChannel.setLockscreenVisibility(Ranking.VISIBILITY_NO_OVERRIDE);
}
- updatedChannel.unlockFields(updatedChannel.getUserLockedFields());
- updatedChannel.lockFields(channel.getUserLockedFields());
+ if (!fromUser) {
+ updatedChannel.unlockFields(updatedChannel.getUserLockedFields());
+ }
if (fromUser) {
+ updatedChannel.lockFields(channel.getUserLockedFields());
lockFieldsForUpdate(channel, updatedChannel);
}
r.channels.put(updatedChannel.getId(), updatedChannel);
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 758c9d5..d2ef67b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -34,6 +34,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.IPackageDataObserver;
+import android.content.pm.IPackageInstaller;
import android.content.pm.IPackageManager;
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
@@ -89,12 +90,7 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.WeakHashMap;
+import java.util.*;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
@@ -235,6 +231,8 @@
return runSetHarmfulAppWarning();
case "get-harmful-app-warning":
return runGetHarmfulAppWarning();
+ case "uninstall-system-updates":
+ return uninstallSystemUpdates();
default: {
String nextArg = getNextArg();
if (nextArg == null) {
@@ -257,6 +255,47 @@
return -1;
}
+ private int uninstallSystemUpdates() {
+ final PrintWriter pw = getOutPrintWriter();
+ List<String> failedUninstalls = new LinkedList<>();
+ try {
+ final ParceledListSlice<ApplicationInfo> packages =
+ mInterface.getInstalledApplications(
+ PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
+ final IPackageInstaller installer = mInterface.getPackageInstaller();
+ List<ApplicationInfo> list = packages.getList();
+ for (ApplicationInfo info : list) {
+ if (info.isUpdatedSystemApp()) {
+ pw.println("Uninstalling updates to " + info.packageName + "...");
+ final LocalIntentReceiver receiver = new LocalIntentReceiver();
+ installer.uninstall(new VersionedPackage(info.packageName,
+ info.versionCode), null /*callerPackageName*/, 0 /* flags */,
+ receiver.getIntentSender(), 0);
+
+ final Intent result = receiver.getResult();
+ final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
+ PackageInstaller.STATUS_FAILURE);
+ if (status != PackageInstaller.STATUS_SUCCESS) {
+ failedUninstalls.add(info.packageName);
+ }
+ }
+ }
+ } catch (RemoteException e) {
+ pw.println("Failure ["
+ + e.getClass().getName() + " - "
+ + e.getMessage() + "]");
+ return 0;
+ }
+ if (!failedUninstalls.isEmpty()) {
+ pw.println("Failure [Couldn't uninstall packages: "
+ + TextUtils.join(", ", failedUninstalls)
+ + "]");
+ return 0;
+ }
+ pw.println("Success");
+ return 1;
+ }
+
private void setParamsSize(InstallParams params, String inPath) {
if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) {
final ParcelFileDescriptor fd = openFileForSystem(inPath, "r");
@@ -2705,6 +2744,10 @@
pw.println(" get-harmful-app-warning [--user <USER_ID>] <PACKAGE>");
pw.println(" Return the harmful app warning message for the given app, if present");
pw.println();
+ pw.println(" uninstall-system-updates");
+ pw.println(" Remove updates to all system applications and fall back to their /system " +
+ "version.");
+ pw.println();
Intent.printIntentArgsHelp(pw , "");
}
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index bd4aa1c..0a6b38f 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -451,7 +451,7 @@
// First send the high-level shut down broadcast.
mActionDone = false;
Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
- intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND | Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mContext.sendOrderedBroadcastAsUser(intent,
UserHandle.ALL, null, br, mHandler, 0, null, null);
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index ef6067a..4bc9404 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -290,7 +290,8 @@
public final static class AnomalyAlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
- Slog.i(TAG, "StatsCompanionService believes an anomaly has occurred.");
+ Slog.i(TAG, "StatsCompanionService believes an anomaly has occurred at time "
+ + System.currentTimeMillis() + "ms.");
synchronized (sStatsdLock) {
if (sStatsd == null) {
Slog.w(TAG, "Could not access statsd to inform it of anomaly alarm firing");
@@ -361,9 +362,8 @@
final long callingToken = Binder.clearCallingIdentity();
try {
// using RTC, not RTC_WAKEUP, so if device is asleep, will only fire when it awakens.
- // This alarm is inexact, leaving its exactness completely up to the OS optimizations.
// AlarmManager will automatically cancel any previous mAnomalyAlarmIntent alarm.
- mAlarmManager.set(AlarmManager.RTC, timestampMs, mAnomalyAlarmIntent);
+ mAlarmManager.setExact(AlarmManager.RTC, timestampMs, mAnomalyAlarmIntent);
} finally {
Binder.restoreCallingIdentity(callingToken);
}
@@ -783,7 +783,9 @@
enforceCallingPermission();
if (DEBUG) Slog.d(TAG, "learned that statsdReady");
sayHiToStatsd(); // tell statsd that we're ready too and link to it
- mContext.sendBroadcastAsUser(new Intent(StatsManager.ACTION_STATSD_STARTED),
+ mContext.sendBroadcastAsUser(
+ new Intent(StatsManager.ACTION_STATSD_STARTED)
+ .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND),
UserHandle.SYSTEM,
android.Manifest.permission.DUMP);
}
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 2bdaa1a..0d36145 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -78,9 +78,12 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.GraphicBuffer;
import android.graphics.Path;
+import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Binder;
@@ -96,11 +99,8 @@
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
import android.view.AppTransitionAnimationSpec;
-import android.view.DisplayListCanvas;
import android.view.IAppTransitionAnimationSpecsFuture;
import android.view.RemoteAnimationAdapter;
-import android.view.RenderNode;
-import android.view.ThreadedRenderer;
import android.view.WindowManager.TransitionFlags;
import android.view.WindowManager.TransitionType;
import android.view.animation.AlphaAnimation;
@@ -973,11 +973,8 @@
final int width = frame.width();
final int height = frame.height();
- final RenderNode node = RenderNode.create("CrossProfileAppsThumbnail", null);
- node.setLeftTopRightBottom(0, 0, width, height);
- node.setClipToBounds(false);
-
- final DisplayListCanvas canvas = node.start(width, height);
+ final Picture picture = new Picture();
+ final Canvas canvas = picture.beginRecording(width, height);
canvas.drawColor(Color.argb(0.6f, 0, 0, 0));
final int thumbnailSize = mService.mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.cross_profile_apps_thumbnail_size);
@@ -988,10 +985,9 @@
(width + thumbnailSize) / 2,
(height + thumbnailSize) / 2);
drawable.draw(canvas);
- node.end(canvas);
+ picture.endRecording();
- return ThreadedRenderer.createHardwareBitmap(node, width, height)
- .createGraphicBufferHandle();
+ return Bitmap.createBitmap(picture).createGraphicBufferHandle();
}
Animation createCrossProfileAppsThumbnailAnimationLocked(Rect appRect) {
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 97d6c43..5d8aca1 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -60,7 +60,6 @@
<uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
<uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!-- Uses API introduced in O (26) -->
<uses-sdk android:minSdkVersion="1"
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
index a5fa903..a566327 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
@@ -15,10 +15,13 @@
*/
package com.android.server.notification;
+import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
import static android.service.notification.NotificationListenerService.Ranking
.USER_SENTIMENT_NEGATIVE;
import static android.service.notification.NotificationListenerService.Ranking
.USER_SENTIMENT_NEUTRAL;
+import static android.service.notification.NotificationListenerService.Ranking
+ .USER_SENTIMENT_POSITIVE;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
@@ -315,7 +318,7 @@
@Test
public void testImportance_locked_preUpgrade() throws Exception {
defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
- defaultChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
+ defaultChannel.lockFields(USER_LOCKED_IMPORTANCE);
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
false /* lights */, false /* defaultLights */, null /* group */);
@@ -327,7 +330,7 @@
@Test
public void testImportance_locked_unspecified_preUpgrade() throws Exception {
defaultChannel.setImportance(NotificationManager.IMPORTANCE_UNSPECIFIED);
- defaultChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
+ defaultChannel.lockFields(USER_LOCKED_IMPORTANCE);
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
false /* lights */, false /* defaultLights */, null /* group */);
@@ -549,4 +552,23 @@
assertEquals(USER_SENTIMENT_NEGATIVE, record.getUserSentiment());
}
+
+ @Test
+ public void testUserSentiment_userLocked() throws Exception {
+ channel.lockFields(USER_LOCKED_IMPORTANCE);
+ StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
+ true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+ false /* lights */, false /* defaultLights */, groupId /* group */);
+ NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+
+ assertEquals(USER_SENTIMENT_POSITIVE, record.getUserSentiment());
+
+ Bundle signals = new Bundle();
+ signals.putInt(Adjustment.KEY_USER_SENTIMENT, USER_SENTIMENT_NEGATIVE);
+ record.addAdjustment(new Adjustment(pkg, record.getKey(), signals, null, sbn.getUserId()));
+
+ record.applyAdjustments();
+
+ assertEquals(USER_SENTIMENT_POSITIVE, record.getUserSentiment());
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
index abfc54d..9ebce71 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
@@ -914,16 +914,18 @@
final NotificationChannel update1 = getChannel();
update1.setSound(new Uri.Builder().scheme("test").build(),
new AudioAttributes.Builder().build());
- update1.lockFields(NotificationChannel.USER_LOCKED_PRIORITY); // should be ignored
+ update1.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
mHelper.updateNotificationChannel(PKG, UID, update1, true);
- assertEquals(NotificationChannel.USER_LOCKED_SOUND,
+ assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
+ | NotificationChannel.USER_LOCKED_SOUND,
mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
.getUserLockedFields());
NotificationChannel update2 = getChannel();
update2.enableVibration(true);
mHelper.updateNotificationChannel(PKG, UID, update2, true);
- assertEquals(NotificationChannel.USER_LOCKED_SOUND
+ assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
+ | NotificationChannel.USER_LOCKED_SOUND
| NotificationChannel.USER_LOCKED_VIBRATION,
mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
.getUserLockedFields());
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 24184e0..d8599e8 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -2743,7 +2743,20 @@
/**
* Notifies this Connection, which is in {@link #STATE_RINGING}, of
* a request to accept.
- *
+ * <p>
+ * For managed {@link ConnectionService}s, this will be called when the user answers a call via
+ * the default dialer's {@link InCallService}.
+ * <p>
+ * Although a self-managed {@link ConnectionService} provides its own incoming call UI, the
+ * Telecom framework may request that the call is answered in the following circumstances:
+ * <ul>
+ * <li>The user chooses to answer an incoming call via a Bluetooth device.</li>
+ * <li>A car mode {@link InCallService} is in use which has declared
+ * {@link TelecomManager#METADATA_INCLUDE_SELF_MANAGED_CALLS} in its manifest. Such an
+ * {@link InCallService} will be able to see calls from self-managed
+ * {@link ConnectionService}s, and will be able to display an incoming call UI on their
+ * behalf.</li>
+ * </ul>
* @param videoState The video state in which to answer the connection.
*/
public void onAnswer(int videoState) {}
@@ -2751,6 +2764,20 @@
/**
* Notifies this Connection, which is in {@link #STATE_RINGING}, of
* a request to accept.
+ * <p>
+ * For managed {@link ConnectionService}s, this will be called when the user answers a call via
+ * the default dialer's {@link InCallService}.
+ * <p>
+ * Although a self-managed {@link ConnectionService} provides its own incoming call UI, the
+ * Telecom framework may request that the call is answered in the following circumstances:
+ * <ul>
+ * <li>The user chooses to answer an incoming call via a Bluetooth device.</li>
+ * <li>A car mode {@link InCallService} is in use which has declared
+ * {@link TelecomManager#METADATA_INCLUDE_SELF_MANAGED_CALLS} in its manifest. Such an
+ * {@link InCallService} will be able to see calls from self-managed
+ * {@link ConnectionService}s, and will be able to display an incoming call UI on their
+ * behalf.</li>
+ * </ul>
*/
public void onAnswer() {
onAnswer(VideoProfile.STATE_AUDIO_ONLY);
@@ -2765,6 +2792,20 @@
/**
* Notifies this Connection, which is in {@link #STATE_RINGING}, of
* a request to reject.
+ * <p>
+ * For managed {@link ConnectionService}s, this will be called when the user rejects a call via
+ * the default dialer's {@link InCallService}.
+ * <p>
+ * Although a self-managed {@link ConnectionService} provides its own incoming call UI, the
+ * Telecom framework may request that the call is rejected in the following circumstances:
+ * <ul>
+ * <li>The user chooses to reject an incoming call via a Bluetooth device.</li>
+ * <li>A car mode {@link InCallService} is in use which has declared
+ * {@link TelecomManager#METADATA_INCLUDE_SELF_MANAGED_CALLS} in its manifest. Such an
+ * {@link InCallService} will be able to see calls from self-managed
+ * {@link ConnectionService}s, and will be able to display an incoming call UI on their
+ * behalf.</li>
+ * </ul>
*/
public void onReject() {}
@@ -2847,9 +2888,10 @@
* should show its own incoming call user interface.
* <p>
* Where there are ongoing calls in other self-managed {@link ConnectionService}s, or in a
- * regular {@link ConnectionService}, the Telecom framework will display its own incoming call
- * user interface to allow the user to choose whether to answer the new incoming call and
- * disconnect other ongoing calls, or to reject the new incoming call.
+ * regular {@link ConnectionService}, and it is not possible to hold these other calls, the
+ * Telecom framework will display its own incoming call user interface to allow the user to
+ * choose whether to answer the new incoming call and disconnect other ongoing calls, or to
+ * reject the new incoming call.
* <p>
* You should trigger the display of the incoming call user interface for your application by
* showing a {@link Notification} with a full-screen {@link Intent} specified.
diff --git a/telephony/java/android/telephony/OWNERS b/telephony/java/android/telephony/OWNERS
new file mode 100644
index 0000000..68dedce
--- /dev/null
+++ b/telephony/java/android/telephony/OWNERS
@@ -0,0 +1,14 @@
+set noparent
+
+amitmahajan@google.com
+breadley@google.com
+fionaxu@google.com
+jackyu@google.com
+hallliu@google.com
+rgreenwalt@google.com
+tgunn@google.com
+jminjie@google.com
+mpq@google.com
+shuoq@google.com
+refuhoo@google.com
+
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index 38408fe..77413d9c 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -17,6 +17,7 @@
package android.telephony;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -34,6 +35,8 @@
import android.util.DisplayMetrics;
import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
/**
* A Parcelable class for Subscription Information.
@@ -332,12 +335,7 @@
return this.mCountryIso;
}
- /**
- * @return whether the subscription is an embedded one.
- * @hide
- *
- * TODO(b/35851809): Make this public.
- */
+ /** @return whether the subscription is an embedded one. */
public boolean isEmbedded() {
return this.mIsEmbedded;
}
@@ -351,9 +349,9 @@
* @return whether the app is authorized to manage this subscription per its metadata.
* @throws UnsupportedOperationException if this subscription is not embedded.
* @hide
- *
- * TODO(b/35851809): Make this public.
+ * @deprecated - Do not use.
*/
+ @Deprecated
public boolean canManageSubscription(Context context) {
return canManageSubscription(context, context.getPackageName());
}
@@ -367,7 +365,9 @@
* @return whether the app is authorized to manage this subscription per its metadata.
* @throws UnsupportedOperationException if this subscription is not embedded.
* @hide
+ * @deprecated - Do not use.
*/
+ @Deprecated
public boolean canManageSubscription(Context context, String packageName) {
if (!isEmbedded()) {
throw new UnsupportedOperationException("Not an embedded subscription");
@@ -395,14 +395,14 @@
* @return the {@link UiccAccessRule}s dictating who is authorized to manage this subscription.
* @throws UnsupportedOperationException if this subscription is not embedded.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
- public @Nullable UiccAccessRule[] getAccessRules() {
+ @SystemApi
+ public @Nullable List<UiccAccessRule> getAccessRules() {
if (!isEmbedded()) {
throw new UnsupportedOperationException("Not an embedded subscription");
}
- return mAccessRules;
+ if (mAccessRules == null) return null;
+ return Arrays.asList(mAccessRules);
}
/**
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index debf43d..11a1984 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -30,6 +30,7 @@
import android.app.BroadcastOptions;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -822,10 +823,13 @@
* if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
* then by {@link SubscriptionInfo#getSubscriptionId}.
* </ul>
- * @hide
*
- * TODO(b/35851809): Make this a SystemApi.
+ * <p>
+ * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required
+ * for #getAvailableSubscriptionInfoList to be invoked.
+ * @hide
*/
+ @SystemApi
public List<SubscriptionInfo> getAvailableSubscriptionInfoList() {
List<SubscriptionInfo> result = null;
@@ -863,9 +867,6 @@
* if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
* then by {@link SubscriptionInfo#getSubscriptionId}.
* </ul>
- * @hide
- *
- * TODO(b/35851809): Make this public.
*/
public List<SubscriptionInfo> getAccessibleSubscriptionInfoList() {
List<SubscriptionInfo> result = null;
@@ -891,9 +892,8 @@
*
* <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+ @SystemApi
public void requestEmbeddedSubscriptionInfoListRefresh() {
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -1892,4 +1892,51 @@
options.setTemporaryAppWhitelistDuration(TimeUnit.MINUTES.toMillis(1));
mContext.sendBroadcast(intent, null, options.toBundle());
}
+
+ /**
+ * Checks whether the app with the given context is authorized to manage the given subscription
+ * according to its metadata. Only supported for embedded subscriptions (if
+ * {@code SubscriptionInfo#isEmbedded} returns true).
+ *
+ * @param info The subscription to check.
+ * @return whether the app is authorized to manage this subscription per its metadata.
+ * @throws UnsupportedOperationException if this subscription is not embedded.
+ */
+ public boolean canManageSubscription(SubscriptionInfo info) {
+ return canManageSubscription(info, mContext.getPackageName());
+ }
+
+ /**
+ * Checks whether the given app is authorized to manage the given subscription according to its
+ * metadata. Only supported for embedded subscriptions (if {@code SubscriptionInfo#isEmbedded}
+ * returns true).
+ *
+ * @param info The subscription to check.
+ * @param packageName Package name of the app to check.
+ * @return whether the app is authorized to manage this subscription per its metadata.
+ * @throws UnsupportedOperationException if this subscription is not embedded.
+ * @hide
+ */
+ public boolean canManageSubscription(SubscriptionInfo info, String packageName) {
+ if (!info.isEmbedded()) {
+ throw new UnsupportedOperationException("Not an embedded subscription");
+ }
+ if (info.getAccessRules() == null) {
+ return false;
+ }
+ PackageManager packageManager = mContext.getPackageManager();
+ PackageInfo packageInfo;
+ try {
+ packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
+ } catch (PackageManager.NameNotFoundException e) {
+ throw new IllegalArgumentException("Unknown package: " + packageName, e);
+ }
+ for (UiccAccessRule rule : info.getAccessRules()) {
+ if (rule.getCarrierPrivilegeStatus(packageInfo)
+ == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 03d8b5c..7afd28c 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -4801,7 +4801,7 @@
}
/**
- * Sets the telephony property with the value specified.
+ * Sets a per-phone telephony property with the value specified.
*
* @hide
*/
@@ -4851,6 +4851,20 @@
}
/**
+ * Sets a global telephony property with the value specified.
+ *
+ * @hide
+ */
+ public static void setTelephonyProperty(String property, String value) {
+ if (value == null) {
+ value = "";
+ }
+ Rlog.d(TAG, "setTelephonyProperty: success" + " property=" +
+ property + " value: " + value);
+ SystemProperties.set(property, value);
+ }
+
+ /**
* Convenience function for retrieving a value from the secure settings
* value list as an integer. Note that internally setting values are
* always stored as strings; this function converts the string to an
@@ -4939,7 +4953,7 @@
}
/**
- * Gets the telephony property.
+ * Gets a per-phone telephony property.
*
* @hide
*/
@@ -4955,6 +4969,19 @@
return propVal == null ? defaultVal : propVal;
}
+ /**
+ * Gets a global telephony property.
+ *
+ * See also getTelephonyProperty(phoneId, property, defaultVal). Most telephony properties are
+ * per-phone.
+ *
+ * @hide
+ */
+ public static String getTelephonyProperty(String property, String defaultVal) {
+ String propVal = SystemProperties.get(property);
+ return propVal == null ? defaultVal : propVal;
+ }
+
/** @hide */
public int getSimCount() {
// FIXME Need to get it from Telephony Dev Controller when that gets implemented!
diff --git a/telephony/java/android/telephony/UiccAccessRule.java b/telephony/java/android/telephony/UiccAccessRule.java
index 3937201..c3f8a19 100644
--- a/telephony/java/android/telephony/UiccAccessRule.java
+++ b/telephony/java/android/telephony/UiccAccessRule.java
@@ -16,6 +16,7 @@
package android.telephony;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.content.pm.PackageInfo;
import android.content.pm.Signature;
import android.os.Parcel;
@@ -39,9 +40,8 @@
* specification.
*
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+@SystemApi
public final class UiccAccessRule implements Parcelable {
private static final String TAG = "UiccAccessRule";
diff --git a/telephony/java/android/telephony/euicc/DownloadableSubscription.java b/telephony/java/android/telephony/euicc/DownloadableSubscription.java
index 01041c8..88db22b 100644
--- a/telephony/java/android/telephony/euicc/DownloadableSubscription.java
+++ b/telephony/java/android/telephony/euicc/DownloadableSubscription.java
@@ -16,18 +16,17 @@
package android.telephony.euicc;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.UiccAccessRule;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import com.android.internal.util.Preconditions;
-/**
- * Information about a subscription which is available for download.
- *
- * TODO(b/35851809): Make this public.
- * @hide
- */
+/** Information about a subscription which is available for download. */
public final class DownloadableSubscription implements Parcelable {
public static final Creator<DownloadableSubscription> CREATOR =
@@ -46,11 +45,12 @@
/**
* Activation code. May be null for subscriptions which are not based on activation codes, e.g.
* to download a default subscription assigned to this device.
+ * Should use getEncodedActivationCode() instead.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
+ * @deprecated - Do not use. This will be private. Use getEncodedActivationCode() instead.
*/
@Nullable
+ @Deprecated
public final String encodedActivationCode;
@Nullable private String confirmationCode;
@@ -58,8 +58,16 @@
// see getCarrierName and setCarrierName
@Nullable
private String carrierName;
+
// see getAccessRules and setAccessRules
- private UiccAccessRule[] accessRules;
+ @Nullable
+ private List<UiccAccessRule> accessRules;
+
+ /** Gets the activation code. */
+ @Nullable
+ public String getEncodedActivationCode() {
+ return encodedActivationCode;
+ }
/** @hide */
private DownloadableSubscription(String encodedActivationCode) {
@@ -70,7 +78,59 @@
encodedActivationCode = in.readString();
confirmationCode = in.readString();
carrierName = in.readString();
- accessRules = in.createTypedArray(UiccAccessRule.CREATOR);
+ accessRules = new ArrayList<UiccAccessRule>();
+ in.readTypedList(accessRules, UiccAccessRule.CREATOR);
+ }
+
+ private DownloadableSubscription(String encodedActivationCode, String confirmationCode,
+ String carrierName, List<UiccAccessRule> accessRules) {
+ this.encodedActivationCode = encodedActivationCode;
+ this.confirmationCode = confirmationCode;
+ this.carrierName = carrierName;
+ this.accessRules = accessRules;
+ }
+
+ /** @hide */
+ @SystemApi
+ public static final class Builder {
+ @Nullable private String encodedActivationCode;
+ @Nullable private String confirmationCode;
+ @Nullable private String carrierName;
+ List<UiccAccessRule> accessRules;
+
+ public Builder() {}
+
+ public Builder(DownloadableSubscription baseSubscription) {
+ encodedActivationCode = baseSubscription.getEncodedActivationCode();
+ confirmationCode = baseSubscription.getConfirmationCode();
+ carrierName = baseSubscription.getCarrierName();
+ accessRules = baseSubscription.getAccessRules();
+ }
+
+ public DownloadableSubscription build() {
+ return new DownloadableSubscription(encodedActivationCode, confirmationCode,
+ carrierName, accessRules);
+ }
+
+ public Builder setEncodedActivationCode(String value) {
+ encodedActivationCode = value;
+ return this;
+ }
+
+ public Builder setConfirmationCode(String value) {
+ confirmationCode = value;
+ return this;
+ }
+
+ public Builder setCarrierName(String value) {
+ carrierName = value;
+ return this;
+ }
+
+ public Builder setAccessRules(List<UiccAccessRule> value) {
+ accessRules = value;
+ return this;
+ }
}
/**
@@ -87,7 +147,10 @@
/**
* Sets the confirmation code.
+ * @hide
+ * @deprecated - Do not use.
*/
+ @Deprecated
public void setConfirmationCode(String confirmationCode) {
this.confirmationCode = confirmationCode;
}
@@ -103,9 +166,9 @@
/**
* Set the user-visible carrier name.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
+ * @deprecated - Do not use.
*/
+ @Deprecated
public void setCarrierName(String carrierName) {
this.carrierName = carrierName;
}
@@ -117,44 +180,51 @@
* those created with {@link #forActivationCode}). May be populated with
* {@link EuiccManager#getDownloadableSubscriptionMetadata}.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+ @SystemApi
@Nullable
public String getCarrierName() {
return carrierName;
}
/**
- * Returns the {@link UiccAccessRule}s dictating access to this subscription.
+ * Returns the {@link UiccAccessRule}s in list dictating access to this subscription.
*
* <p>Only present for downloadable subscriptions that were queried from a server (as opposed to
* those created with {@link #forActivationCode}). May be populated with
* {@link EuiccManager#getDownloadableSubscriptionMetadata}.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
- public UiccAccessRule[] getAccessRules() {
+ @SystemApi
+ public List<UiccAccessRule> getAccessRules() {
return accessRules;
}
/**
* Set the {@link UiccAccessRule}s dictating access to this subscription.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
+ * @deprecated - Do not use.
*/
- public void setAccessRules(UiccAccessRule[] accessRules) {
+ @Deprecated
+ public void setAccessRules(List<UiccAccessRule> accessRules) {
this.accessRules = accessRules;
}
+ /**
+ * @hide
+ * @deprecated - Do not use.
+ */
+ @Deprecated
+ public void setAccessRules(UiccAccessRule[] accessRules) {
+ this.accessRules = Arrays.asList(accessRules);
+ }
+
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(encodedActivationCode);
dest.writeString(confirmationCode);
dest.writeString(carrierName);
- dest.writeTypedArray(accessRules, flags);
+ dest.writeTypedList(accessRules);
}
@Override
diff --git a/telephony/java/android/telephony/euicc/EuiccCardManager.java b/telephony/java/android/telephony/euicc/EuiccCardManager.java
index a1a6a5a..c3f4007 100644
--- a/telephony/java/android/telephony/euicc/EuiccCardManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccCardManager.java
@@ -17,6 +17,7 @@
import android.annotation.IntDef;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -49,14 +50,14 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import android.annotation.CallbackExecutor;
+import java.util.concurrent.Executor;
/**
* EuiccCardManager is the application interface to an eSIM card.
- *
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+@SystemApi
public class EuiccCardManager {
private static final String TAG = "EuiccCardManager";
@@ -68,6 +69,7 @@
CANCEL_REASON_TIMEOUT,
CANCEL_REASON_PPR_NOT_ALLOWED
})
+ /** @hide */
public @interface CancelReason {}
/**
@@ -96,6 +98,7 @@
RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES,
RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS
})
+ /** @hide */
public @interface ResetOption {}
/** Deletes all operational profiles. */
@@ -143,18 +146,20 @@
}
/**
- * Gets all the profiles on eUicc.
+ * Requests all the profiles on eUicc.
*
* @param cardId The Id of the eUICC.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code and all the profiles.
*/
- public void getAllProfiles(String cardId, ResultCallback<EuiccProfileInfo[]> callback) {
+ public void requestAllProfiles(String cardId, @CallbackExecutor Executor executor,
+ ResultCallback<EuiccProfileInfo[]> callback) {
try {
getIEuiccCardController().getAllProfiles(mContext.getOpPackageName(), cardId,
new IGetAllProfilesCallback.Stub() {
@Override
public void onComplete(int resultCode, EuiccProfileInfo[] profiles) {
- callback.onComplete(resultCode, profiles);
+ executor.execute(() -> callback.onComplete(resultCode, profiles));
}
});
} catch (RemoteException e) {
@@ -164,19 +169,21 @@
}
/**
- * Gets the profile of the given iccid.
+ * Requests the profile of the given iccid.
*
* @param cardId The Id of the eUICC.
* @param iccid The iccid of the profile.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code and profile.
*/
- public void getProfile(String cardId, String iccid, ResultCallback<EuiccProfileInfo> callback) {
+ public void requestProfile(String cardId, String iccid, @CallbackExecutor Executor executor,
+ ResultCallback<EuiccProfileInfo> callback) {
try {
getIEuiccCardController().getProfile(mContext.getOpPackageName(), cardId, iccid,
new IGetProfileCallback.Stub() {
@Override
public void onComplete(int resultCode, EuiccProfileInfo profile) {
- callback.onComplete(resultCode, profile);
+ executor.execute(() -> callback.onComplete(resultCode, profile));
}
});
} catch (RemoteException e) {
@@ -191,16 +198,17 @@
* @param cardId The Id of the eUICC.
* @param iccid The iccid of the profile.
* @param refresh Whether sending the REFRESH command to modem.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code.
*/
public void disableProfile(String cardId, String iccid, boolean refresh,
- ResultCallback<Void> callback) {
+ @CallbackExecutor Executor executor, ResultCallback<Void> callback) {
try {
getIEuiccCardController().disableProfile(mContext.getOpPackageName(), cardId, iccid,
refresh, new IDisableProfileCallback.Stub() {
@Override
public void onComplete(int resultCode) {
- callback.onComplete(resultCode, null);
+ executor.execute(() -> callback.onComplete(resultCode, null));
}
});
} catch (RemoteException e) {
@@ -216,16 +224,17 @@
* @param cardId The Id of the eUICC.
* @param iccid The iccid of the profile to switch to.
* @param refresh Whether sending the REFRESH command to modem.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code and the EuiccProfileInfo enabled.
*/
public void switchToProfile(String cardId, String iccid, boolean refresh,
- ResultCallback<EuiccProfileInfo> callback) {
+ @CallbackExecutor Executor executor, ResultCallback<EuiccProfileInfo> callback) {
try {
getIEuiccCardController().switchToProfile(mContext.getOpPackageName(), cardId, iccid,
refresh, new ISwitchToProfileCallback.Stub() {
@Override
public void onComplete(int resultCode, EuiccProfileInfo profile) {
- callback.onComplete(resultCode, profile);
+ executor.execute(() -> callback.onComplete(resultCode, profile));
}
});
} catch (RemoteException e) {
@@ -240,16 +249,17 @@
* @param cardId The Id of the eUICC.
* @param iccid The iccid of the profile.
* @param nickname The nickname of the profile.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code.
*/
public void setNickname(String cardId, String iccid, String nickname,
- ResultCallback<Void> callback) {
+ @CallbackExecutor Executor executor, ResultCallback<Void> callback) {
try {
getIEuiccCardController().setNickname(mContext.getOpPackageName(), cardId, iccid,
nickname, new ISetNicknameCallback.Stub() {
@Override
public void onComplete(int resultCode) {
- callback.onComplete(resultCode, null);
+ executor.execute(() -> callback.onComplete(resultCode, null));
}
});
} catch (RemoteException e) {
@@ -263,15 +273,17 @@
*
* @param cardId The Id of the eUICC.
* @param iccid The iccid of the profile.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code.
*/
- public void deleteProfile(String cardId, String iccid, ResultCallback<Void> callback) {
+ public void deleteProfile(String cardId, String iccid, @CallbackExecutor Executor executor,
+ ResultCallback<Void> callback) {
try {
getIEuiccCardController().deleteProfile(mContext.getOpPackageName(), cardId, iccid,
new IDeleteProfileCallback.Stub() {
@Override
public void onComplete(int resultCode) {
- callback.onComplete(resultCode, null);
+ executor.execute(() -> callback.onComplete(resultCode, null));
}
});
} catch (RemoteException e) {
@@ -286,15 +298,17 @@
* @param cardId The Id of the eUICC.
* @param options Bits of the options of resetting which parts of the eUICC memory. See
* EuiccCard for details.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code.
*/
- public void resetMemory(String cardId, @ResetOption int options, ResultCallback<Void> callback) {
+ public void resetMemory(String cardId, @ResetOption int options,
+ @CallbackExecutor Executor executor, ResultCallback<Void> callback) {
try {
getIEuiccCardController().resetMemory(mContext.getOpPackageName(), cardId, options,
new IResetMemoryCallback.Stub() {
@Override
public void onComplete(int resultCode) {
- callback.onComplete(resultCode, null);
+ executor.execute(() -> callback.onComplete(resultCode, null));
}
});
} catch (RemoteException e) {
@@ -304,18 +318,20 @@
}
/**
- * Gets the default SM-DP+ address from eUICC.
+ * Requests the default SM-DP+ address from eUICC.
*
* @param cardId The Id of the eUICC.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code and the default SM-DP+ address.
*/
- public void getDefaultSmdpAddress(String cardId, ResultCallback<String> callback) {
+ public void requestDefaultSmdpAddress(String cardId, @CallbackExecutor Executor executor,
+ ResultCallback<String> callback) {
try {
getIEuiccCardController().getDefaultSmdpAddress(mContext.getOpPackageName(), cardId,
new IGetDefaultSmdpAddressCallback.Stub() {
@Override
public void onComplete(int resultCode, String address) {
- callback.onComplete(resultCode, address);
+ executor.execute(() -> callback.onComplete(resultCode, address));
}
});
} catch (RemoteException e) {
@@ -325,18 +341,20 @@
}
/**
- * Gets the SM-DS address from eUICC.
+ * Requests the SM-DS address from eUICC.
*
* @param cardId The Id of the eUICC.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code and the SM-DS address.
*/
- public void getSmdsAddress(String cardId, ResultCallback<String> callback) {
+ public void requestSmdsAddress(String cardId, @CallbackExecutor Executor executor,
+ ResultCallback<String> callback) {
try {
getIEuiccCardController().getSmdsAddress(mContext.getOpPackageName(), cardId,
new IGetSmdsAddressCallback.Stub() {
@Override
public void onComplete(int resultCode, String address) {
- callback.onComplete(resultCode, address);
+ executor.execute(() -> callback.onComplete(resultCode, address));
}
});
} catch (RemoteException e) {
@@ -350,16 +368,18 @@
*
* @param cardId The Id of the eUICC.
* @param defaultSmdpAddress The default SM-DP+ address to set.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code.
*/
- public void setDefaultSmdpAddress(String cardId, String defaultSmdpAddress, ResultCallback<Void> callback) {
+ public void setDefaultSmdpAddress(String cardId, String defaultSmdpAddress,
+ @CallbackExecutor Executor executor, ResultCallback<Void> callback) {
try {
getIEuiccCardController().setDefaultSmdpAddress(mContext.getOpPackageName(), cardId,
defaultSmdpAddress,
new ISetDefaultSmdpAddressCallback.Stub() {
@Override
public void onComplete(int resultCode) {
- callback.onComplete(resultCode, null);
+ executor.execute(() -> callback.onComplete(resultCode, null));
}
});
} catch (RemoteException e) {
@@ -369,18 +389,20 @@
}
/**
- * Gets Rules Authorisation Table.
+ * Requests Rules Authorisation Table.
*
* @param cardId The Id of the eUICC.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and the rule authorisation table.
*/
- public void getRulesAuthTable(String cardId, ResultCallback<EuiccRulesAuthTable> callback) {
+ public void requestRulesAuthTable(String cardId, @CallbackExecutor Executor executor,
+ ResultCallback<EuiccRulesAuthTable> callback) {
try {
getIEuiccCardController().getRulesAuthTable(mContext.getOpPackageName(), cardId,
new IGetRulesAuthTableCallback.Stub() {
@Override
public void onComplete(int resultCode, EuiccRulesAuthTable rat) {
- callback.onComplete(resultCode, rat);
+ executor.execute(() -> callback.onComplete(resultCode, rat));
}
});
} catch (RemoteException e) {
@@ -390,18 +412,20 @@
}
/**
- * Gets the eUICC challenge for new profile downloading.
+ * Requests the eUICC challenge for new profile downloading.
*
* @param cardId The Id of the eUICC.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and the challenge.
*/
- public void getEuiccChallenge(String cardId, ResultCallback<byte[]> callback) {
+ public void requestEuiccChallenge(String cardId, @CallbackExecutor Executor executor,
+ ResultCallback<byte[]> callback) {
try {
getIEuiccCardController().getEuiccChallenge(mContext.getOpPackageName(), cardId,
new IGetEuiccChallengeCallback.Stub() {
@Override
public void onComplete(int resultCode, byte[] challenge) {
- callback.onComplete(resultCode, challenge);
+ executor.execute(() -> callback.onComplete(resultCode, challenge));
}
});
} catch (RemoteException e) {
@@ -411,18 +435,20 @@
}
/**
- * Gets the eUICC info1 defined in GSMA RSP v2.0+ for new profile downloading.
+ * Requests the eUICC info1 defined in GSMA RSP v2.0+ for new profile downloading.
*
* @param cardId The Id of the eUICC.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and the info1.
*/
- public void getEuiccInfo1(String cardId, ResultCallback<byte[]> callback) {
+ public void requestEuiccInfo1(String cardId, @CallbackExecutor Executor executor,
+ ResultCallback<byte[]> callback) {
try {
getIEuiccCardController().getEuiccInfo1(mContext.getOpPackageName(), cardId,
new IGetEuiccInfo1Callback.Stub() {
@Override
public void onComplete(int resultCode, byte[] info) {
- callback.onComplete(resultCode, info);
+ executor.execute(() -> callback.onComplete(resultCode, info));
}
});
} catch (RemoteException e) {
@@ -435,15 +461,17 @@
* Gets the eUICC info2 defined in GSMA RSP v2.0+ for new profile downloading.
*
* @param cardId The Id of the eUICC.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and the info2.
*/
- public void getEuiccInfo2(String cardId, ResultCallback<byte[]> callback) {
+ public void requestEuiccInfo2(String cardId, @CallbackExecutor Executor executor,
+ ResultCallback<byte[]> callback) {
try {
getIEuiccCardController().getEuiccInfo2(mContext.getOpPackageName(), cardId,
new IGetEuiccInfo2Callback.Stub() {
@Override
public void onComplete(int resultCode, byte[] info) {
- callback.onComplete(resultCode, info);
+ executor.execute(() -> callback.onComplete(resultCode, info));
}
});
} catch (RemoteException e) {
@@ -466,12 +494,13 @@
* GSMA RSP v2.0+.
* @param serverCertificate ASN.1 data in byte array indicating SM-DP+ Certificate returned by
* SM-DP+ server.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and a byte array which represents a
* {@code AuthenticateServerResponse} defined in GSMA RSP v2.0+.
*/
public void authenticateServer(String cardId, String matchingId, byte[] serverSigned1,
byte[] serverSignature1, byte[] euiccCiPkIdToBeUsed, byte[] serverCertificate,
- ResultCallback<byte[]> callback) {
+ @CallbackExecutor Executor executor, ResultCallback<byte[]> callback) {
try {
getIEuiccCardController().authenticateServer(
mContext.getOpPackageName(),
@@ -484,7 +513,7 @@
new IAuthenticateServerCallback.Stub() {
@Override
public void onComplete(int resultCode, byte[] response) {
- callback.onComplete(resultCode, response);
+ executor.execute(() -> callback.onComplete(resultCode, response));
}
});
} catch (RemoteException e) {
@@ -505,11 +534,13 @@
* SM-DP+ server.
* @param smdpCertificate ASN.1 data in byte array indicating the SM-DP+ Certificate returned
* by SM-DP+ server.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and a byte array which represents a
* {@code PrepareDownloadResponse} defined in GSMA RSP v2.0+
*/
public void prepareDownload(String cardId, @Nullable byte[] hashCc, byte[] smdpSigned2,
- byte[] smdpSignature2, byte[] smdpCertificate, ResultCallback<byte[]> callback) {
+ byte[] smdpSignature2, byte[] smdpCertificate, @CallbackExecutor Executor executor,
+ ResultCallback<byte[]> callback) {
try {
getIEuiccCardController().prepareDownload(
mContext.getOpPackageName(),
@@ -521,7 +552,7 @@
new IPrepareDownloadCallback.Stub() {
@Override
public void onComplete(int resultCode, byte[] response) {
- callback.onComplete(resultCode, response);
+ executor.execute(() -> callback.onComplete(resultCode, response));
}
});
} catch (RemoteException e) {
@@ -535,11 +566,12 @@
*
* @param cardId The Id of the eUICC.
* @param boundProfilePackage the Bound Profile Package data returned by SM-DP+ server.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and a byte array which represents a
* {@code LoadBoundProfilePackageResponse} defined in GSMA RSP v2.0+.
*/
public void loadBoundProfilePackage(String cardId, byte[] boundProfilePackage,
- ResultCallback<byte[]> callback) {
+ @CallbackExecutor Executor executor, ResultCallback<byte[]> callback) {
try {
getIEuiccCardController().loadBoundProfilePackage(
mContext.getOpPackageName(),
@@ -548,7 +580,7 @@
new ILoadBoundProfilePackageCallback.Stub() {
@Override
public void onComplete(int resultCode, byte[] response) {
- callback.onComplete(resultCode, response);
+ executor.execute(() -> callback.onComplete(resultCode, response));
}
});
} catch (RemoteException e) {
@@ -563,11 +595,12 @@
* @param cardId The Id of the eUICC.
* @param transactionId the transaction ID returned by SM-DP+ server.
* @param reason the cancel reason.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and an byte[] which represents a
* {@code CancelSessionResponse} defined in GSMA RSP v2.0+.
*/
public void cancelSession(String cardId, byte[] transactionId, @CancelReason int reason,
- ResultCallback<byte[]> callback) {
+ @CallbackExecutor Executor executor, ResultCallback<byte[]> callback) {
try {
getIEuiccCardController().cancelSession(
mContext.getOpPackageName(),
@@ -577,7 +610,7 @@
new ICancelSessionCallback.Stub() {
@Override
public void onComplete(int resultCode, byte[] response) {
- callback.onComplete(resultCode, response);
+ executor.execute(() -> callback.onComplete(resultCode, response));
}
});
} catch (RemoteException e) {
@@ -591,16 +624,17 @@
*
* @param cardId The Id of the eUICC.
* @param events bits of the event types ({@link EuiccNotification.Event}) to list.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and the list of notifications.
*/
public void listNotifications(String cardId, @EuiccNotification.Event int events,
- ResultCallback<EuiccNotification[]> callback) {
+ @CallbackExecutor Executor executor, ResultCallback<EuiccNotification[]> callback) {
try {
getIEuiccCardController().listNotifications(mContext.getOpPackageName(), cardId, events,
new IListNotificationsCallback.Stub() {
@Override
public void onComplete(int resultCode, EuiccNotification[] notifications) {
- callback.onComplete(resultCode, notifications);
+ executor.execute(() -> callback.onComplete(resultCode, notifications));
}
});
} catch (RemoteException e) {
@@ -614,16 +648,17 @@
*
* @param cardId The Id of the eUICC.
* @param events bits of the event types ({@link EuiccNotification.Event}) to list.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and the list of notifications.
*/
public void retrieveNotificationList(String cardId, @EuiccNotification.Event int events,
- ResultCallback<EuiccNotification[]> callback) {
+ @CallbackExecutor Executor executor, ResultCallback<EuiccNotification[]> callback) {
try {
getIEuiccCardController().retrieveNotificationList(mContext.getOpPackageName(), cardId,
events, new IRetrieveNotificationListCallback.Stub() {
@Override
public void onComplete(int resultCode, EuiccNotification[] notifications) {
- callback.onComplete(resultCode, notifications);
+ executor.execute(() -> callback.onComplete(resultCode, notifications));
}
});
} catch (RemoteException e) {
@@ -637,16 +672,17 @@
*
* @param cardId The Id of the eUICC.
* @param seqNumber the sequence number of the notification.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and the notification.
*/
public void retrieveNotification(String cardId, int seqNumber,
- ResultCallback<EuiccNotification> callback) {
+ @CallbackExecutor Executor executor, ResultCallback<EuiccNotification> callback) {
try {
getIEuiccCardController().retrieveNotification(mContext.getOpPackageName(), cardId,
seqNumber, new IRetrieveNotificationCallback.Stub() {
@Override
public void onComplete(int resultCode, EuiccNotification notification) {
- callback.onComplete(resultCode, notification);
+ executor.execute(() -> callback.onComplete(resultCode, notification));
}
});
} catch (RemoteException e) {
@@ -660,10 +696,11 @@
*
* @param cardId The Id of the eUICC.
* @param seqNumber the sequence number of the notification.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code.
*/
public void removeNotificationFromList(String cardId, int seqNumber,
- ResultCallback<Void> callback) {
+ @CallbackExecutor Executor executor, ResultCallback<Void> callback) {
try {
getIEuiccCardController().removeNotificationFromList(
mContext.getOpPackageName(),
@@ -672,7 +709,7 @@
new IRemoveNotificationFromListCallback.Stub() {
@Override
public void onComplete(int resultCode) {
- callback.onComplete(resultCode, null);
+ executor.execute(() -> callback.onComplete(resultCode, null));
}
});
} catch (RemoteException e) {
diff --git a/telephony/java/android/telephony/euicc/EuiccInfo.java b/telephony/java/android/telephony/euicc/EuiccInfo.java
index 5bfff08..a4adf05 100644
--- a/telephony/java/android/telephony/euicc/EuiccInfo.java
+++ b/telephony/java/android/telephony/euicc/EuiccInfo.java
@@ -23,9 +23,6 @@
* Information about an eUICC chip/device.
*
* @see EuiccManager#getEuiccInfo
- * @hide
- *
- * TODO(b/35851809): Make this public.
*/
// WARNING: Do not add any privacy-sensitive fields to this class (such as an eUICC identifier)!
// This API is accessible to all applications. Privacy-sensitive fields should be returned in their
@@ -45,12 +42,17 @@
}
};
+ @Nullable
+ private final String osVersion;
+
/**
- * Version of the operating system running on the eUICC. This field is hardware-specific and is
- * not guaranteed to match any particular format.
+ * Gets the version of the operating system running on the eUICC. This field is
+ * hardware-specific and is not guaranteed to match any particular format.
*/
@Nullable
- public final String osVersion;
+ public String getOsVersion() {
+ return osVersion;
+ }
public EuiccInfo(@Nullable String osVersion) {
this.osVersion = osVersion;
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index 7f913ce..1637c55 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -42,9 +42,6 @@
* {@link Context#getSystemService(String)} and {@link Context#EUICC_SERVICE}.
*
* <p>See {@link #isEnabled} before attempting to use these APIs.
- *
- * TODO(b/35851809): Make this public.
- * @hide
*/
public class EuiccManager {
@@ -56,6 +53,8 @@
*
* <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if
* {@link #isEnabled} is false.
+ *
+ * This is ued by non-LPA app to bring up LUI.
*/
@SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS =
@@ -69,8 +68,10 @@
*
* <p class="note">This is a protected intent that can only be sent
* by the system.
- * TODO(b/35851809): Make this a SystemApi.
+ *
+ * @hide
*/
+ @SystemApi
@SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_OTA_STATUS_CHANGED =
"android.telephony.euicc.action.OTA_STATUS_CHANGED";
@@ -78,12 +79,10 @@
/**
* Broadcast Action: The action sent to carrier app so it knows the carrier setup is not
* completed.
- *
- * TODO(b/35851809): Make this a public API.
*/
@SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_NOTIFY_CARRIER_SETUP =
- "android.telephony.euicc.action.NOTIFY_CARRIER_SETUP";
+ public static final String ACTION_NOTIFY_CARRIER_SETUP_INCOMPLETE =
+ "android.telephony.euicc.action.NOTIFY_CARRIER_SETUP_INCOMPLETE";
/**
* Intent action to provision an embedded subscription.
@@ -95,8 +94,9 @@
* <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if
* {@link #isEnabled} is false.
*
- * TODO(b/35851809): Make this a SystemApi.
+ * @hide
*/
+ @SystemApi
@SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION =
"android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION";
@@ -143,9 +143,8 @@
* Key for an extra set on {@link #getDownloadableSubscriptionMetadata} PendingIntent result
* callbacks providing the downloadable subscription metadata.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+ @SystemApi
public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION =
"android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION";
@@ -153,9 +152,8 @@
* Key for an extra set on {@link #getDefaultDownloadableSubscriptionList} PendingIntent result
* callbacks providing the list of available downloadable subscriptions.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+ @SystemApi
public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS =
"android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS";
@@ -201,6 +199,7 @@
* Euicc OTA update status which can be got by {@link #getOtaStatus}
* @hide
*/
+ @SystemApi
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"EUICC_OTA_"}, value = {
EUICC_OTA_IN_PROGRESS,
@@ -215,15 +214,37 @@
/**
* An OTA is in progress. During this time, the eUICC is not available and the user may lose
* network access.
+ * @hide
*/
+ @SystemApi
public static final int EUICC_OTA_IN_PROGRESS = 1;
- /** The OTA update failed. */
+
+ /**
+ * The OTA update failed.
+ * @hide
+ */
+ @SystemApi
public static final int EUICC_OTA_FAILED = 2;
- /** The OTA update finished successfully. */
+
+ /**
+ * The OTA update finished successfully.
+ * @hide
+ */
+ @SystemApi
public static final int EUICC_OTA_SUCCEEDED = 3;
- /** The OTA update not needed since current eUICC OS is latest. */
+
+ /**
+ * The OTA update not needed since current eUICC OS is latest.
+ * @hide
+ */
+ @SystemApi
public static final int EUICC_OTA_NOT_NEEDED = 4;
- /** The OTA status is unavailable since eUICC service is unavailable. */
+
+ /**
+ * The OTA status is unavailable since eUICC service is unavailable.
+ * @hide
+ */
+ @SystemApi
public static final int EUICC_OTA_STATUS_UNAVAILABLE = 5;
private final Context mContext;
@@ -276,8 +297,10 @@
*
* @return the status of eUICC OTA. If {@link #isEnabled()} is false or the eUICC is not ready,
* {@link OtaStatus#EUICC_OTA_STATUS_UNAVAILABLE} will be returned.
- * TODO(b/35851809): Make this a SystemApi.
+ *
+ * @hide
*/
+ @SystemApi
public int getOtaStatus() {
if (!isEnabled()) {
return EUICC_OTA_STATUS_UNAVAILABLE;
@@ -292,7 +315,7 @@
/**
* Attempt to download the given {@link DownloadableSubscription}.
*
- * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
+ * <p>Requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
* or the calling app must be authorized to manage both the currently-active subscription and
* the subscription to be downloaded according to the subscription metadata. Without the former,
* an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback
@@ -354,14 +377,16 @@
*
* <p>To be called by the LUI upon completion of a resolvable error flow.
*
+ * <p>Requires that the calling app has the
+ * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
+ *
* @param resolutionIntent The original intent used to start the LUI.
* @param resolutionExtras Resolution-specific extras depending on the result of the resolution.
* For example, this may indicate whether the user has consented or may include the input
* they provided.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+ @SystemApi
public void continueOperation(Intent resolutionIntent, Bundle resolutionExtras) {
if (!isEnabled()) {
PendingIntent callbackIntent =
@@ -395,9 +420,8 @@
* @param subscription the subscription which needs metadata filled in
* @param callbackIntent a PendingIntent to launch when the operation completes.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+ @SystemApi
public void getDownloadableSubscriptionMetadata(
DownloadableSubscription subscription, PendingIntent callbackIntent) {
if (!isEnabled()) {
@@ -426,9 +450,8 @@
*
* @param callbackIntent a PendingIntent to launch when the operation completes.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+ @SystemApi
public void getDefaultDownloadableSubscriptionList(PendingIntent callbackIntent) {
if (!isEnabled()) {
sendUnavailableError(callbackIntent);
@@ -468,7 +491,7 @@
*
* <p>Requires that the calling app has carrier privileges according to the metadata of the
* profile to be deleted, or the
- * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
+ * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
*
* @param subscriptionId the ID of the subscription to delete.
* @param callbackIntent a PendingIntent to launch when the operation completes.
@@ -489,7 +512,7 @@
/**
* Switch to (enable) the given subscription.
*
- * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
+ * <p>Requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
* or the calling app must be authorized to manage both the currently-active subscription and
* the subscription to be enabled according to the subscription metadata. Without the former,
* an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback
@@ -599,11 +622,7 @@
}
}
- /**
- * @hide
- */
- @TestApi
- protected IEuiccController getIEuiccController() {
+ private static IEuiccController getIEuiccController() {
return IEuiccController.Stub.asInterface(ServiceManager.getService("econtroller"));
}
}
diff --git a/telephony/java/android/telephony/euicc/EuiccNotification.java b/telephony/java/android/telephony/euicc/EuiccNotification.java
index ef3c1ce..43a7707 100644
--- a/telephony/java/android/telephony/euicc/EuiccNotification.java
+++ b/telephony/java/android/telephony/euicc/EuiccNotification.java
@@ -17,6 +17,7 @@
import android.annotation.IntDef;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -31,10 +32,9 @@
* disabling, or deleting).
*
* @hide
- *
- * TODO(b/35851809): Make this a @SystemApi.
*/
-public class EuiccNotification implements Parcelable {
+@SystemApi
+public final class EuiccNotification implements Parcelable {
/** Event */
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, prefix = { "EVENT_" }, value = {
@@ -43,6 +43,7 @@
EVENT_DISABLE,
EVENT_DELETE
})
+ /** @hide */
public @interface Event {}
/** A profile is downloaded and installed. */
@@ -57,7 +58,7 @@
/** A profile is deleted. */
public static final int EVENT_DELETE = 1 << 3;
- /** Value of the bits of all above events */
+ /** Value of the bits of all the events including install, enable, disable and delete. */
@Event
public static final int ALL_EVENTS =
EVENT_INSTALL | EVENT_ENABLE | EVENT_DISABLE | EVENT_DELETE;
diff --git a/telephony/java/android/telephony/euicc/EuiccRulesAuthTable.java b/telephony/java/android/telephony/euicc/EuiccRulesAuthTable.java
index 7efe043..67ae983 100644
--- a/telephony/java/android/telephony/euicc/EuiccRulesAuthTable.java
+++ b/telephony/java/android/telephony/euicc/EuiccRulesAuthTable.java
@@ -16,6 +16,7 @@
package android.telephony.euicc;
import android.annotation.IntDef;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.service.carrier.CarrierIdentifier;
@@ -27,20 +28,21 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
/**
* This represents the RAT (Rules Authorisation Table) stored on eUICC.
- *
* @hide
- *
- * TODO(b/35851809): Make this a @SystemApi.
*/
+@SystemApi
public final class EuiccRulesAuthTable implements Parcelable {
/** Profile policy rule flags */
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, prefix = { "POLICY_RULE_FLAG_" }, value = {
POLICY_RULE_FLAG_CONSENT_REQUIRED
})
+ /** @hide */
public @interface PolicyRuleFlag {}
/** User consent is required to install the profile. */
@@ -89,12 +91,14 @@
* @throws ArrayIndexOutOfBoundsException If the {@code mPosition} is larger than the size
* this table.
*/
- public Builder add(int policyRules, CarrierIdentifier[] carrierId, int policyRuleFlags) {
+ public Builder add(int policyRules, List<CarrierIdentifier> carrierId, int policyRuleFlags) {
if (mPosition >= mPolicyRules.length) {
throw new ArrayIndexOutOfBoundsException(mPosition);
}
mPolicyRules[mPosition] = policyRules;
- mCarrierIds[mPosition] = carrierId;
+ if (carrierId != null && carrierId.size() > 0) {
+ mCarrierIds[mPosition] = carrierId.toArray(new CarrierIdentifier[carrierId.size()]);
+ }
mPolicyRuleFlags[mPosition] = policyRuleFlags;
mPosition++;
return this;
diff --git a/tests/FrameworkPerf/AndroidManifest.xml b/tests/FrameworkPerf/AndroidManifest.xml
index d62ef9e..2591aaf 100644
--- a/tests/FrameworkPerf/AndroidManifest.xml
+++ b/tests/FrameworkPerf/AndroidManifest.xml
@@ -1,6 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.frameworkperf">
- <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-sdk android:minSdkVersion="5" />
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/DrawIntoHwBitmapActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/DrawIntoHwBitmapActivity.java
index faabdfc..af8e10b 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/DrawIntoHwBitmapActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/DrawIntoHwBitmapActivity.java
@@ -27,6 +27,7 @@
import android.graphics.Color;
import android.graphics.GraphicBuffer;
import android.graphics.Paint;
+import android.graphics.Picture;
import android.graphics.PixelFormat;
import android.graphics.SurfaceTexture;
import android.os.Bundle;
@@ -47,10 +48,8 @@
}
Bitmap createBitmap() {
- RenderNode node = RenderNode.create("HwuiCanvas", null);
- node.setLeftTopRightBottom(0, 0, 500, 500);
- node.setClipToBounds(false);
- DisplayListCanvas canvas = node.start(500, 500);
+ Picture picture = new Picture();
+ Canvas canvas = picture.beginRecording(500, 500);
Paint p = new Paint();
p.setColor(Color.BLACK);
p.setTextSize(20 * getResources().getDisplayMetrics().density);
@@ -59,7 +58,7 @@
canvas.drawRect(0, 0, 500, 100, p);
p.setColor(Color.BLACK);
canvas.drawText("Hello, World!", 0, 90, p);
- node.end(canvas);
- return ThreadedRenderer.createHardwareBitmap(node, 500, 500);
+ picture.endRecording();
+ return Bitmap.createBitmap(picture);
}
}
diff --git a/tests/OneMedia/AndroidManifest.xml b/tests/OneMedia/AndroidManifest.xml
index 8697f1b..c6824ec 100644
--- a/tests/OneMedia/AndroidManifest.xml
+++ b/tests/OneMedia/AndroidManifest.xml
@@ -5,7 +5,6 @@
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="19"/>
- <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
diff --git a/tools/sdkparcelables/src/com/android/sdkparcelables/ParcelableDetector.kt b/tools/sdkparcelables/src/com/android/sdkparcelables/ParcelableDetector.kt
index d6a0a45..45027b5 100644
--- a/tools/sdkparcelables/src/com/android/sdkparcelables/ParcelableDetector.kt
+++ b/tools/sdkparcelables/src/com/android/sdkparcelables/ParcelableDetector.kt
@@ -27,6 +27,8 @@
impl.build()
return impl.parcelables
}
+
+ const val PARCELABLE_CLASS = "android/os/Parcelable"
}
private class Impl(val ancestors: Map<String, Ancestors>) {
@@ -35,7 +37,7 @@
fun build() {
val classList = ancestors.keys
- classList.filterTo(parcelables, this::isParcelable)
+ classList.filterTo(parcelables, { (it != PARCELABLE_CLASS) && isParcelable(it) })
parcelables.sort()
}
@@ -44,7 +46,7 @@
return false
}
- if (c == "android/os/Parcelable") {
+ if (c == PARCELABLE_CLASS) {
return true
}
diff --git a/tools/sdkparcelables/tests/com/android/sdkparcelables/ParcelableDetectorTest.kt b/tools/sdkparcelables/tests/com/android/sdkparcelables/ParcelableDetectorTest.kt
index c9bcbc9..f08173d 100644
--- a/tools/sdkparcelables/tests/com/android/sdkparcelables/ParcelableDetectorTest.kt
+++ b/tools/sdkparcelables/tests/com/android/sdkparcelables/ParcelableDetectorTest.kt
@@ -28,7 +28,7 @@
val parcelables = ParcelableDetector.ancestorsToParcelables(ancestorMap)
- assertEquals(parcelables, listOf("android/os/Parcelable", "android/test/Parcelable"))
+ assertEquals(parcelables, listOf("android/test/Parcelable"))
}
@Test
@@ -39,7 +39,7 @@
val parcelables = ParcelableDetector.ancestorsToParcelables(ancestorMap)
- assertEquals(parcelables, listOf("android/os/Parcelable", "android/test/Parcelable"))
+ assertEquals(parcelables, listOf("android/test/Parcelable"))
}
@Test
@@ -51,7 +51,7 @@
val parcelables = ParcelableDetector.ancestorsToParcelables(ancestorMap)
- assertEquals(parcelables, listOf("android/os/Parcelable", "android/test/Parcelable", "android/test/SuperParcelable"))
+ assertEquals(parcelables, listOf("android/test/Parcelable", "android/test/SuperParcelable"))
}
@Test
@@ -63,7 +63,7 @@
val parcelables = ParcelableDetector.ancestorsToParcelables(ancestorMap)
- assertEquals(parcelables, listOf("android/os/Parcelable", "android/test/IParcelable", "android/test/Parcelable"))
+ assertEquals(parcelables, listOf("android/test/IParcelable", "android/test/Parcelable"))
}
}
diff --git a/wifi/java/android/net/wifi/rtt/RangingResult.java b/wifi/java/android/net/wifi/rtt/RangingResult.java
index 201833b..f7c8567 100644
--- a/wifi/java/android/net/wifi/rtt/RangingResult.java
+++ b/wifi/java/android/net/wifi/rtt/RangingResult.java
@@ -59,6 +59,19 @@
*/
public static final int STATUS_FAIL = 1;
+ /**
+ * Individual range request status, {@link #getStatus()}. Indicates that the ranging operation
+ * failed because the specified peer does not support IEEE 802.11mc RTT operations. Support by
+ * an Access Point can be confirmed using
+ * {@link android.net.wifi.ScanResult#is80211mcResponder()}.
+ * <p>
+ * On such a failure, the individual result fields of {@link RangingResult} such as
+ * {@link RangingResult#getDistanceMm()} are invalid.
+ *
+ * @hide
+ */
+ public static final int STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC = 2;
+
private final int mStatus;
private final MacAddress mMac;
private final PeerHandle mPeerHandle;