diff options
| author | 2023-02-22 00:16:49 +0000 | |
|---|---|---|
| committer | 2023-02-22 00:16:49 +0000 | |
| commit | 5ab7fc28ed19fa87f4efbc30108a0ad654c7fe99 (patch) | |
| tree | 9d3c398ded81e2057d2e860865ab19c9041d9fc9 /java | |
| parent | 915fc26805d3a3408c4d31792a0c24a90612ca42 (diff) | |
| parent | 62bc595d899bfe849d039ab546f590469163bc4d (diff) | |
Merge "Run Chooser integration tests for the new features" into tm-qpr-dev am: 62bc595d89
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/modules/IntentResolver/+/21319931
Change-Id: I5b21c5006ba91a08977a0a9a31ad42235a4a1c5e
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'java')
5 files changed, 171 insertions, 48 deletions
diff --git a/java/src/com/android/intentresolver/flags/Flags.kt b/java/src/com/android/intentresolver/flags/Flags.kt index 59b5ea74..f4dbeddb 100644 --- a/java/src/com/android/intentresolver/flags/Flags.kt +++ b/java/src/com/android/intentresolver/flags/Flags.kt @@ -21,24 +21,33 @@ import com.android.systemui.flags.UnreleasedFlag // Flag id, name and namespace should be kept in sync with [com.android.systemui.flags.Flags] to // make the flags available in the flag flipper app (see go/sysui-flags). object Flags { + const val SHARESHEET_CUSTOM_ACTIONS_NAME = "sharesheet_custom_actions" + const val SHARESHEET_RESELECTION_ACTION_NAME = "sharesheet_reselection_action" + const val SHARESHEET_IMAGE_AND_TEXT_PREVIEW_NAME = "sharesheet_image_text_preview" + const val SHARESHEET_SCROLLABLE_IMAGE_PREVIEW_NAME = "sharesheet_scrollable_image_preview" + // TODO(b/266983432) Tracking Bug @JvmField - val SHARESHEET_CUSTOM_ACTIONS = unreleasedFlag(1501, "sharesheet_custom_actions", teamfood = true) + val SHARESHEET_CUSTOM_ACTIONS = unreleasedFlag( + 1501, SHARESHEET_CUSTOM_ACTIONS_NAME, teamfood = true + ) // TODO(b/266982749) Tracking Bug @JvmField - val SHARESHEET_RESELECTION_ACTION = unreleasedFlag(1502, "sharesheet_reselection_action", teamfood = true) + val SHARESHEET_RESELECTION_ACTION = unreleasedFlag( + 1502, SHARESHEET_RESELECTION_ACTION_NAME, teamfood = true + ) // TODO(b/266983474) Tracking Bug @JvmField val SHARESHEET_IMAGE_AND_TEXT_PREVIEW = unreleasedFlag( - id = 1503, name = "sharesheet_image_text_preview", teamfood = true + id = 1503, name = SHARESHEET_IMAGE_AND_TEXT_PREVIEW_NAME, teamfood = true ) // TODO(b/267355521) Tracking Bug @JvmField val SHARESHEET_SCROLLABLE_IMAGE_PREVIEW = unreleasedFlag( - 1504, "sharesheet_scrollable_image_preview", teamfood = true + 1504, SHARESHEET_SCROLLABLE_IMAGE_PREVIEW_NAME, teamfood = true ) private fun unreleasedFlag(id: Int, name: String, teamfood: Boolean = false) = diff --git a/java/tests/src/com/android/intentresolver/FeatureFlagRule.kt b/java/tests/src/com/android/intentresolver/FeatureFlagRule.kt new file mode 100644 index 00000000..3fa01bcc --- /dev/null +++ b/java/tests/src/com/android/intentresolver/FeatureFlagRule.kt @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2023 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.intentresolver + +import com.android.systemui.flags.BooleanFlag +import org.junit.rules.TestRule +import org.junit.runner.Description +import org.junit.runners.model.Statement + +/** + * Ignores tests annotated with [RequireFeatureFlags] which flag requirements does not + * meet in the active flag set. + * @param flags active flag set + */ +internal class FeatureFlagRule(flags: Map<BooleanFlag, Boolean>) : TestRule { + private val flags = flags.entries.fold(HashMap<String, Boolean>()) { map, (key, value) -> + map.apply { + put(key.name, value) + } + } + private val skippingStatement = object : Statement() { + override fun evaluate() = Unit + } + + override fun apply(base: Statement, description: Description): Statement { + val annotation = description.annotations.firstOrNull { + it is RequireFeatureFlags + } as? RequireFeatureFlags + ?: return base + + if (annotation.flags.size != annotation.values.size) { + error("${description.className}#${description.methodName}: inconsistent number of" + + " flags and values in $annotation") + } + for (i in annotation.flags.indices) { + val flag = annotation.flags[i] + val value = annotation.values[i] + if (flags.getOrDefault(flag, !value) != value) return skippingStatement + } + return base + } +} diff --git a/java/tests/src/com/android/intentresolver/RequireFeatureFlags.kt b/java/tests/src/com/android/intentresolver/RequireFeatureFlags.kt new file mode 100644 index 00000000..1ddf7462 --- /dev/null +++ b/java/tests/src/com/android/intentresolver/RequireFeatureFlags.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2023 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.intentresolver + +/** + * Specifies expected feature flag values for a test. + */ +@Target(AnnotationTarget.FUNCTION) +annotation class RequireFeatureFlags(val flags: Array<String>, val values: BooleanArray) diff --git a/java/tests/src/com/android/intentresolver/TestFeatureFlagRepository.kt b/java/tests/src/com/android/intentresolver/TestFeatureFlagRepository.kt index abc24efb..5a159d24 100644 --- a/java/tests/src/com/android/intentresolver/TestFeatureFlagRepository.kt +++ b/java/tests/src/com/android/intentresolver/TestFeatureFlagRepository.kt @@ -17,14 +17,15 @@ package com.android.intentresolver import com.android.intentresolver.flags.FeatureFlagRepository +import com.android.systemui.flags.BooleanFlag import com.android.systemui.flags.ReleasedFlag import com.android.systemui.flags.UnreleasedFlag internal class TestFeatureFlagRepository( - private val overrides: Map<UnreleasedFlag, Boolean> + private val overrides: Map<BooleanFlag, Boolean> ) : FeatureFlagRepository { - override fun isEnabled(flag: UnreleasedFlag): Boolean = - overrides.getOrDefault(flag, flag.default) + override fun isEnabled(flag: UnreleasedFlag): Boolean = getValue(flag) + override fun isEnabled(flag: ReleasedFlag): Boolean = getValue(flag) - override fun isEnabled(flag: ReleasedFlag): Boolean = flag.default + private fun getValue(flag: BooleanFlag) = overrides.getOrDefault(flag, flag.default) } diff --git a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java index 17fd5bd9..82a635dd 100644 --- a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java +++ b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java @@ -107,6 +107,7 @@ import com.android.intentresolver.flags.Flags; import com.android.intentresolver.shortcuts.ShortcutLoader; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.systemui.flags.BooleanFlag; import org.hamcrest.Description; import org.hamcrest.Matcher; @@ -115,6 +116,8 @@ import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; +import org.junit.rules.RuleChain; +import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.mockito.ArgumentCaptor; @@ -123,7 +126,6 @@ import org.mockito.Mockito; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -162,14 +164,40 @@ public class UnbundledChooserActivityTest { return mock; }; + private static final List<BooleanFlag> ALL_FLAGS = + Arrays.asList( + Flags.SHARESHEET_CUSTOM_ACTIONS, + Flags.SHARESHEET_RESELECTION_ACTION, + Flags.SHARESHEET_IMAGE_AND_TEXT_PREVIEW, + Flags.SHARESHEET_SCROLLABLE_IMAGE_PREVIEW); + + private static final Map<BooleanFlag, Boolean> ALL_FLAGS_OFF = + createAllFlagsOverride(false); + private static final Map<BooleanFlag, Boolean> ALL_FLAGS_ON = + createAllFlagsOverride(true); + @Parameterized.Parameters public static Collection packageManagers() { return Arrays.asList(new Object[][] { - {0, "Default PackageManager", DEFAULT_PM}, - {1, "No App Prediction Service", NO_APP_PREDICTION_SERVICE_PM} + // Default PackageManager and all flags off + { DEFAULT_PM, ALL_FLAGS_OFF }, + // Default PackageManager and all flags on + { DEFAULT_PM, ALL_FLAGS_ON }, + // No App Prediction Service and all flags off + { NO_APP_PREDICTION_SERVICE_PM, ALL_FLAGS_OFF }, + // No App Prediction Service and all flags on + { NO_APP_PREDICTION_SERVICE_PM, ALL_FLAGS_ON } }); } + private static Map<BooleanFlag, Boolean> createAllFlagsOverride(boolean value) { + HashMap<BooleanFlag, Boolean> overrides = new HashMap<>(ALL_FLAGS.size()); + for (BooleanFlag flag : ALL_FLAGS) { + overrides.put(flag, value); + } + return overrides; + } + /* -------- * Subclasses can override the following methods to customize test behavior. * -------- @@ -189,6 +217,8 @@ public class UnbundledChooserActivityTest { .adoptShellPermissionIdentity(); cleanOverrideData(); + ChooserActivityOverrideData.getInstance().featureFlagRepository = + new TestFeatureFlagRepository(mFlags); } /** @@ -221,11 +251,13 @@ public class UnbundledChooserActivityTest { * -------- */ + @Rule + public final TestRule mRule; + // Shared test code references the activity under test as ChooserActivity, the common ancestor // of any (inheritance-based) chooser implementation. For testing purposes, that activity will // usually be cast to IChooserWrapper to expose instrumentation. - @Rule - public ActivityTestRule<ChooserActivity> mActivityRule = + private ActivityTestRule<ChooserActivity> mActivityRule = new ActivityTestRule<>(ChooserActivity.class, false, false) { @Override public ChooserActivity launchActivity(Intent clientIntent) { @@ -252,16 +284,20 @@ public class UnbundledChooserActivityTest { private static final int CONTENT_PREVIEW_IMAGE = 1; private static final int CONTENT_PREVIEW_FILE = 2; private static final int CONTENT_PREVIEW_TEXT = 3; - private Function<PackageManager, PackageManager> mPackageManagerOverride; - private int mTestNum; + + private final Function<PackageManager, PackageManager> mPackageManagerOverride; + private final Map<BooleanFlag, Boolean> mFlags; public UnbundledChooserActivityTest( - int testNum, - String testName, - Function<PackageManager, PackageManager> packageManagerOverride) { + Function<PackageManager, PackageManager> packageManagerOverride, + Map<BooleanFlag, Boolean> flags) { mPackageManagerOverride = packageManagerOverride; - mTestNum = testNum; + mFlags = flags; + + mRule = RuleChain + .outerRule(new FeatureFlagRule(flags)) + .around(mActivityRule); } private void setDeviceConfigProperty( @@ -757,10 +793,10 @@ public class UnbundledChooserActivityTest { } @Test + @RequireFeatureFlags( + flags = { Flags.SHARESHEET_IMAGE_AND_TEXT_PREVIEW_NAME }, + values = { true }) public void testImagePlusTextSharing_ExcludeText() { - ChooserActivityOverrideData.getInstance().featureFlagRepository = - new TestFeatureFlagRepository( - Collections.singletonMap(Flags.SHARESHEET_IMAGE_AND_TEXT_PREVIEW, true)); Intent sendIntent = createSendImageIntent( Uri.parse("android.resource://com.android.frameworks.coretests/" + R.drawable.test320x240)); @@ -809,10 +845,10 @@ public class UnbundledChooserActivityTest { } @Test + @RequireFeatureFlags( + flags = { Flags.SHARESHEET_IMAGE_AND_TEXT_PREVIEW_NAME }, + values = { true }) public void testImagePlusTextSharing_RemoveAndAddBackText() { - ChooserActivityOverrideData.getInstance().featureFlagRepository = - new TestFeatureFlagRepository( - Collections.singletonMap(Flags.SHARESHEET_IMAGE_AND_TEXT_PREVIEW, true)); Intent sendIntent = createSendImageIntent( Uri.parse("android.resource://com.android.frameworks.coretests/" + R.drawable.test320x240)); @@ -865,10 +901,10 @@ public class UnbundledChooserActivityTest { } @Test + @RequireFeatureFlags( + flags = { Flags.SHARESHEET_IMAGE_AND_TEXT_PREVIEW_NAME }, + values = { true }) public void testImagePlusTextSharing_TextExclusionDoesNotAffectAlternativeIntent() { - ChooserActivityOverrideData.getInstance().featureFlagRepository = - new TestFeatureFlagRepository( - Collections.singletonMap(Flags.SHARESHEET_IMAGE_AND_TEXT_PREVIEW, true)); Intent sendIntent = createSendImageIntent( Uri.parse("android.resource://com.android.frameworks.coretests/" + R.drawable.test320x240)); @@ -1070,10 +1106,10 @@ public class UnbundledChooserActivityTest { } @Test + @RequireFeatureFlags( + flags = { Flags.SHARESHEET_SCROLLABLE_IMAGE_PREVIEW_NAME }, + values = { false }) public void twoVisibleImagePreview() { - ChooserActivityOverrideData.getInstance().featureFlagRepository = - new TestFeatureFlagRepository( - Collections.singletonMap(Flags.SHARESHEET_SCROLLABLE_IMAGE_PREVIEW, false)); Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/" + R.drawable.test320x240); @@ -1110,11 +1146,10 @@ public class UnbundledChooserActivityTest { } @Test + @RequireFeatureFlags( + flags = { Flags.SHARESHEET_SCROLLABLE_IMAGE_PREVIEW_NAME }, + values = { false }) public void threeOrMoreVisibleImagePreview() { - ChooserActivityOverrideData.getInstance().featureFlagRepository = - new TestFeatureFlagRepository( - Collections.singletonMap( - Flags.SHARESHEET_SCROLLABLE_IMAGE_PREVIEW, false)); Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/" + R.drawable.test320x240); @@ -1154,11 +1189,10 @@ public class UnbundledChooserActivityTest { } @Test + @RequireFeatureFlags( + flags = { Flags.SHARESHEET_SCROLLABLE_IMAGE_PREVIEW_NAME }, + values = { true }) public void testManyVisibleImagePreview_ScrollableImagePreview() { - ChooserActivityOverrideData.getInstance().featureFlagRepository = - new TestFeatureFlagRepository( - Collections.singletonMap( - Flags.SHARESHEET_SCROLLABLE_IMAGE_PREVIEW, true)); Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/" + R.drawable.test320x240); @@ -1204,10 +1238,10 @@ public class UnbundledChooserActivityTest { } @Test + @RequireFeatureFlags( + flags = { Flags.SHARESHEET_IMAGE_AND_TEXT_PREVIEW_NAME }, + values = { true }) public void testImageAndTextPreview() { - ChooserActivityOverrideData.getInstance().featureFlagRepository = - new TestFeatureFlagRepository( - Collections.singletonMap(Flags.SHARESHEET_IMAGE_AND_TEXT_PREVIEW, true)); final Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/" + R.drawable.test320x240); final String sharedText = "text-" + System.currentTimeMillis(); @@ -1943,10 +1977,10 @@ public class UnbundledChooserActivityTest { } @Test + @RequireFeatureFlags( + flags = { Flags.SHARESHEET_CUSTOM_ACTIONS_NAME }, + values = { true }) public void testLaunchWithCustomAction() throws InterruptedException { - ChooserActivityOverrideData.getInstance().featureFlagRepository = - new TestFeatureFlagRepository( - Collections.singletonMap(Flags.SHARESHEET_CUSTOM_ACTIONS, true)); List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2); when( ChooserActivityOverrideData @@ -1998,10 +2032,10 @@ public class UnbundledChooserActivityTest { } @Test + @RequireFeatureFlags( + flags = { Flags.SHARESHEET_RESELECTION_ACTION_NAME }, + values = { true }) public void testLaunchWithShareModification() throws InterruptedException { - ChooserActivityOverrideData.getInstance().featureFlagRepository = - new TestFeatureFlagRepository( - Collections.singletonMap(Flags.SHARESHEET_RESELECTION_ACTION, true)); List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2); when( ChooserActivityOverrideData |