summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp22
-rw-r--r--java/src-debug/com/android/intentresolver/flags/DebugFeatureFlagRepository.kt81
-rw-r--r--java/src-debug/com/android/intentresolver/flags/FeatureFlagRepositoryFactory.kt30
-rw-r--r--java/src-release/com/android/intentresolver/flags/FeatureFlagRepositoryFactory.kt24
-rw-r--r--java/src-release/com/android/intentresolver/flags/ReleaseFeatureFlagRepository.kt31
-rw-r--r--java/src/com/android/intentresolver/ChooserActivity.java28
-rw-r--r--java/src/com/android/intentresolver/ChooserRequestParameters.java4
-rw-r--r--java/src/com/android/intentresolver/flags/DeviceConfigProxy.kt33
-rw-r--r--java/src/com/android/intentresolver/flags/FeatureFlagRepository.kt25
-rw-r--r--java/src/com/android/intentresolver/flags/Flags.kt30
-rw-r--r--java/src/com/android/intentresolver/inject/FeatureFlagsModule.kt15
-rw-r--r--java/src/com/android/intentresolver/inject/Qualifiers.kt5
-rw-r--r--java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java3
-rw-r--r--java/tests/src/com/android/intentresolver/ChooserRequestParametersTest.kt7
-rw-r--r--java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java9
-rw-r--r--java/tests/src/com/android/intentresolver/FeatureFlagRule.kt56
-rw-r--r--java/tests/src/com/android/intentresolver/RequireFeatureFlags.kt23
-rw-r--r--java/tests/src/com/android/intentresolver/TestFeatureFlagRepository.kt31
-rw-r--r--java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java150
19 files changed, 48 insertions, 559 deletions
diff --git a/Android.bp b/Android.bp
index 93f19179..674aae1f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -19,33 +19,12 @@ package {
default_visibility: [":__subpackages__"],
}
-filegroup {
- name: "ReleaseSources",
- srcs: [
- "java/src-release/**/*.kt",
- ],
-}
-
-filegroup {
- name: "DebugSources",
- srcs: [
- "java/src-debug/**/*.kt",
- ],
-}
-
java_defaults {
name: "Java_Defaults",
srcs: [
"java/src/**/*.java",
"java/src/**/*.kt",
- ":ReleaseSources",
],
- product_variables: {
- debuggable: {
- srcs: [":DebugSources"],
- exclude_srcs: [":ReleaseSources"],
- }
- },
resource_dirs: [
"java/res",
],
@@ -78,7 +57,6 @@ android_library {
"kotlinx-coroutines-android",
"//external/kotlinc:kotlin-annotations",
"guava",
- "SystemUIFlagsLib",
],
}
diff --git a/java/src-debug/com/android/intentresolver/flags/DebugFeatureFlagRepository.kt b/java/src-debug/com/android/intentresolver/flags/DebugFeatureFlagRepository.kt
deleted file mode 100644
index 5067c0ee..00000000
--- a/java/src-debug/com/android/intentresolver/flags/DebugFeatureFlagRepository.kt
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.intentresolver.flags
-
-import android.util.SparseBooleanArray
-import androidx.annotation.GuardedBy
-import com.android.systemui.flags.BooleanFlag
-import com.android.systemui.flags.FlagManager
-import com.android.systemui.flags.ReleasedFlag
-import com.android.systemui.flags.UnreleasedFlag
-import javax.annotation.concurrent.ThreadSafe
-
-@ThreadSafe
-internal class DebugFeatureFlagRepository(
- private val flagManager: FlagManager,
- private val deviceConfig: DeviceConfigProxy,
-) : FeatureFlagRepository {
- @GuardedBy("self")
- private val cache = hashMapOf<String, Boolean>()
-
- override fun isEnabled(flag: UnreleasedFlag): Boolean = isFlagEnabled(flag)
-
- override fun isEnabled(flag: ReleasedFlag): Boolean = isFlagEnabled(flag)
-
- private fun isFlagEnabled(flag: BooleanFlag): Boolean {
- synchronized(cache) {
- cache[flag.name]?.let { return it }
- }
- val flagValue = readFlagValue(flag)
- return synchronized(cache) {
- // the first read saved in the cache wins
- cache.getOrPut(flag.name) { flagValue }
- }
- }
-
- private fun readFlagValue(flag: BooleanFlag): Boolean {
- val localOverride = runCatching {
- flagManager.isEnabled(flag.name)
- }.getOrDefault(null)
- val remoteOverride = deviceConfig.isEnabled(flag)
-
- // Only check for teamfood if the default is false
- // and there is no server override.
- if (remoteOverride == null
- && !flag.default
- && localOverride == null
- && !flag.isTeamfoodFlag
- && flag.teamfood
- ) {
- return flagManager.isTeamfoodEnabled
- }
- return localOverride ?: remoteOverride ?: flag.default
- }
-
- companion object {
- /** keep in sync with [com.android.systemui.flags.Flags] */
- private const val TEAMFOOD_FLAG_NAME = "teamfood"
-
- private val BooleanFlag.isTeamfoodFlag: Boolean
- get() = name == TEAMFOOD_FLAG_NAME
-
- private val FlagManager.isTeamfoodEnabled: Boolean
- get() = runCatching {
- isEnabled(TEAMFOOD_FLAG_NAME) ?: false
- }.getOrDefault(false)
- }
-}
diff --git a/java/src-debug/com/android/intentresolver/flags/FeatureFlagRepositoryFactory.kt b/java/src-debug/com/android/intentresolver/flags/FeatureFlagRepositoryFactory.kt
deleted file mode 100644
index 4ddb0447..00000000
--- a/java/src-debug/com/android/intentresolver/flags/FeatureFlagRepositoryFactory.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.intentresolver.flags
-
-import android.content.Context
-import android.os.Handler
-import android.os.Looper
-import com.android.systemui.flags.FlagManager
-
-class FeatureFlagRepositoryFactory {
- fun create(context: Context): FeatureFlagRepository =
- DebugFeatureFlagRepository(
- FlagManager(context, Handler(Looper.getMainLooper())),
- DeviceConfigProxy(),
- )
-}
diff --git a/java/src-release/com/android/intentresolver/flags/FeatureFlagRepositoryFactory.kt b/java/src-release/com/android/intentresolver/flags/FeatureFlagRepositoryFactory.kt
deleted file mode 100644
index 6bf7579e..00000000
--- a/java/src-release/com/android/intentresolver/flags/FeatureFlagRepositoryFactory.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.intentresolver.flags
-
-import android.content.Context
-
-class FeatureFlagRepositoryFactory {
- fun create(context: Context): FeatureFlagRepository =
- ReleaseFeatureFlagRepository(DeviceConfigProxy())
-}
diff --git a/java/src-release/com/android/intentresolver/flags/ReleaseFeatureFlagRepository.kt b/java/src-release/com/android/intentresolver/flags/ReleaseFeatureFlagRepository.kt
deleted file mode 100644
index f9fa2c6a..00000000
--- a/java/src-release/com/android/intentresolver/flags/ReleaseFeatureFlagRepository.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.intentresolver.flags
-
-import com.android.systemui.flags.ReleasedFlag
-import com.android.systemui.flags.UnreleasedFlag
-import javax.annotation.concurrent.ThreadSafe
-
-@ThreadSafe
-internal class ReleaseFeatureFlagRepository(
- private val deviceConfig: DeviceConfigProxy,
-) : FeatureFlagRepository {
- override fun isEnabled(flag: UnreleasedFlag): Boolean = flag.default
-
- override fun isEnabled(flag: ReleasedFlag): Boolean =
- deviceConfig.isEnabled(flag) ?: flag.default
-}
diff --git a/java/src/com/android/intentresolver/ChooserActivity.java b/java/src/com/android/intentresolver/ChooserActivity.java
index 1e670a21..0101c046 100644
--- a/java/src/com/android/intentresolver/ChooserActivity.java
+++ b/java/src/com/android/intentresolver/ChooserActivity.java
@@ -23,9 +23,7 @@ import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT
import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CROSS_PROFILE_BLOCKED_TITLE;
import static android.stats.devicepolicy.nano.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL;
import static android.stats.devicepolicy.nano.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK;
-
import static androidx.lifecycle.LifecycleKt.getCoroutineScope;
-
import static com.android.internal.util.LatencyTracker.ACTION_LOAD_SHARE_SHEET;
import android.annotation.IntDef;
@@ -85,8 +83,6 @@ import com.android.intentresolver.contentpreview.BasePreviewViewModel;
import com.android.intentresolver.contentpreview.ChooserContentPreviewUi;
import com.android.intentresolver.contentpreview.HeadlineGeneratorImpl;
import com.android.intentresolver.contentpreview.PreviewViewModel;
-import com.android.intentresolver.flags.FeatureFlagRepository;
-import com.android.intentresolver.flags.FeatureFlagRepositoryFactory;
import com.android.intentresolver.grid.ChooserGridAdapter;
import com.android.intentresolver.icons.DefaultTargetDataLoader;
import com.android.intentresolver.icons.TargetDataLoader;
@@ -119,6 +115,8 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
+import javax.inject.Inject;
+
/**
* The Chooser Activity handles intent resolution specifically for sharing intents -
* for example, as generated by {@see android.content.Intent#createChooser(Intent, CharSequence)}.
@@ -175,6 +173,8 @@ public class ChooserActivity extends Hilt_ChooserActivity implements
@Retention(RetentionPolicy.SOURCE)
public @interface ShareTargetType {}
+ @Inject public FeatureFlags mFeatureFlags;
+
private ChooserIntegratedDeviceComponents mIntegratedDeviceComponents;
/* TODO: this is `nullable` because we have to defer the assignment til onCreate(). We make the
@@ -188,7 +188,6 @@ public class ChooserActivity extends Hilt_ChooserActivity implements
private ChooserRefinementManager mRefinementManager;
- private FeatureFlagRepository mFeatureFlagRepository;
private ChooserContentPreviewUi mChooserContentPreviewUi;
private boolean mShouldDisplayLandscape;
@@ -242,15 +241,11 @@ public class ChooserActivity extends Hilt_ChooserActivity implements
getEventLog().logSharesheetTriggered();
- mFeatureFlagRepository = createFeatureFlagRepository();
- mIntegratedDeviceComponents = getIntegratedDeviceComponents();
-
try {
mChooserRequest = new ChooserRequestParameters(
getIntent(),
getReferrerPackageName(),
- getReferrer(),
- mFeatureFlagRepository);
+ getReferrer());
} catch (IllegalArgumentException e) {
Log.e(TAG, "Caller provided invalid Chooser request parameters", e);
finish();
@@ -265,7 +260,7 @@ public class ChooserActivity extends Hilt_ChooserActivity implements
createProfileRecords(
new AppPredictorFactory(
- getApplicationContext(),
+ this, // TODO: Review w/team, possible side effects?
mChooserRequest.getSharedText(),
mChooserRequest.getTargetIntentFilter()),
mChooserRequest.getTargetIntentFilter());
@@ -283,7 +278,10 @@ public class ChooserActivity extends Hilt_ChooserActivity implements
new DefaultTargetDataLoader(this, getLifecycle(), false),
/* safeForwardingMode= */ true);
- mFeatureFlagRepository = createFeatureFlagRepository();
+ if (mFeatureFlags.exampleNewSharingMethod()) {
+ // Sample flag usage
+ }
+
mIntegratedDeviceComponents = getIntegratedDeviceComponents();
mRefinementManager = new ViewModelProvider(this).get(ChooserRefinementManager.class);
@@ -371,10 +369,6 @@ public class ChooserActivity extends Hilt_ChooserActivity implements
return R.style.Theme_DeviceDefault_Chooser;
}
- protected FeatureFlagRepository createFeatureFlagRepository() {
- return new FeatureFlagRepositoryFactory().create(getApplicationContext());
- }
-
private void createProfileRecords(
AppPredictorFactory factory, IntentFilter targetIntentFilter) {
UserHandle mainUserHandle = getPersonalProfileUserHandle();
@@ -395,7 +389,7 @@ public class ChooserActivity extends Hilt_ChooserActivity implements
ShortcutLoader shortcutLoader = ActivityManager.isLowRamDeviceStatic()
? null
: createShortcutLoader(
- getApplicationContext(),
+ this, // TODO: Review w/team, possible side effects?
appPredictor,
userHandle,
targetIntentFilter,
diff --git a/java/src/com/android/intentresolver/ChooserRequestParameters.java b/java/src/com/android/intentresolver/ChooserRequestParameters.java
index 5157986b..b05d51b2 100644
--- a/java/src/com/android/intentresolver/ChooserRequestParameters.java
+++ b/java/src/com/android/intentresolver/ChooserRequestParameters.java
@@ -32,7 +32,6 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
-import com.android.intentresolver.flags.FeatureFlagRepository;
import com.android.intentresolver.util.UriFilters;
import com.google.common.collect.ImmutableList;
@@ -104,8 +103,7 @@ public class ChooserRequestParameters {
public ChooserRequestParameters(
final Intent clientIntent,
String referrerPackageName,
- final Uri referrer,
- FeatureFlagRepository featureFlags) {
+ final Uri referrer) {
final Intent requestedTarget = parseTargetIntentExtra(
clientIntent.getParcelableExtra(Intent.EXTRA_INTENT));
mTarget = intentWithModifiedLaunchFlags(requestedTarget);
diff --git a/java/src/com/android/intentresolver/flags/DeviceConfigProxy.kt b/java/src/com/android/intentresolver/flags/DeviceConfigProxy.kt
deleted file mode 100644
index d1494fe7..00000000
--- a/java/src/com/android/intentresolver/flags/DeviceConfigProxy.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.intentresolver.flags
-
-import android.provider.DeviceConfig
-import com.android.systemui.flags.ParcelableFlag
-
-internal class DeviceConfigProxy {
- fun isEnabled(flag: ParcelableFlag<Boolean>): Boolean? {
- return runCatching {
- val hasProperty = DeviceConfig.getProperty(flag.namespace, flag.name) != null
- if (hasProperty) {
- DeviceConfig.getBoolean(flag.namespace, flag.name, flag.default)
- } else {
- null
- }
- }.getOrDefault(null)
- }
-}
diff --git a/java/src/com/android/intentresolver/flags/FeatureFlagRepository.kt b/java/src/com/android/intentresolver/flags/FeatureFlagRepository.kt
deleted file mode 100644
index 5b5d769c..00000000
--- a/java/src/com/android/intentresolver/flags/FeatureFlagRepository.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.intentresolver.flags
-
-import com.android.systemui.flags.ReleasedFlag
-import com.android.systemui.flags.UnreleasedFlag
-
-interface FeatureFlagRepository {
- fun isEnabled(flag: UnreleasedFlag): Boolean
- fun isEnabled(flag: ReleasedFlag): Boolean
-}
diff --git a/java/src/com/android/intentresolver/flags/Flags.kt b/java/src/com/android/intentresolver/flags/Flags.kt
deleted file mode 100644
index 2c20d341..00000000
--- a/java/src/com/android/intentresolver/flags/Flags.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.intentresolver.flags
-
-import com.android.systemui.flags.ReleasedFlag
-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).
-// All flags added should be included in UnbundledChooserActivityTest.ALL_FLAGS.
-object Flags {
- private fun releasedFlag(name: String) = ReleasedFlag(name, "systemui")
-
- private fun unreleasedFlag(name: String, teamfood: Boolean = false) =
- UnreleasedFlag(name, "systemui", teamfood)
-}
diff --git a/java/src/com/android/intentresolver/inject/FeatureFlagsModule.kt b/java/src/com/android/intentresolver/inject/FeatureFlagsModule.kt
new file mode 100644
index 00000000..05cf2104
--- /dev/null
+++ b/java/src/com/android/intentresolver/inject/FeatureFlagsModule.kt
@@ -0,0 +1,15 @@
+package com.android.intentresolver.inject
+
+import com.android.intentresolver.FeatureFlags
+import com.android.intentresolver.FeatureFlagsImpl
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+
+@Module
+@InstallIn(SingletonComponent::class)
+object FeatureFlagsModule {
+
+ @Provides fun featureFlags(): FeatureFlags = FeatureFlagsImpl()
+}
diff --git a/java/src/com/android/intentresolver/inject/Qualifiers.kt b/java/src/com/android/intentresolver/inject/Qualifiers.kt
index 2bfb1ff9..fca1e896 100644
--- a/java/src/com/android/intentresolver/inject/Qualifiers.kt
+++ b/java/src/com/android/intentresolver/inject/Qualifiers.kt
@@ -20,6 +20,11 @@ import javax.inject.Qualifier
@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class ActivityOwned
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class ApplicationOwned
+
@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class Background
@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class Default
diff --git a/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java b/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java
index 84f5124c..5b938aa1 100644
--- a/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java
+++ b/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java
@@ -29,7 +29,6 @@ import android.os.UserHandle;
import com.android.intentresolver.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker;
import com.android.intentresolver.chooser.TargetInfo;
import com.android.intentresolver.contentpreview.ImageLoader;
-import com.android.intentresolver.flags.FeatureFlagRepository;
import com.android.intentresolver.logging.EventLog;
import com.android.intentresolver.shortcuts.ShortcutLoader;
@@ -77,7 +76,6 @@ public class ChooserActivityOverrideData {
public WorkProfileAvailabilityManager mWorkProfileAvailability;
public CrossProfileIntentsChecker mCrossProfileIntentsChecker;
public PackageManager packageManager;
- public FeatureFlagRepository featureFlagRepository;
public void reset() {
onSafelyStartInternalCallback = null;
@@ -127,7 +125,6 @@ public class ChooserActivityOverrideData {
mCrossProfileIntentsChecker = mock(CrossProfileIntentsChecker.class);
when(mCrossProfileIntentsChecker.hasCrossProfileIntents(any(), anyInt(), anyInt()))
.thenAnswer(invocation -> hasCrossProfileIntents);
- featureFlagRepository = null;
}
private ChooserActivityOverrideData() {}
diff --git a/java/tests/src/com/android/intentresolver/ChooserRequestParametersTest.kt b/java/tests/src/com/android/intentresolver/ChooserRequestParametersTest.kt
index 331d1c21..90f6cf93 100644
--- a/java/tests/src/com/android/intentresolver/ChooserRequestParametersTest.kt
+++ b/java/tests/src/com/android/intentresolver/ChooserRequestParametersTest.kt
@@ -29,7 +29,6 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class ChooserRequestParametersTest {
- val flags = TestFeatureFlagRepository(mapOf())
@Test
fun testChooserActions() {
@@ -41,7 +40,7 @@ class ChooserRequestParametersTest {
putExtra(Intent.EXTRA_INTENT, intent)
putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, actions)
}
- val request = ChooserRequestParameters(chooserIntent, "", Uri.EMPTY, flags)
+ val request = ChooserRequestParameters(chooserIntent, "", Uri.EMPTY)
assertThat(request.chooserActions).containsExactlyElementsIn(actions).inOrder()
}
@@ -50,7 +49,7 @@ class ChooserRequestParametersTest {
val intent = Intent(Intent.ACTION_SEND)
val chooserIntent =
Intent(Intent.ACTION_CHOOSER).apply { putExtra(Intent.EXTRA_INTENT, intent) }
- val request = ChooserRequestParameters(chooserIntent, "", Uri.EMPTY, flags)
+ val request = ChooserRequestParameters(chooserIntent, "", Uri.EMPTY)
assertThat(request.chooserActions).isEmpty()
}
@@ -64,7 +63,7 @@ class ChooserRequestParametersTest {
putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, chooserActions)
}
- val request = ChooserRequestParameters(chooserIntent, "", Uri.EMPTY, flags)
+ val request = ChooserRequestParameters(chooserIntent, "", Uri.EMPTY)
val expectedActions = chooserActions.sliceArray(0 until 5)
assertThat(request.chooserActions).containsExactlyElementsIn(expectedActions).inOrder()
diff --git a/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java b/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java
index 8c2a15f1..578b9557 100644
--- a/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java
+++ b/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java
@@ -37,7 +37,6 @@ import androidx.lifecycle.ViewModelProvider;
import com.android.intentresolver.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker;
import com.android.intentresolver.chooser.DisplayResolveInfo;
import com.android.intentresolver.chooser.TargetInfo;
-import com.android.intentresolver.flags.FeatureFlagRepository;
import com.android.intentresolver.grid.ChooserGridAdapter;
import com.android.intentresolver.icons.TargetDataLoader;
import com.android.intentresolver.logging.EventLog;
@@ -282,12 +281,4 @@ public class ChooserWrapperActivity extends ChooserActivity implements IChooserW
return super.createShortcutLoader(
context, appPredictor, userHandle, targetIntentFilter, callback);
}
-
- @Override
- protected FeatureFlagRepository createFeatureFlagRepository() {
- if (sOverrides.featureFlagRepository != null) {
- return sOverrides.featureFlagRepository;
- }
- return super.createFeatureFlagRepository();
- }
}
diff --git a/java/tests/src/com/android/intentresolver/FeatureFlagRule.kt b/java/tests/src/com/android/intentresolver/FeatureFlagRule.kt
deleted file mode 100644
index 3fa01bcc..00000000
--- a/java/tests/src/com/android/intentresolver/FeatureFlagRule.kt
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 1ddf7462..00000000
--- a/java/tests/src/com/android/intentresolver/RequireFeatureFlags.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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
deleted file mode 100644
index b9047712..00000000
--- a/java/tests/src/com/android/intentresolver/TestFeatureFlagRepository.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.intentresolver.flags.FeatureFlagRepository
-import com.android.systemui.flags.BooleanFlag
-import com.android.systemui.flags.ReleasedFlag
-import com.android.systemui.flags.UnreleasedFlag
-
-class TestFeatureFlagRepository(
- private val overrides: Map<BooleanFlag, Boolean>
-) : FeatureFlagRepository {
- override fun isEnabled(flag: UnreleasedFlag): Boolean = getValue(flag)
- override fun isEnabled(flag: ReleasedFlag): Boolean = getValue(flag)
-
- 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 aca78604..59357843 100644
--- a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java
+++ b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java
@@ -17,7 +17,6 @@
package com.android.intentresolver;
import static android.app.Activity.RESULT_OK;
-
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.longClick;
@@ -29,7 +28,6 @@ import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
import static com.android.intentresolver.ChooserActivity.TARGET_TYPE_CHOOSER_TARGET;
import static com.android.intentresolver.ChooserActivity.TARGET_TYPE_DEFAULT;
import static com.android.intentresolver.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE;
@@ -37,11 +35,8 @@ import static com.android.intentresolver.ChooserActivity.TARGET_TYPE_SHORTCUTS_F
import static com.android.intentresolver.ChooserListAdapter.CALLER_TARGET_SCORE_BOOST;
import static com.android.intentresolver.ChooserListAdapter.SHORTCUT_TARGET_SCORE_BOOST;
import static com.android.intentresolver.MatcherUtils.first;
-
import static com.google.common.truth.Truth.assertThat;
-
import static junit.framework.Assert.assertNull;
-
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
@@ -105,7 +100,6 @@ import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
-import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.GridLayoutManager;
@@ -122,7 +116,6 @@ import com.android.intentresolver.logging.EventLog;
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;
@@ -131,8 +124,6 @@ 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;
@@ -155,27 +146,14 @@ import java.util.function.Consumer;
import java.util.function.Function;
/**
- * Instrumentation tests for the IntentResolver module's Sharesheet (ChooserActivity).
- * TODO: remove methods that supported running these tests against arbitrary ChooserActivity
- * subclasses. Those were left over from an earlier version where IntentResolver's ChooserActivity
- * inherited from the framework version at com.android.internal.app.ChooserActivity, and this test
- * file inherited from the framework's version as well. Once the migration to the IntentResolver
- * package is complete, that aspect of the test design can revert to match the style of the
- * framework tests prior to ag/16482932.
- * TODO: this can simply be renamed to "ChooserActivityTest" if that's ever unambiguous (i.e., if
- * there's no risk of confusion with the framework tests that currently share the same name).
+ * Instrumentation tests for ChooserActivity.
+ * <p>
+ * Legacy test suite migrated from framework CoreTests.
+ * <p>
*/
@RunWith(Parameterized.class)
public class UnbundledChooserActivityTest {
- /* --------
- * Subclasses should copy the following section verbatim (or alternatively could specify some
- * additional @Parameterized.Parameters, as long as the correct parameters are used to
- * initialize the ChooserActivityTest). The subclasses should also be @RunWith the
- * `Parameterized` runner.
- * --------
- */
-
private static final UserHandle PERSONAL_USER_HANDLE = InstrumentationRegistry
.getInstrumentation().getTargetContext().getUser();
private static final Function<PackageManager, PackageManager> DEFAULT_PM = pm -> pm;
@@ -186,56 +164,18 @@ public class UnbundledChooserActivityTest {
return mock;
};
- private static final List<BooleanFlag> ALL_FLAGS =
- Arrays.asList();
-
- 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() {
- if (ALL_FLAGS.isEmpty()) {
- // No flags to toggle between, so just two configurations.
- return Arrays.asList(new Object[][] {
- // Default PackageManager and all flags off
- { DEFAULT_PM, ALL_FLAGS_OFF},
- // No App Prediction Service and all flags off
- { NO_APP_PREDICTION_SERVICE_PM, ALL_FLAGS_OFF },
- });
- }
return Arrays.asList(new Object[][] {
- // 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 }
+ // Default PackageManager
+ { DEFAULT_PM },
+ // No App Prediction Service
+ { NO_APP_PREDICTION_SERVICE_PM}
});
}
- 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.
- * --------
- */
-
- /**
- * Perform any necessary per-test initialization steps (subclasses may add additional steps
- * before and/or after calling up to the superclass implementation).
- */
- @CallSuper
- protected void setup() {
+ @Before
+ public void setUp() {
// TODO: use the other form of `adoptShellPermissionIdentity()` where we explicitly list the
// permissions we require (which we'll read from the manifest at runtime).
InstrumentationRegistry
@@ -244,67 +184,11 @@ public class UnbundledChooserActivityTest {
.adoptShellPermissionIdentity();
cleanOverrideData();
- ChooserActivityOverrideData.getInstance().featureFlagRepository =
- new TestFeatureFlagRepository(mFlags);
- }
-
- /**
- * Given an intent that was constructed in a test, perform any additional configuration to
- * specify the appropriate concrete ChooserActivity subclass. The activity launched by this
- * intent must descend from android.intentresolver.ChooserActivity (for our ActivityTestRule), and
- * must also implement the android.intentresolver.IChooserWrapper interface (since test code will
- * assume the ability to make unsafe downcasts).
- */
- protected Intent getConcreteIntentForLaunch(Intent clientIntent) {
- clientIntent.setClass(
- InstrumentationRegistry.getInstrumentation().getTargetContext(),
- com.android.intentresolver.ChooserWrapperActivity.class);
- return clientIntent;
- }
-
- /**
- * Whether {@code #testIsAppPredictionServiceAvailable} should verify the behavior after
- * changing the availability conditions at runtime. In the unbundled chooser, the availability
- * is cached at start and will never be re-evaluated.
- * TODO: remove when we no longer want to test the system's on-the-fly evaluation.
- */
- protected boolean shouldTestTogglingAppPredictionServiceAvailabilityAtRuntime() {
- return false;
}
- /* --------
- * The code in this section is unorthodox and can be simplified/reverted when we no longer need
- * to support the parallel chooser implementations.
- * --------
- */
-
@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.
- private ActivityTestRule<ChooserActivity> mActivityRule =
- new ActivityTestRule<>(ChooserActivity.class, false, false) {
- @Override
- public ChooserActivity launchActivity(Intent clientIntent) {
- return super.launchActivity(getConcreteIntentForLaunch(clientIntent));
- }
- };
-
- @Before
- public final void doPolymorphicSetup() {
- // The base class needs a @Before-annotated setup for when it runs against the system
- // chooser, while subclasses need to be able to specify their own setup behavior. Notably
- // the unbundled chooser, running in user-space, needs to take additional steps before it
- // can run #cleanOverrideData() (which writes to DeviceConfig).
- setup();
- }
-
- /* --------
- * Subclasses can ignore the remaining code and inherit the full suite of tests.
- * --------
- */
+ public ActivityTestRule<ChooserWrapperActivity> mActivityRule =
+ new ActivityTestRule<>(ChooserWrapperActivity.class, false, false);
private static final String TEST_MIME_TYPE = "application/TestType";
@@ -313,18 +197,10 @@ public class UnbundledChooserActivityTest {
private static final int CONTENT_PREVIEW_TEXT = 3;
private final Function<PackageManager, PackageManager> mPackageManagerOverride;
- private final Map<BooleanFlag, Boolean> mFlags;
-
public UnbundledChooserActivityTest(
- Function<PackageManager, PackageManager> packageManagerOverride,
- Map<BooleanFlag, Boolean> flags) {
+ Function<PackageManager, PackageManager> packageManagerOverride) {
mPackageManagerOverride = packageManagerOverride;
- mFlags = flags;
-
- mRule = RuleChain
- .outerRule(new FeatureFlagRule(flags))
- .around(mActivityRule);
}
private void setDeviceConfigProperty(