diff options
Diffstat (limited to 'tests')
28 files changed, 749 insertions, 193 deletions
diff --git a/tests/ApkVerityTest/AndroidTest.xml b/tests/ApkVerityTest/AndroidTest.xml index 39b75cc27acb..2a0a2c76e50f 100644 --- a/tests/ApkVerityTest/AndroidTest.xml +++ b/tests/ApkVerityTest/AndroidTest.xml @@ -43,6 +43,8 @@ <option name="push" value="block_device_writer->/data/local/tmp/block_device_writer" /> </target_preparer> + <!-- Skip on HWASan. TODO(b/232288278): Re-enable --> + <object type="module_controller" class="com.android.tradefed.testtype.suite.module.SkipHWASanModuleController" /> <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" > <option name="jar" value="ApkVerityTest.jar" /> </test> diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java index 0f4e122d147a..4bcf5a4e30d5 100644 --- a/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java +++ b/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java @@ -16,14 +16,16 @@ package com.android.test.hwuicompare; -import java.util.LinkedHashMap; -import java.util.Map.Entry; +import static java.util.Map.entry; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; import android.util.Log; +import java.util.Map; +import java.util.Map.Entry; + public abstract class DisplayModifier { // automated tests ignore any combination of operations that don't together return TOTAL_MASK @@ -76,41 +78,36 @@ public abstract class DisplayModifier { }; @SuppressWarnings("serial") - private static final LinkedHashMap<String, LinkedHashMap<String, DisplayModifier>> gMaps = new LinkedHashMap<String, LinkedHashMap<String, DisplayModifier>>() { - { - put("aa", new LinkedHashMap<String, DisplayModifier>() { - { - put("true", new DisplayModifier() { + private static final Map<String, Map<String, DisplayModifier>> gMaps = Map.of( + "aa", Map.of( + "true", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setAntiAlias(true); } - }); - put("false", new DisplayModifier() { + }, + "false", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setAntiAlias(false); } - }); - } - }); - put("style", new LinkedHashMap<String, DisplayModifier>() { - { - put("fill", new DisplayModifier() { + }), + "style", Map.of( + "fill", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setStyle(Paint.Style.FILL); } - }); - put("stroke", new DisplayModifier() { + }, + "stroke", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setStyle(Paint.Style.STROKE); } @Override protected int mask() { return SWEEP_STROKE_WIDTH_BIT; } - }); - put("fillAndStroke", new DisplayModifier() { + }, + "fillAndStroke", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setStyle(Paint.Style.FILL_AND_STROKE); @@ -118,131 +115,118 @@ public abstract class DisplayModifier { @Override protected int mask() { return SWEEP_STROKE_WIDTH_BIT; } - }); - } - }); - put("strokeWidth", new LinkedHashMap<String, DisplayModifier>() { - { - put("hair", new DisplayModifier() { + }), + "strokeWidth", Map.of( + "hair", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setStrokeWidth(0); } @Override protected int mask() { return SWEEP_STROKE_WIDTH_BIT; } - }); - put("0.3", new DisplayModifier() { + }, + "0.3", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setStrokeWidth(0.3f); } - }); - put("1", new DisplayModifier() { + }, + "1", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setStrokeWidth(1); } - }); - put("5", new DisplayModifier() { + }, + "5", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setStrokeWidth(5); } - }); - put("30", new DisplayModifier() { + }, + "30", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setStrokeWidth(30); } - }); - } - }); - put("strokeCap", new LinkedHashMap<String, DisplayModifier>() { - { - put("butt", new DisplayModifier() { + }), + "strokeCap", Map.of( + "butt", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setStrokeCap(Paint.Cap.BUTT); } @Override protected int mask() { return SWEEP_STROKE_CAP_BIT; } - }); - put("round", new DisplayModifier() { + }, + "round", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setStrokeCap(Paint.Cap.ROUND); } - }); - put("square", new DisplayModifier() { + }, + "square", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setStrokeCap(Paint.Cap.SQUARE); } - }); - } - }); - put("strokeJoin", new LinkedHashMap<String, DisplayModifier>() { - { - put("bevel", new DisplayModifier() { + }), + "strokeJoin", Map.of( + "bevel", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setStrokeJoin(Paint.Join.BEVEL); } @Override protected int mask() { return SWEEP_STROKE_JOIN_BIT; } - }); - put("round", new DisplayModifier() { + }, + "round", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setStrokeJoin(Paint.Join.ROUND); } - }); - put("miter", new DisplayModifier() { + }, + "miter", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setStrokeJoin(Paint.Join.MITER); } - }); + }), // TODO: add miter0, miter1 etc to test miter distances - } - }); - - put("transform", new LinkedHashMap<String, DisplayModifier>() { - { - put("noTransform", new DisplayModifier() { + "transform", Map.of( + "noTransform", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) {} @Override protected int mask() { return SWEEP_TRANSFORM_BIT; }; - }); - put("rotate5", new DisplayModifier() { + }, + "rotate5", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { canvas.rotate(5); } - }); - put("rotate45", new DisplayModifier() { + }, + "rotate45", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { canvas.rotate(45); } - }); - put("rotate90", new DisplayModifier() { + }, + "rotate90", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { canvas.rotate(90); canvas.translate(0, -200); } - }); - put("scale2x2", new DisplayModifier() { + }, + "scale2x2", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { canvas.scale(2, 2); } @Override protected int mask() { return SWEEP_TRANSFORM_BIT; }; - }); - put("rot20scl1x4", new DisplayModifier() { + }, + "rot20scl1x4", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { canvas.rotate(20); @@ -250,180 +234,167 @@ public abstract class DisplayModifier { } @Override protected int mask() { return SWEEP_TRANSFORM_BIT; }; - }); - } - }); - - put("shader", new LinkedHashMap<String, DisplayModifier>() { - { - put("noShader", new DisplayModifier() { + }), + "shader", Map.ofEntries( + entry("noShader", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) {} @Override protected int mask() { return SWEEP_SHADER_BIT; }; - }); - put("repeatShader", new DisplayModifier() { + }), + entry("repeatShader", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setShader(ResourceModifiers.instance().mRepeatShader); } @Override protected int mask() { return SWEEP_SHADER_BIT; }; - }); - put("translatedShader", new DisplayModifier() { + }), + entry("translatedShader", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setShader(ResourceModifiers.instance().mTranslatedShader); } - }); - put("scaledShader", new DisplayModifier() { + }), + entry("scaledShader", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setShader(ResourceModifiers.instance().mScaledShader); } - }); - put("horGradient", new DisplayModifier() { + }), + entry("horGradient", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setShader(ResourceModifiers.instance().mHorGradient); } - }); - put("diagGradient", new DisplayModifier() { + }), + entry("diagGradient", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setShader(ResourceModifiers.instance().mDiagGradient); } @Override protected int mask() { return SWEEP_SHADER_BIT; }; - }); - put("vertGradient", new DisplayModifier() { + }), + entry("vertGradient", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setShader(ResourceModifiers.instance().mVertGradient); } - }); - put("radGradient", new DisplayModifier() { + }), + entry("radGradient", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setShader(ResourceModifiers.instance().mRadGradient); } - }); - put("sweepGradient", new DisplayModifier() { + }), + entry("sweepGradient", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setShader(ResourceModifiers.instance().mSweepGradient); } - }); - put("composeShader", new DisplayModifier() { + }), + entry("composeShader", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setShader(ResourceModifiers.instance().mComposeShader); } - }); - put("bad composeShader", new DisplayModifier() { + }), + entry("bad composeShader", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setShader(ResourceModifiers.instance().mBadComposeShader); } - }); - put("bad composeShader 2", new DisplayModifier() { + }), + entry("bad composeShader 2", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setShader(ResourceModifiers.instance().mAnotherBadComposeShader); } - }); - } - }); - - // FINAL MAP: DOES ACTUAL DRAWING - put("drawing", new LinkedHashMap<String, DisplayModifier>() { - { - put("roundRect", new DisplayModifier() { + })), + "drawing", Map.ofEntries( + entry("roundRect", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { canvas.drawRoundRect(gRect, 20, 20, paint); } - }); - put("rect", new DisplayModifier() { + }), + entry("rect", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { canvas.drawRect(gRect, paint); } @Override protected int mask() { return SWEEP_SHADER_BIT | SWEEP_STROKE_CAP_BIT; }; - }); - put("circle", new DisplayModifier() { + }), + entry("circle", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { canvas.drawCircle(100, 100, 75, paint); } - }); - put("oval", new DisplayModifier() { + }), + entry("oval", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { canvas.drawOval(gRect, paint); } - }); - put("lines", new DisplayModifier() { + }), + entry("lines", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { canvas.drawLines(gLinePts, paint); } @Override protected int mask() { return SWEEP_STROKE_CAP_BIT; }; - }); - put("plusPoints", new DisplayModifier() { + }), + entry("plusPoints", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { canvas.drawPoints(gPts, paint); } - }); - put("text", new DisplayModifier() { + }), + entry("text", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setTextSize(36); canvas.drawText("TEXTTEST", 0, 50, paint); } - }); - put("shadowtext", new DisplayModifier() { + }), + entry("shadowtext", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { paint.setTextSize(36); paint.setShadowLayer(3.0f, 0.0f, 3.0f, 0xffff00ff); canvas.drawText("TEXTTEST", 0, 50, paint); } - }); - put("bitmapMesh", new DisplayModifier() { + }), + entry("bitmapMesh", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { canvas.drawBitmapMesh(ResourceModifiers.instance().mBitmap, 3, 3, ResourceModifiers.instance().mBitmapVertices, 0, null, 0, null); } - }); - put("arc", new DisplayModifier() { + }), + entry("arc", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { canvas.drawArc(gRect, 260, 285, false, paint); } @Override protected int mask() { return SWEEP_STROKE_CAP_BIT; }; - }); - put("arcFromCenter", new DisplayModifier() { + }), + entry("arcFromCenter", new DisplayModifier() { @Override public void modifyDrawing(Paint paint, Canvas canvas) { canvas.drawArc(gRect, 260, 285, true, paint); } @Override protected int mask() { return SWEEP_STROKE_JOIN_BIT; }; - }); - } - }); + }))); // WARNING: DON'T PUT MORE MAPS BELOW THIS - } - }; - private static LinkedHashMap<String, DisplayModifier> getMapAtIndex(int index) { - for (LinkedHashMap<String, DisplayModifier> map : gMaps.values()) { + private static Map<String, DisplayModifier> getMapAtIndex(int index) { + for (Map<String, DisplayModifier> map : gMaps.values()) { if (index == 0) { return map; } @@ -439,7 +410,7 @@ public abstract class DisplayModifier { private static boolean stepInternal(boolean forward) { int modifierMapIndex = gMaps.size() - 1; while (modifierMapIndex >= 0) { - LinkedHashMap<String, DisplayModifier> map = getMapAtIndex(modifierMapIndex); + Map<String, DisplayModifier> map = getMapAtIndex(modifierMapIndex); mIndices[modifierMapIndex] += (forward ? 1 : -1); if (mIndices[modifierMapIndex] >= 0 && mIndices[modifierMapIndex] < map.size()) { @@ -471,7 +442,7 @@ public abstract class DisplayModifier { private static boolean checkModificationStateMask() { int operatorMask = 0x0; int mapIndex = 0; - for (LinkedHashMap<String, DisplayModifier> map : gMaps.values()) { + for (Map<String, DisplayModifier> map : gMaps.values()) { int displayModifierIndex = mIndices[mapIndex]; for (Entry<String, DisplayModifier> modifierEntry : map.entrySet()) { if (displayModifierIndex == 0) { @@ -488,7 +459,7 @@ public abstract class DisplayModifier { public static void apply(Paint paint, Canvas canvas) { int mapIndex = 0; - for (LinkedHashMap<String, DisplayModifier> map : gMaps.values()) { + for (Map<String, DisplayModifier> map : gMaps.values()) { int displayModifierIndex = mIndices[mapIndex]; for (Entry<String, DisplayModifier> modifierEntry : map.entrySet()) { if (displayModifierIndex == 0) { @@ -510,7 +481,7 @@ public abstract class DisplayModifier { String[][] keys = new String[gMaps.size()][]; int i = 0; - for (LinkedHashMap<String, DisplayModifier> map : gMaps.values()) { + for (Map<String, DisplayModifier> map : gMaps.values()) { keys[i] = new String[map.size()]; int j = 0; for (String key : map.keySet()) { diff --git a/tests/Codegen/Android.bp b/tests/Codegen/Android.bp index ddbf16817b94..7fbe3b37f99e 100644 --- a/tests/Codegen/Android.bp +++ b/tests/Codegen/Android.bp @@ -24,6 +24,14 @@ android_test { plugins: [ "staledataclass-annotation-processor", ], + // Exports needed for staledataclass-annotation-processor, see b/139342589. + javacflags: [ + "-J--add-modules=jdk.compiler", + "-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", + "-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED", + "-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", + "-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", + ], static_libs: [ "junit", "hamcrest", diff --git a/tests/FixVibrateSetting/src/com/android/fixvibratesetting/FixVibrateSetting.java b/tests/FixVibrateSetting/src/com/android/fixvibratesetting/FixVibrateSetting.java index 2e515705a253..761efe4a8484 100644 --- a/tests/FixVibrateSetting/src/com/android/fixvibratesetting/FixVibrateSetting.java +++ b/tests/FixVibrateSetting/src/com/android/fixvibratesetting/FixVibrateSetting.java @@ -110,7 +110,7 @@ public class FixVibrateSetting extends Activity implements View.OnClickListener private void test() { Intent intent = new Intent(this, FixVibrateSetting.class); - PendingIntent pending = PendingIntent.getActivity(this, 0, intent, 0); + PendingIntent pending = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE); Notification n = new Notification.Builder(this) .setSmallIcon(R.drawable.stat_sys_warning) diff --git a/tests/HandwritingIme/OWNERS b/tests/HandwritingIme/OWNERS new file mode 100644 index 000000000000..6bb4b17ed4eb --- /dev/null +++ b/tests/HandwritingIme/OWNERS @@ -0,0 +1,3 @@ +# Bug component: 34867 + +include /services/core/java/com/android/server/inputmethod/OWNERS diff --git a/tests/HierarchyViewerTest/src/com/android/test/hierarchyviewer/ViewDumpParser.java b/tests/HierarchyViewerTest/src/com/android/test/hierarchyviewer/ViewDumpParser.java index 2ad0da98c409..8b9c02049351 100644 --- a/tests/HierarchyViewerTest/src/com/android/test/hierarchyviewer/ViewDumpParser.java +++ b/tests/HierarchyViewerTest/src/com/android/test/hierarchyviewer/ViewDumpParser.java @@ -58,7 +58,7 @@ public class ViewDumpParser { Object hash = getProperty(props, "__hash__"); if (name instanceof String && hash instanceof Integer) { - return String.format(Locale.US, "%s@%x", name, hash); + return String.format(Locale.US, "%s@%x", name, (Integer) hash); } else { return null; } diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java index 47f87d6d75ff..573b3b695a90 100644 --- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java +++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java @@ -102,6 +102,7 @@ public final class NotificationTest { @After public void tearDown() { mNotificationManager.cancelAll(); + mUiDevice.pressHome(); } @Test diff --git a/tests/JankBench/app/src/main/java/com/android/benchmark/app/HomeActivity.java b/tests/JankBench/app/src/main/java/com/android/benchmark/app/HomeActivity.java index 4de51fb57308..43dc9de6c90a 100644 --- a/tests/JankBench/app/src/main/java/com/android/benchmark/app/HomeActivity.java +++ b/tests/JankBench/app/src/main/java/com/android/benchmark/app/HomeActivity.java @@ -140,9 +140,9 @@ public class HomeActivity extends AppCompatActivity implements Button.OnClickLis handleNextBenchmark(); } + @SuppressWarnings("MissingSuperCall") // TODO: Fix me @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { - } private void handleNextBenchmark() { diff --git a/tests/JankBench/app/src/main/java/com/android/benchmark/app/RunLocalBenchmarksActivity.java b/tests/JankBench/app/src/main/java/com/android/benchmark/app/RunLocalBenchmarksActivity.java index c16efbda1830..d015a5695ec0 100644 --- a/tests/JankBench/app/src/main/java/com/android/benchmark/app/RunLocalBenchmarksActivity.java +++ b/tests/JankBench/app/src/main/java/com/android/benchmark/app/RunLocalBenchmarksActivity.java @@ -367,6 +367,7 @@ public class RunLocalBenchmarksActivity extends AppCompatActivity { } } + @SuppressWarnings("MissingSuperCall") // TODO: Fix me @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { diff --git a/tests/MirrorSurfaceTest/src/com/google/android/test/mirrorsurface/MirrorSurfaceActivity.java b/tests/MirrorSurfaceTest/src/com/google/android/test/mirrorsurface/MirrorSurfaceActivity.java index 8afe8411a790..17fa210a1db6 100644 --- a/tests/MirrorSurfaceTest/src/com/google/android/test/mirrorsurface/MirrorSurfaceActivity.java +++ b/tests/MirrorSurfaceTest/src/com/google/android/test/mirrorsurface/MirrorSurfaceActivity.java @@ -295,8 +295,8 @@ public class MirrorSurfaceActivity extends Activity implements View.OnClickListe private void updateMirror(Rect displayFrame, float scale) { if (displayFrame.isEmpty()) { Rect bounds = mWindowBounds; - int defaultCropW = Math.round(bounds.width() / 2); - int defaultCropH = Math.round(bounds.height() / 2); + int defaultCropW = bounds.width() / 2; + int defaultCropH = bounds.height() / 2; displayFrame.set(0, 0, defaultCropW, defaultCropH); } diff --git a/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java b/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java index 241206d8919b..65b7549f22d1 100644 --- a/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java +++ b/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java @@ -24,18 +24,14 @@ public class MainActivity extends Activity implements OnItemClickListener { static final String KEY_NAME = "name"; static final String KEY_CLASS = "clazz"; - static Map<String,?> make(String name) { - Map<String,Object> ret = new HashMap<String,Object>(); - ret.put(KEY_NAME, name); - return ret; - } - - @SuppressWarnings("serial") - static final ArrayList<Map<String,?>> SAMPLES = new ArrayList<Map<String,?>>() {{ + static final ArrayList<Map<String, ?>> SAMPLES = new ArrayList<>(); + static { for (int i = 1; i < 25; i++) { - add(make("List Item: " + i)); + Map<String, Object> sample = new HashMap<String, Object>(); + sample.put(KEY_NAME, "List Item: " + i); + SAMPLES.add(sample); } - }}; + } Handler mHandler = new Handler(); diff --git a/tests/RollbackTest/Android.bp b/tests/RollbackTest/Android.bp index 9f6ce4e8425b..f2234fb64108 100644 --- a/tests/RollbackTest/Android.bp +++ b/tests/RollbackTest/Android.bp @@ -51,6 +51,7 @@ java_test_host { data: [ ":com.android.apex.apkrollback.test_v1", ":test.rebootless_apex_v1", + ":RollbackTest", ], } @@ -61,6 +62,7 @@ java_test_host { static_libs: ["RollbackTestLib", "frameworks-base-hostutils"], test_suites: ["general-tests"], test_config: "NetworkStagedRollbackTest.xml", + data: [":RollbackTest"], } java_test_host { diff --git a/tests/RollbackTest/SampleRollbackApp/Android.bp b/tests/RollbackTest/SampleRollbackApp/Android.bp new file mode 100644 index 000000000000..074c7bc39155 --- /dev/null +++ b/tests/RollbackTest/SampleRollbackApp/Android.bp @@ -0,0 +1,33 @@ +// Copyright (C) 2022 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 { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +android_app { + name: "SampleRollbackApp", + srcs: [ + "src/**/*.java", + ], + resource_dirs: ["res"], + certificate: "platform", + sdk_version: "system_current", + min_sdk_version: "29", +} diff --git a/tests/RollbackTest/SampleRollbackApp/AndroidManifest.xml b/tests/RollbackTest/SampleRollbackApp/AndroidManifest.xml new file mode 100644 index 000000000000..7fe4bae2a3fe --- /dev/null +++ b/tests/RollbackTest/SampleRollbackApp/AndroidManifest.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2022 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. + --> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.sample.rollbackapp" > + <uses-permission android:name="android.permission.MANAGE_ROLLBACKS" /> + <application + android:label="@string/title_activity_main"> + <activity + android:name="com.android.sample.rollbackapp.MainActivity" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/RollbackTest/SampleRollbackApp/res/layout/activity_main.xml b/tests/RollbackTest/SampleRollbackApp/res/layout/activity_main.xml new file mode 100644 index 000000000000..3fb987bb539c --- /dev/null +++ b/tests/RollbackTest/SampleRollbackApp/res/layout/activity_main.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2022 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. + --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <Button + android:id="@+id/trigger_rollback_button" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + style="?android:attr/buttonBarButtonStyle" + android:text="Rollback Selected" /> + + <ListView + android:id="@+id/listView" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:divider="?android:attr/dividerHorizontal" + android:dividerHeight="1dp" /> + +</LinearLayout>
\ No newline at end of file diff --git a/tests/RollbackTest/SampleRollbackApp/res/layout/listitem_rollbackinfo.xml b/tests/RollbackTest/SampleRollbackApp/res/layout/listitem_rollbackinfo.xml new file mode 100644 index 000000000000..f650dd5d2230 --- /dev/null +++ b/tests/RollbackTest/SampleRollbackApp/res/layout/listitem_rollbackinfo.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2022 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. + --> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" +> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:paddingTop="10dp" + android:paddingLeft="10dp" + android:paddingRight="10dp"> + <TextView android:id="@+id/rollback_id" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="20dp"/> + <TextView android:id="@+id/rollback_packages" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="16dp"/> + <CheckBox android:id="@+id/checkbox" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Roll Back"/> + </LinearLayout> +</RelativeLayout>
\ No newline at end of file diff --git a/tests/RollbackTest/SampleRollbackApp/res/values/strings.xml b/tests/RollbackTest/SampleRollbackApp/res/values/strings.xml new file mode 100644 index 000000000000..a85b6800a146 --- /dev/null +++ b/tests/RollbackTest/SampleRollbackApp/res/values/strings.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2022 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. + --> + +<resources> + <string name="title_activity_main" description="Launcher title">Rollback Sample App</string> +</resources>
\ No newline at end of file diff --git a/tests/RollbackTest/SampleRollbackApp/src/com/android/sample/rollbackapp/MainActivity.java b/tests/RollbackTest/SampleRollbackApp/src/com/android/sample/rollbackapp/MainActivity.java new file mode 100644 index 000000000000..79a2f1f5f4de --- /dev/null +++ b/tests/RollbackTest/SampleRollbackApp/src/com/android/sample/rollbackapp/MainActivity.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2022 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.sample.rollbackapp; + +import static android.app.PendingIntent.FLAG_MUTABLE; + +import android.app.Activity; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.rollback.PackageRollbackInfo; +import android.content.rollback.RollbackInfo; +import android.content.rollback.RollbackManager; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.Toast; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class MainActivity extends Activity { + + List<Integer> mIdsToRollback = new ArrayList<>(); + Button mTriggerRollbackButton; + RollbackManager mRollbackManager; + static final String ROLLBACK_ID_EXTRA = "rollbackId"; + static final String ACTION_NAME = MainActivity.class.getName(); + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + ListView rollbackListView = findViewById(R.id.listView); + mRollbackManager = getApplicationContext().getSystemService(RollbackManager.class); + initTriggerRollbackButton(); + + // Populate list of available rollbacks. + List<RollbackInfo> availableRollbacks = mRollbackManager.getAvailableRollbacks(); + CustomAdapter adapter = new CustomAdapter(availableRollbacks); + rollbackListView.setAdapter(adapter); + + // Register receiver for rollback status events. + getApplicationContext().registerReceiver( + new BroadcastReceiver() { + @Override + public void onReceive(Context context, + Intent intent) { + int rollbackId = intent.getIntExtra(ROLLBACK_ID_EXTRA, -1); + int rollbackStatusCode = intent.getIntExtra(RollbackManager.EXTRA_STATUS, + RollbackManager.STATUS_FAILURE); + String rollbackStatus = "FAILED"; + if (rollbackStatusCode == RollbackManager.STATUS_SUCCESS) { + rollbackStatus = "SUCCESS"; + mTriggerRollbackButton.setClickable(false); + } + makeToast("Status for rollback ID " + rollbackId + " is " + rollbackStatus); + }}, new IntentFilter(ACTION_NAME), Context.RECEIVER_NOT_EXPORTED); + } + + private void initTriggerRollbackButton() { + mTriggerRollbackButton = findViewById(R.id.trigger_rollback_button); + mTriggerRollbackButton.setClickable(false); + mTriggerRollbackButton.setOnClickListener(v -> { + // Commits all selected rollbacks. Rollback status events will be sent to our receiver. + for (int i = 0; i < mIdsToRollback.size(); i++) { + Intent intent = new Intent(ACTION_NAME); + intent.putExtra(ROLLBACK_ID_EXTRA, mIdsToRollback.get(i)); + PendingIntent pendingIntent = PendingIntent.getBroadcast( + getApplicationContext(), 0, intent, FLAG_MUTABLE); + mRollbackManager.commitRollback(mIdsToRollback.get(i), + Collections.emptyList(), + pendingIntent.getIntentSender()); + } + }); + } + + + + private void makeToast(String message) { + runOnUiThread(() -> Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show()); + } + + public class CustomAdapter extends BaseAdapter { + List<RollbackInfo> mRollbackInfos; + LayoutInflater mInflater = LayoutInflater.from(getApplicationContext()); + + CustomAdapter(List<RollbackInfo> rollbackInfos) { + mRollbackInfos = rollbackInfos; + } + + @Override + public int getCount() { + return mRollbackInfos.size(); + } + + @Override + public Object getItem(int position) { + return mRollbackInfos.get(position); + } + + @Override + public long getItemId(int position) { + return mRollbackInfos.get(position).getRollbackId(); + } + + @Override + public View getView(int position, View view, ViewGroup parent) { + if (view == null) { + view = mInflater.inflate(R.layout.listitem_rollbackinfo, null); + } + RollbackInfo rollbackInfo = mRollbackInfos.get(position); + TextView rollbackIdView = view.findViewById(R.id.rollback_id); + rollbackIdView.setText("Rollback ID " + rollbackInfo.getRollbackId()); + TextView rollbackPackagesTextView = view.findViewById(R.id.rollback_packages); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < rollbackInfo.getPackages().size(); i++) { + PackageRollbackInfo pkgInfo = rollbackInfo.getPackages().get(i); + sb.append(pkgInfo.getPackageName() + ": " + + pkgInfo.getVersionRolledBackFrom().getLongVersionCode() + " -> " + + pkgInfo.getVersionRolledBackTo().getLongVersionCode() + ","); + } + sb.deleteCharAt(sb.length() - 1); + rollbackPackagesTextView.setText(sb.toString()); + CheckBox checkbox = view.findViewById(R.id.checkbox); + checkbox.setOnCheckedChangeListener((buttonView, isChecked) -> { + if (isChecked) { + mIdsToRollback.add(rollbackInfo.getRollbackId()); + } else { + mIdsToRollback.remove(Integer.valueOf(rollbackInfo.getRollbackId())); + } + mTriggerRollbackButton.setClickable(mIdsToRollback.size() > 0); + }); + return view; + } + } +} diff --git a/tests/SmokeTestApps/src/com/android/smoketest/triggers/CrashyApp.java b/tests/SmokeTestApps/src/com/android/smoketest/triggers/CrashyApp.java index c11b0f3acf79..f85fb0f267d5 100644 --- a/tests/SmokeTestApps/src/com/android/smoketest/triggers/CrashyApp.java +++ b/tests/SmokeTestApps/src/com/android/smoketest/triggers/CrashyApp.java @@ -30,6 +30,7 @@ public class CrashyApp extends Activity { setContentView(tv); } + @SuppressWarnings("ReturnValueIgnored") @Override public void onResume() { ((String) null).length(); diff --git a/tests/TouchLatency/OWNERS b/tests/TouchLatency/OWNERS new file mode 100644 index 000000000000..2b7de2555587 --- /dev/null +++ b/tests/TouchLatency/OWNERS @@ -0,0 +1,2 @@ +include platform/frameworks/base:/graphics/java/android/graphics/OWNERS +include platform/frameworks/native:/services/surfaceflinger/OWNERS
\ No newline at end of file diff --git a/tests/TrustTests/Android.bp b/tests/TrustTests/Android.bp index 77f98e88f1eb..a1b888aef934 100644 --- a/tests/TrustTests/Android.bp +++ b/tests/TrustTests/Android.bp @@ -24,7 +24,7 @@ android_test { static_libs: [ "androidx.test.rules", "androidx.test.ext.junit", - "androidx.test.uiautomator", + "androidx.test.uiautomator_uiautomator", "mockito-target-minus-junit4", "servicestests-utils", "truth-prebuilt", diff --git a/tests/UpdatableSystemFontTest/Android.bp b/tests/UpdatableSystemFontTest/Android.bp index 9a9e42bfc300..9bfcc18ee301 100644 --- a/tests/UpdatableSystemFontTest/Android.bp +++ b/tests/UpdatableSystemFontTest/Android.bp @@ -37,6 +37,7 @@ android_test { "vts", ], data: [ + ":EmojiRenderingTestApp", ":UpdatableSystemFontTestCertDer", ":UpdatableSystemFontTest_NotoColorEmoji.ttf", ":UpdatableSystemFontTest_NotoColorEmoji.sig", diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java index db4898492ac5..661dd845757b 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java @@ -33,6 +33,8 @@ import android.widget.CheckBox; import android.widget.ImageView; import android.widget.TextView; +import java.util.Arrays; + public class MainInteractionSession extends VoiceInteractionSession implements View.OnClickListener { static final String TAG = "MainInteractionSession"; @@ -403,7 +405,7 @@ public class MainInteractionSession extends VoiceInteractionSession @Override public void onRequestPickOption(PickOptionRequest request) { Log.i(TAG, "onPickOption: prompt=" + request.getVoicePrompt() + " options=" - + request.getOptions() + " extras=" + request.getExtras()); + + Arrays.toString(request.getOptions()) + " extras=" + request.getExtras()); mConfirmButton.setText("Pick Option"); mPendingRequest = request; setPrompt(request.getVoicePrompt()); diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/StartVoiceInteractionActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/StartVoiceInteractionActivity.java index 733f602f6c14..8ae7186461d3 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/StartVoiceInteractionActivity.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/StartVoiceInteractionActivity.java @@ -24,6 +24,8 @@ import android.view.View; import android.widget.Button; import android.widget.TextView; +import java.util.Arrays; + public class StartVoiceInteractionActivity extends Activity implements View.OnClickListener { static final String TAG = "LocalVoiceInteractionActivity"; @@ -187,7 +189,8 @@ public class StartVoiceInteractionActivity extends Activity implements View.OnCl } @Override public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) { - Log.i(TAG, "Pick result: finished=" + finished + " selections=" + selections + Log.i(TAG, "Pick result: finished=" + finished + + " selections=" + Arrays.toString(selections) + " result=" + result); StringBuilder sb = new StringBuilder(); if (finished) { diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java index ada0e21e059a..4fc3a15ac38d 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java @@ -28,6 +28,8 @@ import android.view.View; import android.widget.Button; import android.widget.TextView; +import java.util.Arrays; + public class TestInteractionActivity extends Activity implements View.OnClickListener { static final String TAG = "TestInteractionActivity"; @@ -240,7 +242,8 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis } @Override public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) { - Log.i(TAG, "Pick result: finished=" + finished + " selections=" + selections + Log.i(TAG, "Pick result: finished=" + finished + + " selections=" + Arrays.toString(selections) + " result=" + result); StringBuilder sb = new StringBuilder(); if (finished) { diff --git a/tests/utils/testutils/java/com/android/internal/util/test/BroadcastInterceptingContext.java b/tests/utils/testutils/java/com/android/internal/util/test/BroadcastInterceptingContext.java index 3da8b460df13..133c1767c9b4 100644 --- a/tests/utils/testutils/java/com/android/internal/util/test/BroadcastInterceptingContext.java +++ b/tests/utils/testutils/java/com/android/internal/util/test/BroadcastInterceptingContext.java @@ -147,12 +147,39 @@ public class BroadcastInterceptingContext extends ContextWrapper { @Override public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { - return registerReceiver(receiver, filter, null, null); + return registerReceiver(receiver, filter, null, null, 0); + } + + /** + * Registers the specified {@code receiver} to listen for broadcasts that match the {@code + * filter} in the current process. + * + * <p>Since this method only listens for broadcasts in the current process, the provided {@code + * flags} are ignored; this method is primarily intended to allow receivers that register with + * flags to register in the current process during tests. + */ + @Override + public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags) { + return registerReceiver(receiver, filter, null, null, flags); } @Override public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) { + return registerReceiver(receiver, filter, broadcastPermission, scheduler, 0); + } + + /** + * Registers the specified {@code receiver} to listen for broadcasts that match the {@code + * filter} to run in the context of the specified {@code scheduler} in the current process. + * + * <p>Since this method only listens for broadcasts in the current process, the provided {@code + * flags} are ignored; this method is primarily intended to allow receivers that register with + * flags to register in the current process during tests. + */ + @Override + public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, + String broadcastPermission, Handler scheduler, int flags) { synchronized (mInterceptors) { mInterceptors.add(new BroadcastInterceptor(receiver, filter, scheduler)); } diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java index f924b2e9b932..258642ac229e 100644 --- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java +++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java @@ -17,10 +17,12 @@ package com.android.server; import static android.net.ConnectivityManager.NetworkCallback; +import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; +import static android.net.vcn.VcnManager.VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY; import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE; import static android.net.vcn.VcnManager.VCN_STATUS_CODE_SAFE_MODE; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; @@ -95,6 +97,7 @@ import com.android.server.vcn.Vcn; import com.android.server.vcn.VcnContext; import com.android.server.vcn.VcnNetworkProvider; import com.android.server.vcn.util.PersistableBundleUtils; +import com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper; import org.junit.Before; import org.junit.Test; @@ -252,6 +255,10 @@ public class VcnManagementServiceTest { .when(mMockContext) .enforceCallingOrSelfPermission( eq(android.Manifest.permission.NETWORK_FACTORY), any()); + + doReturn(Collections.singleton(TRANSPORT_WIFI)) + .when(mMockDeps) + .getRestrictedTransports(any(), any()); } @@ -637,8 +644,7 @@ public class VcnManagementServiceTest { final BroadcastReceiver receiver = getPackageChangeReceiver(); verify(mMockContext).registerReceiver(any(), argThat(filter -> { - return filter.hasAction(Intent.ACTION_PACKAGE_REMOVED) - && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED); + return filter.hasAction(Intent.ACTION_PACKAGE_REMOVED); }), any(), any()); receiver.onReceive(mMockContext, new Intent(Intent.ACTION_PACKAGE_REMOVED)); @@ -1032,63 +1038,188 @@ public class VcnManagementServiceTest { new LinkProperties()); } + private void checkGetRestrictedTransports( + ParcelUuid subGrp, + TelephonySubscriptionSnapshot lastSnapshot, + Set<Integer> expectedTransports) { + Set<Integer> result = + new VcnManagementService.Dependencies() + .getRestrictedTransports(subGrp, lastSnapshot); + assertEquals(expectedTransports, result); + } + + @Test + public void testGetRestrictedTransports() { + final Set<Integer> restrictedTransports = new ArraySet<>(); + restrictedTransports.add(TRANSPORT_CELLULAR); + restrictedTransports.add(TRANSPORT_WIFI); + + PersistableBundle carrierConfigBundle = new PersistableBundle(); + carrierConfigBundle.putIntArray( + VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY, + restrictedTransports.stream().mapToInt(i -> i).toArray()); + final PersistableBundleWrapper carrierConfig = + new PersistableBundleWrapper(carrierConfigBundle); + + final TelephonySubscriptionSnapshot lastSnapshot = + mock(TelephonySubscriptionSnapshot.class); + doReturn(carrierConfig).when(lastSnapshot).getCarrierConfigForSubGrp(eq(TEST_UUID_2)); + + checkGetRestrictedTransports(TEST_UUID_2, lastSnapshot, restrictedTransports); + } + @Test - public void testGetUnderlyingNetworkPolicyCellular() throws Exception { + public void testGetRestrictedTransports_noRestrictPolicyConfigured() { + final Set<Integer> restrictedTransports = Collections.singleton(TRANSPORT_WIFI); + + final PersistableBundleWrapper carrierConfig = + new PersistableBundleWrapper(new PersistableBundle()); + final TelephonySubscriptionSnapshot lastSnapshot = + mock(TelephonySubscriptionSnapshot.class); + doReturn(carrierConfig).when(lastSnapshot).getCarrierConfigForSubGrp(eq(TEST_UUID_2)); + + checkGetRestrictedTransports(TEST_UUID_2, lastSnapshot, restrictedTransports); + } + + @Test + public void testGetRestrictedTransports_noCarrierConfig() { + final Set<Integer> restrictedTransports = Collections.singleton(TRANSPORT_WIFI); + + final TelephonySubscriptionSnapshot lastSnapshot = + mock(TelephonySubscriptionSnapshot.class); + + checkGetRestrictedTransports(TEST_UUID_2, lastSnapshot, restrictedTransports); + } + + private void checkGetUnderlyingNetworkPolicy( + int transportType, + boolean isTransportRestricted, + boolean isActive, + boolean expectVcnManaged, + boolean expectRestricted) + throws Exception { + + final Set<Integer> restrictedTransports = new ArraySet(); + if (isTransportRestricted) { + restrictedTransports.add(transportType); + } + doReturn(restrictedTransports).when(mMockDeps).getRestrictedTransports(any(), any()); + final VcnUnderlyingNetworkPolicy policy = startVcnAndGetPolicyForTransport( - TEST_SUBSCRIPTION_ID, TEST_UUID_2, true /* isActive */, TRANSPORT_CELLULAR); + TEST_SUBSCRIPTION_ID, TEST_UUID_2, isActive, transportType); assertFalse(policy.isTeardownRequested()); verifyMergedNetworkCapabilities( policy.getMergedNetworkCapabilities(), + transportType, + expectVcnManaged, + expectRestricted); + } + + @Test + public void testGetUnderlyingNetworkPolicy_unrestrictCell() throws Exception { + checkGetUnderlyingNetworkPolicy( TRANSPORT_CELLULAR, - true /* isVcnManaged */, - false /* isRestricted */); + false /* isTransportRestricted */, + true /* isActive */, + true /* expectVcnManaged */, + false /* expectRestricted */); } @Test - public void testGetUnderlyingNetworkPolicyCellular_safeMode() throws Exception { - final VcnUnderlyingNetworkPolicy policy = - startVcnAndGetPolicyForTransport( - TEST_SUBSCRIPTION_ID, - TEST_UUID_2, - false /* isActive */, - TRANSPORT_CELLULAR); + public void testGetUnderlyingNetworkPolicy_unrestrictCellSafeMode() throws Exception { + checkGetUnderlyingNetworkPolicy( + TRANSPORT_CELLULAR, + false /* isTransportRestricted */, + false /* isActive */, + false /* expectVcnManaged */, + false /* expectRestricted */); + } - assertFalse(policy.isTeardownRequested()); - verifyMergedNetworkCapabilities( - policy.getMergedNetworkCapabilities(), - NetworkCapabilities.TRANSPORT_CELLULAR, - false /* isVcnManaged */, - false /* isRestricted */); + @Test + public void testGetUnderlyingNetworkPolicy_restrictCell() throws Exception { + checkGetUnderlyingNetworkPolicy( + TRANSPORT_CELLULAR, + true /* isTransportRestricted */, + true /* isActive */, + true /* expectVcnManaged */, + true /* expectRestricted */); } @Test - public void testGetUnderlyingNetworkPolicyWifi() throws Exception { - final VcnUnderlyingNetworkPolicy policy = - startVcnAndGetPolicyForTransport( - TEST_SUBSCRIPTION_ID, TEST_UUID_2, true /* isActive */, TRANSPORT_WIFI); + public void testGetUnderlyingNetworkPolicy_restrictCellSafeMode() throws Exception { + checkGetUnderlyingNetworkPolicy( + TRANSPORT_CELLULAR, + true /* isTransportRestricted */, + false /* isActive */, + false /* expectVcnManaged */, + false /* expectRestricted */); + } - assertFalse(policy.isTeardownRequested()); - verifyMergedNetworkCapabilities( - policy.getMergedNetworkCapabilities(), - NetworkCapabilities.TRANSPORT_WIFI, - true /* isVcnManaged */, - true /* isRestricted */); + @Test + public void testGetUnderlyingNetworkPolicy_unrestrictWifi() throws Exception { + checkGetUnderlyingNetworkPolicy( + TRANSPORT_WIFI, + false /* isTransportRestricted */, + true /* isActive */, + true /* expectVcnManaged */, + false /* expectRestricted */); + } + + @Test + public void testGetUnderlyingNetworkPolicy_unrestrictWifiSafeMode() throws Exception { + checkGetUnderlyingNetworkPolicy( + TRANSPORT_WIFI, + false /* isTransportRestricted */, + false /* isActive */, + false /* expectVcnManaged */, + false /* expectRestricted */); + } + + @Test + public void testGetUnderlyingNetworkPolicy_restrictWifi() throws Exception { + checkGetUnderlyingNetworkPolicy( + TRANSPORT_WIFI, + true /* isTransportRestricted */, + true /* isActive */, + true /* expectVcnManaged */, + true /* expectRestricted */); } @Test - public void testGetUnderlyingNetworkPolicyVcnWifi_safeMode() throws Exception { + public void testGetUnderlyingNetworkPolicy_restrictWifiSafeMode() throws Exception { + checkGetUnderlyingNetworkPolicy( + TRANSPORT_WIFI, + true /* isTransportRestricted */, + false /* isActive */, + false /* expectVcnManaged */, + true /* expectRestricted */); + } + + @Test + public void testGetUnderlyingNetworkPolicyCell_restrictWifi() throws Exception { + doReturn(Collections.singleton(TRANSPORT_WIFI)) + .when(mMockDeps) + .getRestrictedTransports(any(), any()); + + setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_2, true /* isVcnActive */); + + // Get the policy for a cellular network and expect it won't be affected by the wifi + // restriction policy final VcnUnderlyingNetworkPolicy policy = - startVcnAndGetPolicyForTransport( - TEST_SUBSCRIPTION_ID, TEST_UUID_2, false /* isActive */, TRANSPORT_WIFI); + mVcnMgmtSvc.getUnderlyingNetworkPolicy( + getNetworkCapabilitiesBuilderForTransport( + TEST_SUBSCRIPTION_ID, TRANSPORT_CELLULAR) + .build(), + new LinkProperties()); assertFalse(policy.isTeardownRequested()); verifyMergedNetworkCapabilities( policy.getMergedNetworkCapabilities(), - NetworkCapabilities.TRANSPORT_WIFI, - false /* isVcnManaged */, - true /* isRestricted */); + TRANSPORT_CELLULAR, + true /* expectVcnManaged */, + false /* expectRestricted */); } private void setupTrackedCarrierWifiNetwork(NetworkCapabilities caps) { @@ -1139,6 +1270,27 @@ public class VcnManagementServiceTest { } @Test + public void testGetUnderlyingNetworkPolicyForRestrictedImsWhenUnrestrictingCell() + throws Exception { + final NetworkCapabilities existingNetworkCaps = + getNetworkCapabilitiesBuilderForTransport(TEST_SUBSCRIPTION_ID, TRANSPORT_CELLULAR) + .addCapability(NET_CAPABILITY_NOT_RESTRICTED) + .removeCapability(NET_CAPABILITY_IMS) + .build(); + setupTrackedCarrierWifiNetwork(existingNetworkCaps); + + final VcnUnderlyingNetworkPolicy policy = + mVcnMgmtSvc.getUnderlyingNetworkPolicy( + getNetworkCapabilitiesBuilderForTransport( + TEST_SUBSCRIPTION_ID, TRANSPORT_CELLULAR) + .addCapability(NET_CAPABILITY_IMS) + .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) + .build(), + new LinkProperties()); + assertFalse(policy.isTeardownRequested()); + } + + @Test public void testGetUnderlyingNetworkPolicyNonVcnNetwork() throws Exception { setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_1, true /* isActive */); @@ -1218,6 +1370,30 @@ public class VcnManagementServiceTest { verify(mMockPolicyListener).onPolicyChanged(); } + @Test + public void testVcnCarrierConfigChangeUpdatesPolicyListener() throws Exception { + setupActiveSubscription(TEST_UUID_2); + + mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME); + mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListenerForTest(mMockPolicyListener); + + final TelephonySubscriptionSnapshot snapshot = + buildSubscriptionSnapshot( + TEST_SUBSCRIPTION_ID, + TEST_UUID_2, + Collections.singleton(TEST_UUID_2), + Collections.emptyMap(), + true /* hasCarrierPrivileges */); + + final PersistableBundleWrapper mockCarrierConfig = mock(PersistableBundleWrapper.class); + doReturn(mockCarrierConfig).when(snapshot).getCarrierConfigForSubGrp(eq(TEST_UUID_2)); + + final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback(); + cb.onNewSnapshot(snapshot); + + verify(mMockPolicyListener).onPolicyChanged(); + } + private void triggerVcnSafeMode( @NonNull ParcelUuid subGroup, @NonNull TelephonySubscriptionSnapshot snapshot, diff --git a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java index 09080be9ee41..965b073ff0db 100644 --- a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java +++ b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java @@ -16,6 +16,9 @@ package com.android.server.vcn; +import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; +import static android.net.NetworkCapabilities.TRANSPORT_WIFI; +import static android.net.vcn.VcnManager.VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY; import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; import static android.telephony.CarrierConfigManager.EXTRA_SLOT_INDEX; import static android.telephony.CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX; @@ -39,6 +42,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; @@ -494,6 +498,37 @@ public class TelephonySubscriptionTrackerTest { } @Test + public void testCarrierConfigUpdatedAfterValidTriggersCallbacks() throws Exception { + mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true)); + mTestLooper.dispatchAll(); + verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES))); + reset(mCallback); + + final PersistableBundle updatedConfig = new PersistableBundle(); + updatedConfig.putIntArray( + VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY, + new int[] {TRANSPORT_WIFI, TRANSPORT_CELLULAR}); + doReturn(updatedConfig) + .when(mCarrierConfigManager) + .getConfigForSubId(eq(TEST_SUBSCRIPTION_ID_1)); + + Map<Integer, PersistableBundleWrapper> subIdToCarrierConfigMap = new HashMap<>(); + subIdToCarrierConfigMap.put( + TEST_SUBSCRIPTION_ID_1, new PersistableBundleWrapper(updatedConfig)); + mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true)); + mTestLooper.dispatchAll(); + + verify(mCallback) + .onNewSnapshot( + eq( + buildExpectedSnapshot( + 0, + TEST_SUBID_TO_INFO_MAP, + subIdToCarrierConfigMap, + TEST_PRIVILEGED_PACKAGES))); + } + + @Test public void testSlotClearedAfterValidTriggersCallbacks() throws Exception { mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true)); mTestLooper.dispatchAll(); |